• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.xts.apimapper.config
18 
19 import javax.xml.parsers.DocumentBuilderFactory
20 import org.w3c.dom.Document
21 import org.w3c.dom.Element
22 
23 /**
24  * Data class representing the configuration for a single injection rule.
25  *
26  * @property pattern The pattern to match the module name.
27  * @property apiPrefixes The list of API prefixes to be logged.
28  * @property callerPrefixes The list of caller class prefixes to be processed.
29  */
30 data class InjectRule(
31     val pattern: Regex,
32     val apiPrefixes: List<String>,
33     val callerPrefixes: List<String>
34 )
35 
36 /**
37  * A class responsible for parsing the XML configuration file.
38  */
39 class Configuration(configFile: String) {
40 
41     private var doc: Document
42 
43     init {
44         val inputStream = this::class.java.classLoader.getResourceAsStream(configFile)
45         doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream)
46     }
47 
48     /**
49      * Parses the XML configuration file and returns a list of [InjectRule] objects.
50      *
51      * @param configFile The path to the XML configuration file.
52      * @return A list of [InjectRule] objects representing the parsed rules.
53      */
getInjectRulesnull54     fun getInjectRules(): List<InjectRule> {
55         val rules = mutableListOf<InjectRule>()
56         val ruleElements = doc.getElementsByTagName("inject-rules")
57 
58         for (i in 0 until ruleElements.length) {
59             val ruleElement = ruleElements.item(i) as Element
60             rules.add(parseRule(ruleElement))
61         }
62 
63         return rules
64     }
65 
66     /**
67      * Parses a single `<rule>` element and extracts its configuration.
68      *
69      * @param ruleElement The `<rule>` element to parse.
70      * @return A [InjectRule] object representing the parsed rule.
71      */
parseRulenull72     private fun parseRule(ruleElement: Element): InjectRule {
73         val pattern = ruleElement.getElementsByTagName("pattern").item(0).textContent
74         val apiPrefixes = parsePrefixes(ruleElement, "apiPrefixes")
75         val callerPrefixes = parsePrefixes(ruleElement, "callerPrefixes")
76         return InjectRule(Regex(pattern), apiPrefixes, callerPrefixes)
77     }
78 
79     /**
80      * Parses the `<apiPrefixes>` or `<callerPrefixes>` element and extracts the individual prefixes.
81      *
82      * @param ruleElement The `<rule>` element containing the prefixes.
83      * @param tagName The name of the tag to parse ("apiPrefixes" or "callerPrefixes").
84      * @return A list of prefixes.
85      */
parsePrefixesnull86     private fun parsePrefixes(ruleElement: Element, tagName: String): List<String> {
87         val prefixes = mutableListOf<String>()
88         val prefixesElement = ruleElement.getElementsByTagName(tagName).item(0) as Element
89         val prefixElements = prefixesElement.getElementsByTagName("prefix")
90         for (j in 0 until prefixElements.length) {
91             prefixes.add(prefixElements.item(j).textContent)
92         }
93         return prefixes
94     }
95 }
96