xref: /aosp_15_r20/cts/tools/utils/android_api_description_splitter.py (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1*b7c941bbSAndroid Build Coastguard Worker#! /usr/bin/python
2*b7c941bbSAndroid Build Coastguard Worker#
3*b7c941bbSAndroid Build Coastguard Worker# Copyright 2008, The Android Open Source Project
4*b7c941bbSAndroid Build Coastguard Worker#
5*b7c941bbSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*b7c941bbSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*b7c941bbSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*b7c941bbSAndroid Build Coastguard Worker#
9*b7c941bbSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*b7c941bbSAndroid Build Coastguard Worker#
11*b7c941bbSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*b7c941bbSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*b7c941bbSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*b7c941bbSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*b7c941bbSAndroid Build Coastguard Worker# limitations under the License.
16*b7c941bbSAndroid Build Coastguard Worker#
17*b7c941bbSAndroid Build Coastguard Worker# This script is used to split the jdiff xml into several smaller xml files
18*b7c941bbSAndroid Build Coastguard Worker# so that we could avoid the xml resource limit in Android platform.
19*b7c941bbSAndroid Build Coastguard Worker#
20*b7c941bbSAndroid Build Coastguard Worker# Usage:
21*b7c941bbSAndroid Build Coastguard Worker#    android_api_description.py xmlfile tagname
22*b7c941bbSAndroid Build Coastguard Worker#
23*b7c941bbSAndroid Build Coastguard Worker# The script will do the following:
24*b7c941bbSAndroid Build Coastguard Worker#    1. Read the xml file and generate DOM tree
25*b7c941bbSAndroid Build Coastguard Worker#    2. Generate xml file for each tagname.
26*b7c941bbSAndroid Build Coastguard Worker#
27*b7c941bbSAndroid Build Coastguard Worker# Example:
28*b7c941bbSAndroid Build Coastguard Worker# xml source:
29*b7c941bbSAndroid Build Coastguard Worker#    <Root>
30*b7c941bbSAndroid Build Coastguard Worker#        <A name="i">
31*b7c941bbSAndroid Build Coastguard Worker#            <B>1</B>
32*b7c941bbSAndroid Build Coastguard Worker#            <B>2</B>
33*b7c941bbSAndroid Build Coastguard Worker#        </A>
34*b7c941bbSAndroid Build Coastguard Worker#        <A name="ii">
35*b7c941bbSAndroid Build Coastguard Worker#            <B>3</B>
36*b7c941bbSAndroid Build Coastguard Worker#        </A>
37*b7c941bbSAndroid Build Coastguard Worker#    </Root>
38*b7c941bbSAndroid Build Coastguard Worker#
39*b7c941bbSAndroid Build Coastguard Worker# when the tagname is specified as A, it will generate two xml files:
40*b7c941bbSAndroid Build Coastguard Worker# first one's source:
41*b7c941bbSAndroid Build Coastguard Worker#    <Root>
42*b7c941bbSAndroid Build Coastguard Worker#        <A name="i">
43*b7c941bbSAndroid Build Coastguard Worker#            <B>1</B>
44*b7c941bbSAndroid Build Coastguard Worker#            <B>2</B>
45*b7c941bbSAndroid Build Coastguard Worker#        </A>
46*b7c941bbSAndroid Build Coastguard Worker#    </Root>
47*b7c941bbSAndroid Build Coastguard Worker# second one's source:
48*b7c941bbSAndroid Build Coastguard Worker#    <Root>
49*b7c941bbSAndroid Build Coastguard Worker#        <A name="ii">
50*b7c941bbSAndroid Build Coastguard Worker#            <B>3</B>
51*b7c941bbSAndroid Build Coastguard Worker#        </A>
52*b7c941bbSAndroid Build Coastguard Worker#    </Root>
53*b7c941bbSAndroid Build Coastguard Worker#
54*b7c941bbSAndroid Build Coastguard Worker# when the tagname is specified as B, it will generated three xml files:
55*b7c941bbSAndroid Build Coastguard Worker# first one's source:
56*b7c941bbSAndroid Build Coastguard Worker#    <Root>
57*b7c941bbSAndroid Build Coastguard Worker#        <A name="i">
58*b7c941bbSAndroid Build Coastguard Worker#            <B>1</B>
59*b7c941bbSAndroid Build Coastguard Worker#        </A>
60*b7c941bbSAndroid Build Coastguard Worker#    </Root>
61*b7c941bbSAndroid Build Coastguard Worker# second one's source:
62*b7c941bbSAndroid Build Coastguard Worker#    <Root>
63*b7c941bbSAndroid Build Coastguard Worker#        <A name="i">
64*b7c941bbSAndroid Build Coastguard Worker#            <B>2</B>
65*b7c941bbSAndroid Build Coastguard Worker#        </A>
66*b7c941bbSAndroid Build Coastguard Worker#    </Root>
67*b7c941bbSAndroid Build Coastguard Worker# third one's source:
68*b7c941bbSAndroid Build Coastguard Worker#    <Root>
69*b7c941bbSAndroid Build Coastguard Worker#        <A name="ii">
70*b7c941bbSAndroid Build Coastguard Worker#            <B>3</B>
71*b7c941bbSAndroid Build Coastguard Worker#        </A>
72*b7c941bbSAndroid Build Coastguard Worker#    </Root>
73*b7c941bbSAndroid Build Coastguard Worker#
74*b7c941bbSAndroid Build Coastguard Worker# NOTE:
75*b7c941bbSAndroid Build Coastguard Worker#    1. Currently just suppor the top level element
76*b7c941bbSAndroid Build Coastguard Worker#    2. Use the name attribute of the specified element as the file name
77*b7c941bbSAndroid Build Coastguard Worker#    3. Currently will remove all the doc element. - workaround for jdiff xml
78*b7c941bbSAndroid Build Coastguard Worker#
79*b7c941bbSAndroid Build Coastguard Workerimport os, sys;
80*b7c941bbSAndroid Build Coastguard Workerimport xml.dom.minidom;
81*b7c941bbSAndroid Build Coastguard Worker
82*b7c941bbSAndroid Build Coastguard Worker"""Split the jdiff xml into several smaller xml files by specified tag.
83*b7c941bbSAndroid Build Coastguard Worker"""
84*b7c941bbSAndroid Build Coastguard Workerclass XMLSplitter:
85*b7c941bbSAndroid Build Coastguard Worker    def __init__(self, xmlfile, outPath):
86*b7c941bbSAndroid Build Coastguard Worker        self.doc = xml.dom.minidom.parse(xmlfile)
87*b7c941bbSAndroid Build Coastguard Worker        self.root = self.doc.documentElement
88*b7c941bbSAndroid Build Coastguard Worker        self.out = os.path.join(outPath, "xml")
89*b7c941bbSAndroid Build Coastguard Worker        if not os.path.isdir(self.out):
90*b7c941bbSAndroid Build Coastguard Worker            os.makedirs(self.out)
91*b7c941bbSAndroid Build Coastguard Worker        return
92*b7c941bbSAndroid Build Coastguard Worker
93*b7c941bbSAndroid Build Coastguard Worker    def split(self, tag):
94*b7c941bbSAndroid Build Coastguard Worker
95*b7c941bbSAndroid Build Coastguard Worker        elemlist = self.doc.getElementsByTagName(tag)
96*b7c941bbSAndroid Build Coastguard Worker
97*b7c941bbSAndroid Build Coastguard Worker        for elem in elemlist:
98*b7c941bbSAndroid Build Coastguard Worker            elem = self.__trimElem(elem)
99*b7c941bbSAndroid Build Coastguard Worker            self.__generateFile(elem)
100*b7c941bbSAndroid Build Coastguard Worker
101*b7c941bbSAndroid Build Coastguard Worker        return
102*b7c941bbSAndroid Build Coastguard Worker
103*b7c941bbSAndroid Build Coastguard Worker    def __trimElem(self, elem):
104*b7c941bbSAndroid Build Coastguard Worker        children = []
105*b7c941bbSAndroid Build Coastguard Worker        for child in elem.childNodes:
106*b7c941bbSAndroid Build Coastguard Worker            if child.nodeType == xml.dom.minidom.Node.ELEMENT_NODE:
107*b7c941bbSAndroid Build Coastguard Worker                children.append(child)
108*b7c941bbSAndroid Build Coastguard Worker
109*b7c941bbSAndroid Build Coastguard Worker        for child in children:
110*b7c941bbSAndroid Build Coastguard Worker            if child.nodeName == "doc":
111*b7c941bbSAndroid Build Coastguard Worker                elem.removeChild(child)
112*b7c941bbSAndroid Build Coastguard Worker                children.remove(child)
113*b7c941bbSAndroid Build Coastguard Worker
114*b7c941bbSAndroid Build Coastguard Worker        for child in children:
115*b7c941bbSAndroid Build Coastguard Worker            child = self.__trimElem(child)
116*b7c941bbSAndroid Build Coastguard Worker
117*b7c941bbSAndroid Build Coastguard Worker        return elem
118*b7c941bbSAndroid Build Coastguard Worker
119*b7c941bbSAndroid Build Coastguard Worker
120*b7c941bbSAndroid Build Coastguard Worker    def __generateFile(self, elem):
121*b7c941bbSAndroid Build Coastguard Worker        self.__removeAllChild(self.root)
122*b7c941bbSAndroid Build Coastguard Worker
123*b7c941bbSAndroid Build Coastguard Worker        filename = os.path.join(self.out, elem.getAttribute("name").replace(".", "_").lower() + ".xml")
124*b7c941bbSAndroid Build Coastguard Worker
125*b7c941bbSAndroid Build Coastguard Worker        doc = xml.dom.minidom.Document()
126*b7c941bbSAndroid Build Coastguard Worker        doc.appendChild(self.root)
127*b7c941bbSAndroid Build Coastguard Worker
128*b7c941bbSAndroid Build Coastguard Worker        self.root.appendChild(elem)
129*b7c941bbSAndroid Build Coastguard Worker
130*b7c941bbSAndroid Build Coastguard Worker        fd = open(filename, "w")
131*b7c941bbSAndroid Build Coastguard Worker        fd.write(doc.toxml())
132*b7c941bbSAndroid Build Coastguard Worker        fd.close
133*b7c941bbSAndroid Build Coastguard Worker
134*b7c941bbSAndroid Build Coastguard Worker        return
135*b7c941bbSAndroid Build Coastguard Worker
136*b7c941bbSAndroid Build Coastguard Worker    def __removeAllChild(self, elem):
137*b7c941bbSAndroid Build Coastguard Worker        children = []
138*b7c941bbSAndroid Build Coastguard Worker        for child in elem.childNodes:
139*b7c941bbSAndroid Build Coastguard Worker            children.append(child)
140*b7c941bbSAndroid Build Coastguard Worker
141*b7c941bbSAndroid Build Coastguard Worker        for child in children:
142*b7c941bbSAndroid Build Coastguard Worker            elem.removeChild(child)
143*b7c941bbSAndroid Build Coastguard Worker
144*b7c941bbSAndroid Build Coastguard Worker        return
145*b7c941bbSAndroid Build Coastguard Worker
146*b7c941bbSAndroid Build Coastguard Workerif __name__ == "__main__":
147*b7c941bbSAndroid Build Coastguard Worker    if len(sys.argv) < 4:
148*b7c941bbSAndroid Build Coastguard Worker        print "Usage: splitxml.py xmlfile outpath tagname"
149*b7c941bbSAndroid Build Coastguard Worker        sys.exit(1)
150*b7c941bbSAndroid Build Coastguard Worker
151*b7c941bbSAndroid Build Coastguard Worker    xmlsplitter = XMLSplitter(sys.argv[1], sys.argv[2])
152*b7c941bbSAndroid Build Coastguard Worker
153*b7c941bbSAndroid Build Coastguard Worker    xmlsplitter.split(sys.argv[3])
154*b7c941bbSAndroid Build Coastguard Worker
155