1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage org.xmlpull.v1;
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream;
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Iterator;
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The name of actual factory class will be determined based on several parameters.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * It works similar to JAXP but tailored to work in J2ME environments
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (no access to system properties or file system) so name of parser class factory to use
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and its class used for loading (no class loader - on J2ME no access to context class loaders)
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * must be passed explicitly. If no name of parser factory was passed (or is null)
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * it will try to find name by searching in CLASSPATH for
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * META-INF/services/org.xmlpull.v1.XmlPullParserFactory resource that should contain
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a comma separated list of class names of factories or parsers to try (in order from
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * left to the right). If none found, it will throw an exception.
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <br /><strong>NOTE:</strong>In J2SE or J2EE environments, you may want to use
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>newInstance(property, classLoaderCtx)</code>
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * where first argument is
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <code>System.getProperty(XmlPullParserFactory.PROPERTY_NAME)</code>
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and second is <code>Thread.getContextClassLoader().getClass()</code> .
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see XmlPullParser
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @author Stefan Haustein
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class XmlPullParserFactory {
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** used as default class to server as context class in newInstance() */
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    final static Class referenceContextClass;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static {
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        XmlPullParserFactory f = new XmlPullParserFactory();
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        referenceContextClass = f.getClass();
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** Name of the system or midlet property that should be used for
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     a system property containing a comma separated list of factory
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     or parser class names (value:
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     org.xmlpull.v1.XmlPullParserFactory). */
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final String PROPERTY_NAME =
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "org.xmlpull.v1.XmlPullParserFactory";
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final String RESOURCE_NAME =
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "/META-INF/services/" + PROPERTY_NAME;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // public static final String DEFAULT_PROPERTY =
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //    "org.xmlpull.xpp3.XmlPullParser,org.kxml2.io.KXmlParser";
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected ArrayList parserClasses;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected String classNamesLocation;
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected ArrayList serializerClasses;
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // features are kept there
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected HashMap features = new HashMap();
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Protected constructor to be called by factory implementations.
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected XmlPullParserFactory() {
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Set the features to be set when XML Pull Parser is created by this factory.
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name string with URI identifying feature
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param state if true feature will be set; if false will be ignored
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setFeature(String name,
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           boolean state) throws XmlPullParserException {
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        features.put(name, new Boolean(state));
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Return the current value of the feature with given name.
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name The name of feature to be retrieved.
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return The value of named feature.
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     Unknown features are <string>always</strong> returned as false
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean getFeature (String name) {
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Boolean value = (Boolean) features.get(name);
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return value != null ? value.booleanValue() : false;
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Specifies that the parser produced by this factory will provide
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * support for XML namespaces.
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * By default the value of this is set to false.
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param awareness true if the parser produced by this code
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *    will provide support for XML namespaces;  false otherwise.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setNamespaceAware(boolean awareness) {
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, new Boolean (awareness));
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates whether or not the factory is configured to produce
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parsers which are namespace aware
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return  true if the factory is configured to produce parsers
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *    which are namespace aware; false otherwise.
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isNamespaceAware() {
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getFeature (XmlPullParser.FEATURE_PROCESS_NAMESPACES);
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Specifies that the parser produced by this factory will be validating
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * By default the value of this is set to false.
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param validating - if true the parsers created by this factory  must be validating.
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setValidating(boolean validating) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        features.put (XmlPullParser.FEATURE_VALIDATION, new Boolean (validating));
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates whether or not the factory is configured to produce parsers
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which validate the XML content during parse.
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return   true if the factory is configured to produce parsers
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which validate the XML content during parse; false otherwise.
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isValidating() {
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return getFeature (XmlPullParser.FEATURE_VALIDATION);
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new instance of a XML Pull Parser
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * using the currently configured factory features.
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return A new instance of a XML Pull Parser.
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws XmlPullParserException if a parser cannot be created which satisfies the
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * requested configuration.
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public XmlPullParser newPullParser() throws XmlPullParserException {
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parserClasses == null) throw new XmlPullParserException
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ("Factory initialization was incomplete - has not tried "+classNamesLocation);
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parserClasses.size() == 0) throw new XmlPullParserException
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ("No valid parser classes found in "+classNamesLocation);
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final StringBuffer issues = new StringBuffer ();
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < parserClasses.size(); i++) {
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            final Class ppClass = (Class) parserClasses.get(i);
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                final XmlPullParser pp = (XmlPullParser) ppClass.newInstance();
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                for (Iterator iter = features.keySet().iterator(); iter.hasNext(); ) {
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    final String key = (String) iter.next();
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    final Boolean value = (Boolean) features.get(key);
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if(value != null && value.booleanValue()) {
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        pp.setFeature(key, true);
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return pp;
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch(Exception ex) {
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new XmlPullParserException ("could not create parser: "+issues);
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new instance of a XML Serializer.
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>NOTE:</b> factory features are not used for XML Serializer.
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return A new instance of a XML Serializer.
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws XmlPullParserException if a parser cannot be created which satisfies the
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * requested configuration.
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public XmlSerializer newSerializer() throws XmlPullParserException {
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (serializerClasses == null) {
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new XmlPullParserException
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ("Factory initialization incomplete - has not tried "+classNamesLocation);
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(serializerClasses.size() == 0) {
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new XmlPullParserException
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                ("No valid serializer classes found in "+classNamesLocation);
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final StringBuffer issues = new StringBuffer ();
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < serializerClasses.size (); i++) {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            final Class ppClass = (Class) serializerClasses.get(i);
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                final XmlSerializer ser = (XmlSerializer) ppClass.newInstance();
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return ser;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } catch(Exception ex) {
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                issues.append (ppClass.getName () + ": "+ ex.toString ()+"; ");
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new XmlPullParserException ("could not create serializer: "+issues);
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Create a new instance of a PullParserFactory that can be used
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to create XML pull parsers (see class description for more
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * details).
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a new instance of a PullParserFactory, as returned by newInstance (null, null);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static XmlPullParserFactory newInstance () throws XmlPullParserException {
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return newInstance(null, null);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static XmlPullParserFactory newInstance (String classNames, Class context)
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throws XmlPullParserException {
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
255113154c2cf1c09894c4426d30e37f03dd6fe4785Elliott Hughes        /*
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (context == null) {
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //NOTE: make sure context uses the same class loader as API classes
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //      this is the best we can do without having access to context classloader in J2ME
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //      if API is in the same classloader as implementation then this will work
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            context = referenceContextClass;
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String  classNamesLocation = null;
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classNames == null || classNames.length() == 0 || "DEFAULT".equals(classNames)) {
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                InputStream is = context.getResourceAsStream (RESOURCE_NAME);
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (is == null) throw new XmlPullParserException
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        ("resource not found: "+RESOURCE_NAME
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                             +" make sure that parser implementing XmlPull API is available");
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                final StringBuffer sb = new StringBuffer();
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                while (true) {
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    final int ch = is.read();
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (ch < 0) break;
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    else if (ch > ' ')
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        sb.append((char) ch);
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                is.close ();
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                classNames = sb.toString ();
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catch (Exception e) {
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new XmlPullParserException (null, null, e);
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            classNamesLocation = "resource "+RESOURCE_NAME+" that contained '"+classNames+"'";
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            classNamesLocation =
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "parameter classNames to newInstance() that contained '"+classNames+"'";
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        */
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classNames = "org.kxml2.io.KXmlParser,org.kxml2.io.KXmlSerializer";
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        XmlPullParserFactory factory = null;
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final ArrayList parserClasses = new ArrayList();
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final ArrayList serializerClasses = new ArrayList();
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int pos = 0;
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (pos < classNames.length ()) {
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int cut = classNames.indexOf (',', pos);
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cut == -1) cut = classNames.length ();
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            final String name = classNames.substring (pos, cut);
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Class candidate = null;
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Object instance = null;
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            try {
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                candidate = Class.forName (name);
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // necessary because of J2ME .class issue
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                instance = candidate.newInstance ();
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            catch (Exception e) {}
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (candidate != null) {
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                boolean recognized = false;
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (instance instanceof XmlPullParser) {
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    parserClasses.add(candidate);
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    recognized = true;
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (instance instanceof XmlSerializer) {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    serializerClasses.add(candidate);
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    recognized = true;
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (instance instanceof XmlPullParserFactory) {
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (factory == null) {
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        factory = (XmlPullParserFactory) instance;
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    recognized = true;
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (!recognized) {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new XmlPullParserException ("incompatible class: "+name);
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            pos = cut + 1;
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (factory == null) {
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            factory = new XmlPullParserFactory ();
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        factory.parserClasses = parserClasses;
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        factory.serializerClasses = serializerClasses;
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        factory.classNamesLocation = "org.kxml2.io.kXmlParser,org.kxml2.io.KXmlSerializer";
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return factory;
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
348