1 /*
2  * Copyright (C) 2018 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.server.wifi.hotspot2.omadm;
18 
19 import android.annotation.NonNull;
20 import android.util.Log;
21 
22 import org.w3c.dom.Document;
23 import org.w3c.dom.Element;
24 
25 import java.io.StringWriter;
26 
27 import javax.xml.parsers.DocumentBuilder;
28 import javax.xml.parsers.DocumentBuilderFactory;
29 import javax.xml.parsers.ParserConfigurationException;
30 import javax.xml.transform.OutputKeys;
31 import javax.xml.transform.Transformer;
32 import javax.xml.transform.TransformerException;
33 import javax.xml.transform.TransformerFactory;
34 import javax.xml.transform.dom.DOMSource;
35 import javax.xml.transform.stream.StreamResult;
36 
37 /**
38  * Provides serialization API for OMA DM Management Object.
39  */
40 class MoSerializer {
41     static final String TAG = "MoSerializable";
42     static final String DM_VERSION = "1.2";
43     static final String TAG_MGMT_TREE = "MgmtTree";
44     static final String TAG_VERSION = "VerDTD";
45     static final String TAG_NODE = "Node";
46     static final String TAG_NODENAME = "NodeName";
47     static final String TAG_PATH = "Path";
48     static final String TAG_VALUE = "Value";
49     static final String TAG_RTPROPERTIES = "RTProperties";
50     static final String TAG_TYPE = "Type";
51     static final String TAG_DDF_NAME = "DDFName";
52     private DocumentBuilder mDbBuilder;
53 
MoSerializer()54     public MoSerializer() throws ParserConfigurationException {
55         mDbBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
56     }
57 
58     /**
59      * Serializes the Management Object into a XML format.
60      *
61      * @return {@link String) that indicates the entire xml of {@link MoSerializer}},
62      * <code>null<code/> in case of failure.
63      */
serialize(@onNull Document doc)64     String serialize(@NonNull Document doc) {
65         StringWriter writer = new StringWriter();
66         try {
67             TransformerFactory tf = TransformerFactory.newInstance();
68             Transformer transformer = tf.newTransformer();
69             transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
70             transformer.transform(new DOMSource(doc), new StreamResult(writer));
71         } catch (TransformerException e) {
72             e.printStackTrace();
73             return null;
74         }
75         return writer.toString();
76     }
77 
78     /**
79      * Create new Document to make a XML document of OMA DM Management Object.
80      *
81      * @return new {@link Document}
82      */
createNewDocument()83     Document createNewDocument() {
84         return mDbBuilder.newDocument();
85     }
86 
87     /**
88      * Generates root Node starting a "MgmtTree".
89      *
90      * Expected output: <MgmtTree></MgmtTree>
91      * @param doc {@link Document} that indicates an entire xml document.
92      * @return {@link Element} for Root
93      */
createMgmtTree(@onNull Document doc)94     Element createMgmtTree(@NonNull Document doc) {
95         // root element
96         Element rootElement = doc.createElement(TAG_MGMT_TREE);
97         doc.appendChild(rootElement);
98         return rootElement;
99     }
100 
101     /**
102      * Generates DTD version Node.
103      *
104      * Expected output: <VerDTD>[value]</VerDTD>
105      * @param doc {@link Document} that indicates an entire xml document.
106      * @return {@link Element} for new Node
107      */
writeVersion(@onNull Document doc)108     Element writeVersion(@NonNull Document doc) {
109         Element dtdElement = doc.createElement(TAG_VERSION);
110         dtdElement.appendChild(doc.createTextNode(DM_VERSION));
111         return dtdElement;
112     }
113 
114     /**
115      * Generates Node having {@param nodeName}
116      *
117      * Expected output: <Node><NodeName>[nodeName]</NodeName></Node>
118      * @param doc {@link Document} that indicates an entire xml document.
119      * @param nodeName node name for new node.
120      * @return {@link Element} for new Node
121      */
createNode(@onNull Document doc, @NonNull String nodeName)122     Element createNode(@NonNull Document doc, @NonNull String nodeName) {
123         Element node = doc.createElement(TAG_NODE);
124         Element nameNode = doc.createElement(TAG_NODENAME);
125         nameNode.appendChild(doc.createTextNode(nodeName));
126         node.appendChild(nameNode);
127         return node;
128     }
129 
130     /** Generates Node with the Unique Resource Name (URN).
131      *
132      * URN is encapsulated inside RTProperties node.
133      *
134      * Expected output: <RTProperties><Type><DDFName>[urn]</DDFName></Type></RTProperites>
135      * @param doc {@link Document} that indicates an entire xml document.
136      * @param urn The unique resource name
137      *
138      * @return {@link Element} for new Node
139      */
createNodeForUrn(@onNull Document doc, @NonNull String urn)140     Element createNodeForUrn(@NonNull Document doc, @NonNull String urn) {
141         Element node = doc.createElement(TAG_RTPROPERTIES);
142         Element type = doc.createElement(TAG_TYPE);
143         Element ddfName = doc.createElement(TAG_DDF_NAME);
144         ddfName.appendChild(doc.createTextNode(urn));
145         type.appendChild(ddfName);
146         node.appendChild(type);
147         return node;
148     }
149 
150     /**
151      * Generates for a node with a value.
152      *
153      * Expected output:
154      * <Node><NodeName>[name]</NodeName><Value>[value]</Value></Node>
155      * @param doc {@link Document} that indicates an entire xml document.
156      * @param name name of the node.
157      * @param value value of the node
158      *
159      * @return {@link Element} for new Node
160      */
createNodeForValue(@onNull Document doc, @NonNull String name, @NonNull String value)161     Element createNodeForValue(@NonNull Document doc, @NonNull String name, @NonNull String value) {
162         Element node = doc.createElement(TAG_NODE);
163         Element nameNode = doc.createElement(TAG_NODENAME);
164         nameNode.appendChild(doc.createTextNode(name));
165         node.appendChild(nameNode);
166 
167         Element valueNode = doc.createElement(TAG_VALUE);
168         valueNode.appendChild(doc.createTextNode(value));
169 
170         node.appendChild(valueNode);
171         return node;
172     }
173 }