summaryrefslogtreecommitdiffstats
path: root/xml
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2014-02-11 11:41:38 +0000
committerNarayan Kamath <narayan@google.com>2014-02-13 12:42:42 +0000
commit34543a94c2e11f602114d2097a8f977d40d56cb9 (patch)
treeeae43adb83dc416d7706c1f245c34c4a6d8a75c3 /xml
parent2e413ba8dfbd9d6c7720afc36699b26eda7aebac (diff)
downloadlibcore-34543a94c2e11f602114d2097a8f977d40d56cb9.zip
libcore-34543a94c2e11f602114d2097a8f977d40d56cb9.tar.gz
libcore-34543a94c2e11f602114d2097a8f977d40d56cb9.tar.bz2
Fix compatibility issues in XmlPullParserFactory.
- We should set features on a parser only if the feature value is true. I.e, we guarantee that we'll never call XmlPullParser.setFeature(..., false). - In change 0363556bad8930a, we didn't consider the fact that apps could extend XmlPullParserFactory and modify protected fields to change the parser / serializer that's instantiated. I've reinstated this feature, despite the fact that it's a particularly pointless feature on a more-or-less pointless public API. Apps can and should instantiate their own parser instances directly instead of going through this factory. bug: 12956724 Change-Id: I793eba335b5385eb641e023b3613bba4515a85bf
Diffstat (limited to 'xml')
-rw-r--r--xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java113
1 files changed, 86 insertions, 27 deletions
diff --git a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
index 32e4f20..41db89c 100644
--- a/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
+++ b/xml/src/main/java/org/xmlpull/v1/XmlPullParserFactory.java
@@ -20,18 +20,13 @@ import java.util.Map;
*/
public class XmlPullParserFactory {
- // TODO: Deprecate or remove these fields. They're currently unused
- // but are public APIs.
- /** Currently unused. */
- public static final String PROPERTY_NAME =
- "org.xmlpull.v1.XmlPullParserFactory";
- /** Currently unused */
+ public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
+ protected ArrayList parserClasses;
+ protected ArrayList serializerClasses;
+
+ /** Unused, but we have to keep it because it's public API. */
protected String classNamesLocation = null;
- /** Currently unused */
- protected ArrayList parserClasses = null;
- /** Currently unused */
- protected ArrayList serializerClasses = null;
// features are kept there
// TODO: This can't be made final because it's a public API.
@@ -40,12 +35,18 @@ public class XmlPullParserFactory {
/**
* Protected constructor to be called by factory implementations.
*/
-
protected XmlPullParserFactory() {
+ parserClasses = new ArrayList<String>();
+ serializerClasses = new ArrayList<String>();
+
+ try {
+ parserClasses.add(Class.forName("org.kxml2.io.KXmlParser"));
+ serializerClasses.add(Class.forName("org.kxml2.io.KXmlSerializer"));
+ } catch (ClassNotFoundException e) {
+ throw new AssertionError();
+ }
}
-
-
/**
* Set the features to be set when XML Pull Parser is created by this factory.
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
@@ -53,7 +54,6 @@ public class XmlPullParserFactory {
* @param name string with URI identifying feature
* @param state if true feature will be set; if false will be ignored
*/
-
public void setFeature(String name, boolean state) throws XmlPullParserException {
features.put(name, state);
}
@@ -67,8 +67,7 @@ public class XmlPullParserFactory {
* @return The value of named feature.
* Unknown features are <string>always</strong> returned as false
*/
-
- public boolean getFeature (String name) {
+ public boolean getFeature(String name) {
Boolean value = features.get(name);
return value != null ? value.booleanValue() : false;
}
@@ -81,7 +80,6 @@ public class XmlPullParserFactory {
* @param awareness true if the parser produced by this code
* will provide support for XML namespaces; false otherwise.
*/
-
public void setNamespaceAware(boolean awareness) {
features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, awareness);
}
@@ -94,12 +92,10 @@ public class XmlPullParserFactory {
* @return true if the factory is configured to produce parsers
* which are namespace aware; false otherwise.
*/
-
public boolean isNamespaceAware() {
- return getFeature (XmlPullParser.FEATURE_PROCESS_NAMESPACES);
+ return getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
}
-
/**
* Specifies that the parser produced by this factory will be validating
* (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
@@ -108,9 +104,8 @@ public class XmlPullParserFactory {
*
* @param validating - if true the parsers created by this factory must be validating.
*/
-
public void setValidating(boolean validating) {
- features.put (XmlPullParser.FEATURE_VALIDATION, validating);
+ features.put(XmlPullParser.FEATURE_VALIDATION, validating);
}
/**
@@ -122,7 +117,7 @@ public class XmlPullParserFactory {
*/
public boolean isValidating() {
- return getFeature (XmlPullParser.FEATURE_VALIDATION);
+ return getFeature(XmlPullParser.FEATURE_VALIDATION);
}
/**
@@ -131,16 +126,80 @@ public class XmlPullParserFactory {
*
* @return A new instance of a XML Pull Parser.
*/
-
public XmlPullParser newPullParser() throws XmlPullParserException {
- final XmlPullParser pp = new KXmlParser();
+ final XmlPullParser pp = getParserInstance();
for (Map.Entry<String, Boolean> entry : features.entrySet()) {
- pp.setFeature(entry.getKey(), entry.getValue());
+ // NOTE: This test is needed for compatibility reasons. We guarantee
+ // that we only set a feature on a parser if its value is true.
+ if (entry.getValue()) {
+ pp.setFeature(entry.getKey(), entry.getValue());
+ }
}
return pp;
}
+ private XmlPullParser getParserInstance() throws XmlPullParserException {
+ ArrayList<Exception> exceptions = null;
+
+ if (parserClasses != null && !parserClasses.isEmpty()) {
+ exceptions = new ArrayList<Exception>();
+ for (Object o : parserClasses) {
+ try {
+ if (o != null) {
+ Class<?> parserClass = (Class<?>) o;
+ return (XmlPullParser) parserClass.newInstance();
+ }
+ } catch (InstantiationException e) {
+ exceptions.add(e);
+ } catch (IllegalAccessException e) {
+ exceptions.add(e);
+ } catch (ClassCastException e) {
+ exceptions.add(e);
+ }
+ }
+ }
+
+ throw newInstantiationException("Invalid parser class list", exceptions);
+ }
+
+ private XmlSerializer getSerializerInstance() throws XmlPullParserException {
+ ArrayList<Exception> exceptions = null;
+
+ if (serializerClasses != null && !serializerClasses.isEmpty()) {
+ exceptions = new ArrayList<Exception>();
+ for (Object o : serializerClasses) {
+ try {
+ if (o != null) {
+ Class<?> serializerClass = (Class<?>) o;
+ return (XmlSerializer) serializerClass.newInstance();
+ }
+ } catch (InstantiationException e) {
+ exceptions.add(e);
+ } catch (IllegalAccessException e) {
+ exceptions.add(e);
+ } catch (ClassCastException e) {
+ exceptions.add(e);
+ }
+ }
+ }
+
+ throw newInstantiationException("Invalid serializer class list", exceptions);
+ }
+
+ private static XmlPullParserException newInstantiationException(String message,
+ ArrayList<Exception> exceptions) {
+ if (exceptions == null || exceptions.isEmpty()) {
+ return new XmlPullParserException(message);
+ } else {
+ XmlPullParserException exception = new XmlPullParserException(message);
+ for (Exception ex : exceptions) {
+ exception.addSuppressed(ex);
+ }
+
+ return exception;
+ }
+ }
/**
* Creates a new instance of a XML Serializer.
@@ -153,7 +212,7 @@ public class XmlPullParserFactory {
*/
public XmlSerializer newSerializer() throws XmlPullParserException {
- return new KXmlSerializer();
+ return getSerializerInstance();
}
/**