blob: 41db89c4e11b04c86dfc6f558767fa79533882ae [file] [log] [blame]
The Android Open Source Projectadc854b2009-03-03 19:28:47 -08001/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
2// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
3
4package org.xmlpull.v1;
5
Narayan Kamath03635562013-10-16 12:13:01 +01006import org.kxml2.io.KXmlParser;
7import org.kxml2.io.KXmlSerializer;
8
Narayan Kamathabd0b0a2013-10-18 10:06:55 +01009import java.util.ArrayList;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080010import java.util.HashMap;
Narayan Kamath03635562013-10-16 12:13:01 +010011import java.util.Map;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080012
13/**
14 * This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080015 *
16 * @see XmlPullParser
17 *
18 * @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
19 * @author Stefan Haustein
20 */
21
22public class XmlPullParserFactory {
Narayan Kamathabd0b0a2013-10-18 10:06:55 +010023
Narayan Kamath34543a92014-02-11 11:41:38 +000024 public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
25 protected ArrayList parserClasses;
26 protected ArrayList serializerClasses;
27
28 /** Unused, but we have to keep it because it's public API. */
Narayan Kamathabd0b0a2013-10-18 10:06:55 +010029 protected String classNamesLocation = null;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080030
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080031 // features are kept there
Narayan Kamathabd0b0a2013-10-18 10:06:55 +010032 // TODO: This can't be made final because it's a public API.
33 protected HashMap<String, Boolean> features = new HashMap<String, Boolean>();
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080034
35 /**
36 * Protected constructor to be called by factory implementations.
37 */
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080038 protected XmlPullParserFactory() {
Narayan Kamath34543a92014-02-11 11:41:38 +000039 parserClasses = new ArrayList<String>();
40 serializerClasses = new ArrayList<String>();
41
42 try {
43 parserClasses.add(Class.forName("org.kxml2.io.KXmlParser"));
44 serializerClasses.add(Class.forName("org.kxml2.io.KXmlSerializer"));
45 } catch (ClassNotFoundException e) {
46 throw new AssertionError();
47 }
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080048 }
49
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080050 /**
51 * Set the features to be set when XML Pull Parser is created by this factory.
52 * <p><b>NOTE:</b> factory features are not used for XML Serializer.
53 *
54 * @param name string with URI identifying feature
55 * @param state if true feature will be set; if false will be ignored
56 */
Elliott Hughes9c324212011-02-24 17:58:33 -080057 public void setFeature(String name, boolean state) throws XmlPullParserException {
58 features.put(name, state);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080059 }
60
61
62 /**
63 * Return the current value of the feature with given name.
64 * <p><b>NOTE:</b> factory features are not used for XML Serializer.
65 *
66 * @param name The name of feature to be retrieved.
67 * @return The value of named feature.
68 * Unknown features are <string>always</strong> returned as false
69 */
Narayan Kamath34543a92014-02-11 11:41:38 +000070 public boolean getFeature(String name) {
Narayan Kamath03635562013-10-16 12:13:01 +010071 Boolean value = features.get(name);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080072 return value != null ? value.booleanValue() : false;
73 }
74
75 /**
76 * Specifies that the parser produced by this factory will provide
77 * support for XML namespaces.
78 * By default the value of this is set to false.
79 *
80 * @param awareness true if the parser produced by this code
81 * will provide support for XML namespaces; false otherwise.
82 */
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080083 public void setNamespaceAware(boolean awareness) {
Elliott Hughes9c324212011-02-24 17:58:33 -080084 features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, awareness);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080085 }
86
87 /**
88 * Indicates whether or not the factory is configured to produce
89 * parsers which are namespace aware
90 * (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
91 *
92 * @return true if the factory is configured to produce parsers
93 * which are namespace aware; false otherwise.
94 */
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080095 public boolean isNamespaceAware() {
Narayan Kamath34543a92014-02-11 11:41:38 +000096 return getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080097 }
98
The Android Open Source Projectadc854b2009-03-03 19:28:47 -080099 /**
100 * Specifies that the parser produced by this factory will be validating
101 * (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
102 *
103 * By default the value of this is set to false.
104 *
105 * @param validating - if true the parsers created by this factory must be validating.
106 */
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800107 public void setValidating(boolean validating) {
Narayan Kamath34543a92014-02-11 11:41:38 +0000108 features.put(XmlPullParser.FEATURE_VALIDATION, validating);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800109 }
110
111 /**
112 * Indicates whether or not the factory is configured to produce parsers
113 * which validate the XML content during parse.
114 *
115 * @return true if the factory is configured to produce parsers
116 * which validate the XML content during parse; false otherwise.
117 */
118
119 public boolean isValidating() {
Narayan Kamath34543a92014-02-11 11:41:38 +0000120 return getFeature(XmlPullParser.FEATURE_VALIDATION);
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800121 }
122
123 /**
124 * Creates a new instance of a XML Pull Parser
125 * using the currently configured factory features.
126 *
127 * @return A new instance of a XML Pull Parser.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800128 */
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800129 public XmlPullParser newPullParser() throws XmlPullParserException {
Narayan Kamath34543a92014-02-11 11:41:38 +0000130 final XmlPullParser pp = getParserInstance();
Narayan Kamath03635562013-10-16 12:13:01 +0100131 for (Map.Entry<String, Boolean> entry : features.entrySet()) {
Narayan Kamath34543a92014-02-11 11:41:38 +0000132 // NOTE: This test is needed for compatibility reasons. We guarantee
133 // that we only set a feature on a parser if its value is true.
134 if (entry.getValue()) {
135 pp.setFeature(entry.getKey(), entry.getValue());
136 }
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800137 }
138
Narayan Kamath03635562013-10-16 12:13:01 +0100139 return pp;
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800140 }
141
Narayan Kamath34543a92014-02-11 11:41:38 +0000142 private XmlPullParser getParserInstance() throws XmlPullParserException {
143 ArrayList<Exception> exceptions = null;
144
145 if (parserClasses != null && !parserClasses.isEmpty()) {
146 exceptions = new ArrayList<Exception>();
147 for (Object o : parserClasses) {
148 try {
149 if (o != null) {
150 Class<?> parserClass = (Class<?>) o;
151 return (XmlPullParser) parserClass.newInstance();
152 }
153 } catch (InstantiationException e) {
154 exceptions.add(e);
155 } catch (IllegalAccessException e) {
156 exceptions.add(e);
157 } catch (ClassCastException e) {
158 exceptions.add(e);
159 }
160 }
161 }
162
163 throw newInstantiationException("Invalid parser class list", exceptions);
164 }
165
166 private XmlSerializer getSerializerInstance() throws XmlPullParserException {
167 ArrayList<Exception> exceptions = null;
168
169 if (serializerClasses != null && !serializerClasses.isEmpty()) {
170 exceptions = new ArrayList<Exception>();
171 for (Object o : serializerClasses) {
172 try {
173 if (o != null) {
174 Class<?> serializerClass = (Class<?>) o;
175 return (XmlSerializer) serializerClass.newInstance();
176 }
177 } catch (InstantiationException e) {
178 exceptions.add(e);
179 } catch (IllegalAccessException e) {
180 exceptions.add(e);
181 } catch (ClassCastException e) {
182 exceptions.add(e);
183 }
184 }
185 }
186
187 throw newInstantiationException("Invalid serializer class list", exceptions);
188 }
189
190 private static XmlPullParserException newInstantiationException(String message,
191 ArrayList<Exception> exceptions) {
192 if (exceptions == null || exceptions.isEmpty()) {
193 return new XmlPullParserException(message);
194 } else {
195 XmlPullParserException exception = new XmlPullParserException(message);
196 for (Exception ex : exceptions) {
197 exception.addSuppressed(ex);
198 }
199
200 return exception;
201 }
202 }
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800203
204 /**
205 * Creates a new instance of a XML Serializer.
206 *
207 * <p><b>NOTE:</b> factory features are not used for XML Serializer.
208 *
209 * @return A new instance of a XML Serializer.
210 * @throws XmlPullParserException if a parser cannot be created which satisfies the
211 * requested configuration.
212 */
213
214 public XmlSerializer newSerializer() throws XmlPullParserException {
Narayan Kamath34543a92014-02-11 11:41:38 +0000215 return getSerializerInstance();
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800216 }
217
218 /**
Narayan Kamath03635562013-10-16 12:13:01 +0100219 * Creates a new instance of a PullParserFactory that can be used
220 * to create XML pull parsers. The factory will always return instances
221 * of {@link KXmlParser} and {@link KXmlSerializer}.
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800222 */
223 public static XmlPullParserFactory newInstance () throws XmlPullParserException {
Narayan Kamath03635562013-10-16 12:13:01 +0100224 return new XmlPullParserFactory();
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800225 }
226
Narayan Kamath03635562013-10-16 12:13:01 +0100227 /**
228 * Creates a factory that always returns instances of of {@link KXmlParser} and
229 * {@link KXmlSerializer}. This <b>does not</b> support factories capable of
230 * creating arbitrary parser and serializer implementations. Both arguments to this
231 * method are unused.
232 */
233 public static XmlPullParserFactory newInstance (String unused, Class unused2)
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800234 throws XmlPullParserException {
Narayan Kamath03635562013-10-16 12:13:01 +0100235 return newInstance();
The Android Open Source Projectadc854b2009-03-03 19:28:47 -0800236 }
237}