1 /*
2  * Copyright (C) 2007 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 android.util;
18 
19 import libcore.util.XmlObjectFactory;
20 
21 import org.xml.sax.ContentHandler;
22 import org.xml.sax.InputSource;
23 import org.xml.sax.SAXException;
24 import org.xml.sax.XMLReader;
25 import org.xmlpull.v1.XmlPullParser;
26 import org.xmlpull.v1.XmlPullParserException;
27 import org.xmlpull.v1.XmlSerializer;
28 
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.Reader;
32 import java.io.StringReader;
33 import java.io.UnsupportedEncodingException;
34 
35 /**
36  * XML utility methods.
37  */
38 public class Xml {
Xml()39     private Xml() {}
40 
41     /**
42      * {@link org.xmlpull.v1.XmlPullParser} "relaxed" feature name.
43      *
44      * @see <a href="http://xmlpull.org/v1/doc/features.html#relaxed">
45      *  specification</a>
46      */
47     public static String FEATURE_RELAXED = "http://xmlpull.org/v1/doc/features.html#relaxed";
48 
49     /**
50      * Parses the given xml string and fires events on the given SAX handler.
51      */
parse(String xml, ContentHandler contentHandler)52     public static void parse(String xml, ContentHandler contentHandler)
53             throws SAXException {
54         try {
55             XMLReader reader = XmlObjectFactory.newXMLReader();
56             reader.setContentHandler(contentHandler);
57             reader.parse(new InputSource(new StringReader(xml)));
58         } catch (IOException e) {
59             throw new AssertionError(e);
60         }
61     }
62 
63     /**
64      * Parses xml from the given reader and fires events on the given SAX
65      * handler.
66      */
parse(Reader in, ContentHandler contentHandler)67     public static void parse(Reader in, ContentHandler contentHandler)
68             throws IOException, SAXException {
69         XMLReader reader = XmlObjectFactory.newXMLReader();
70         reader.setContentHandler(contentHandler);
71         reader.parse(new InputSource(in));
72     }
73 
74     /**
75      * Parses xml from the given input stream and fires events on the given SAX
76      * handler.
77      */
parse(InputStream in, Encoding encoding, ContentHandler contentHandler)78     public static void parse(InputStream in, Encoding encoding,
79             ContentHandler contentHandler) throws IOException, SAXException {
80         XMLReader reader = XmlObjectFactory.newXMLReader();
81         reader.setContentHandler(contentHandler);
82         InputSource source = new InputSource(in);
83         source.setEncoding(encoding.expatName);
84         reader.parse(source);
85     }
86 
87     /**
88      * Returns a new pull parser with namespace support.
89      */
newPullParser()90     public static XmlPullParser newPullParser() {
91         try {
92             XmlPullParser parser = XmlObjectFactory.newXmlPullParser();
93             parser.setFeature(XmlPullParser.FEATURE_PROCESS_DOCDECL, true);
94             parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
95             return parser;
96         } catch (XmlPullParserException e) {
97             throw new AssertionError();
98         }
99     }
100 
101     /**
102      * Creates a new xml serializer.
103      */
newSerializer()104     public static XmlSerializer newSerializer() {
105         return XmlObjectFactory.newXmlSerializer();
106     }
107 
108     /**
109      * Supported character encodings.
110      */
111     public enum Encoding {
112 
113         US_ASCII("US-ASCII"),
114         UTF_8("UTF-8"),
115         UTF_16("UTF-16"),
116         ISO_8859_1("ISO-8859-1");
117 
118         final String expatName;
119 
Encoding(String expatName)120         Encoding(String expatName) {
121             this.expatName = expatName;
122         }
123     }
124 
125     /**
126      * Finds an encoding by name. Returns UTF-8 if you pass {@code null}.
127      */
findEncodingByName(String encodingName)128     public static Encoding findEncodingByName(String encodingName)
129             throws UnsupportedEncodingException {
130         if (encodingName == null) {
131             return Encoding.UTF_8;
132         }
133 
134         for (Encoding encoding : Encoding.values()) {
135             if (encoding.expatName.equalsIgnoreCase(encodingName))
136                 return encoding;
137         }
138         throw new UnsupportedEncodingException(encodingName);
139     }
140 
141     /**
142      * Return an AttributeSet interface for use with the given XmlPullParser.
143      * If the given parser itself implements AttributeSet, that implementation
144      * is simply returned.  Otherwise a wrapper class is
145      * instantiated on top of the XmlPullParser, as a proxy for retrieving its
146      * attributes, and returned to you.
147      *
148      * @param parser The existing parser for which you would like an
149      *               AttributeSet.
150      *
151      * @return An AttributeSet you can use to retrieve the
152      *         attribute values at each of the tags as the parser moves
153      *         through its XML document.
154      *
155      * @see AttributeSet
156      */
asAttributeSet(XmlPullParser parser)157     public static AttributeSet asAttributeSet(XmlPullParser parser) {
158         return (parser instanceof AttributeSet)
159                 ? (AttributeSet) parser
160                 : new XmlPullAttributes(parser);
161     }
162 }
163