XmlUtil.java revision 2b7e486db94455a4a4c0124b5ba5e57c837ef10e
1/*
2 * Copyright (C) 2016 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
17package com.android.server.wifi.util;
18
19import com.android.internal.util.XmlUtils;
20
21import org.xmlpull.v1.XmlPullParser;
22import org.xmlpull.v1.XmlPullParserException;
23import org.xmlpull.v1.XmlSerializer;
24
25import java.io.IOException;
26
27/**
28 * Utils for manipulating XML data. This is essentially a wrapper over XmlUtils provided by core.
29 * The utility provides methods to write/parse section headers and write/parse values.
30 *
31 * This utility is designed for formatting the XML into the following format:
32 * <Document Header>
33 *  <Section 1 Header>
34 *   <Value 1>
35 *   <Value 2>
36 *   ...
37 *   <Sub Section 1 Header>
38 *    <Value 1>
39 *    <Value 2>
40 *    ...
41 *   </Sub Section 1 Header>
42 *  </Section 1 Header>
43 * </Document Header>
44 */
45public class XmlUtil {
46    private static final String TAG = "WifiXmlUtil";
47
48    /**
49     * Move the XML stream to the start of the next tag or the end of document.
50     */
51    private static void gotoNextElement(XmlPullParser in)
52            throws XmlPullParserException, IOException {
53        XmlUtils.nextElement(in);
54    }
55
56    /**
57     * Start processing the XML stream at the document header.
58     *
59     * @param in         XmlPullParser instance pointing to the XML stream.
60     * @param headerName expected name for the start tag.
61     */
62    public static void gotoDocumentStart(XmlPullParser in, String headerName)
63            throws XmlPullParserException, IOException {
64        XmlUtils.beginDocument(in, headerName);
65    }
66
67    /**
68     * Move the XML stream to the next section header. The provided outerdepth is used to find
69     * sub sections within the provided depth.
70     *
71     * @param in         XmlPullParser instance pointing to the XML stream.
72     * @param headerName expected name for the start tag.
73     * @param outerDepth Find section within this depth.
74     * @return {@code true} if a start tag with the provided name is found, {@code false} otherwise
75     */
76    public static boolean gotoNextSection(XmlPullParser in, String headerName, int outerDepth)
77            throws XmlPullParserException, IOException {
78        while (XmlUtils.nextElementWithin(in, outerDepth)) {
79            if (in.getName().equals(headerName)) {
80                return true;
81            }
82        }
83        return false;
84    }
85
86    /**
87     * Read the next value in the XML stream using core XmlUtils and ensure that it matches the
88     * provided name.
89     * Note: Because there could be genuine null values being read from the XML, this method raises
90     * an exception to indicate errors.
91     *
92     * @param in XmlPullParser instance pointing to the XML stream.
93     * @return value retrieved from the XML stream.
94     * @throws {XmlPullParserException}, if the value read does not match |expectedName|,
95     *                                   or if parsing errors occur.
96     */
97    public static Object readNextValue(XmlPullParser in, String expectedName)
98            throws XmlPullParserException, IOException {
99        String[] names = new String[1];
100        names[0] = new String();
101        gotoNextElement(in);
102        Object value = XmlUtils.readValueXml(in, names);
103        if (names[0].equals(expectedName)) {
104            // XmlUtils.readValue does not always move the stream to the end of the tag. So, move
105            // it to the end before returning from here.
106            while (in.getEventType() != XmlPullParser.END_DOCUMENT
107                    && in.getEventType() != XmlPullParser.END_TAG) {
108                in.next();
109            }
110            return value;
111        }
112        throw new XmlPullParserException(
113                "Value not found. Expected: " + expectedName + ", but got: " + names[0]);
114    }
115
116    /**
117     * Write the XML document start with the provided document header name.
118     *
119     * @param out        XmlSerializer instance pointing to the XML stream.
120     * @param headerName name for the start tag.
121     */
122    public static void writeDocumentStart(XmlSerializer out, String headerName)
123            throws XmlPullParserException, IOException {
124        out.startDocument(null, true);
125        out.startTag(null, headerName);
126    }
127
128    /**
129     * Write the XML document end with the provided document header name.
130     *
131     * @param out        XmlSerializer instance pointing to the XML stream.
132     * @param headerName name for the end tag.
133     */
134    public static void writeDocumentEnd(XmlSerializer out, String headerName)
135            throws XmlPullParserException, IOException {
136        out.endTag(null, headerName);
137        out.endDocument();
138    }
139
140    /**
141     * Write a section start header tag with the provided section name.
142     *
143     * @param out        XmlSerializer instance pointing to the XML stream.
144     * @param headerName name for the start tag.
145     */
146    public static void writeNextSectionStart(XmlSerializer out, String headerName)
147            throws XmlPullParserException, IOException {
148        out.startTag(null, headerName);
149    }
150
151    /**
152     * Write a section end header tag with the provided section name.
153     *
154     * @param out        XmlSerializer instance pointing to the XML stream.
155     * @param headerName name for the end tag.
156     */
157    public static void writeNextSectionEnd(XmlSerializer out, String headerName)
158            throws XmlPullParserException, IOException {
159        out.endTag(null, headerName);
160    }
161
162    /**
163     * Write the value with the provided name in the XML stream using core XmlUtils.
164     *
165     * @param out   XmlSerializer instance pointing to the XML stream.
166     * @param name  name of the value.
167     * @param value value to be written.
168     */
169    public static void writeNextValue(XmlSerializer out, String name, Object value)
170            throws XmlPullParserException, IOException {
171        XmlUtils.writeValueXml(value, name, out);
172    }
173}
174
175