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