diff --git a/google-http-client-xml/src/main/java/com/google/api/client/xml/DedicatedObjectParser.java b/google-http-client-xml/src/main/java/com/google/api/client/xml/DedicatedObjectParser.java index d2af22d8e..981bd6d5b 100644 --- a/google-http-client-xml/src/main/java/com/google/api/client/xml/DedicatedObjectParser.java +++ b/google-http-client-xml/src/main/java/com/google/api/client/xml/DedicatedObjectParser.java @@ -1,13 +1,16 @@ package com.google.api.client.xml; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import org.xmlpull.v1.XmlPullParserException; import com.google.api.client.util.ClassInfo; import com.google.api.client.util.FieldInfo; +import com.google.api.client.util.Types; public class DedicatedObjectParser extends Xml { @@ -100,8 +103,27 @@ public void mapCollection(final Class fieldClass, final String fieldName, fin } @Override - public void mapArrayWithClassTypeSetValue(final Object destination, final Object value){ - setValue(destination, value); + public boolean mapArrayWithClassType(final ParserParameter parameter, + final Field field, final String fieldName, + final Type fieldType, final Class fieldClass) + throws IOException, XmlPullParserException { + final boolean isStopped; // not an array/iterable or a map, but we do have a field + Object value = Types.newInstance(fieldClass); + int contextSize = parameter.context.size(); + parameter.context.add(fieldType); + isStopped = Xml.parseElementInternal(new ParserParameter(parameter.parser, + parameter.context, + value, // destination; never null. + null, + parameter.namespaceDictionary, + parameter.customizeParser)); + parameter.context.remove(contextSize); + + // mapArrayWithClassTypeSetValue(parameter.destination, value); + + setValue(parameter.destination, value); + + return isStopped; } } diff --git a/google-http-client-xml/src/main/java/com/google/api/client/xml/GenericXmlParser.java b/google-http-client-xml/src/main/java/com/google/api/client/xml/GenericXmlParser.java index 2633146ae..dad39e7d2 100644 --- a/google-http-client-xml/src/main/java/com/google/api/client/xml/GenericXmlParser.java +++ b/google-http-client-xml/src/main/java/com/google/api/client/xml/GenericXmlParser.java @@ -1,5 +1,6 @@ package com.google.api.client.xml; +import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Type; import java.util.ArrayList; @@ -7,6 +8,7 @@ import java.util.List; import java.util.Map; import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; import com.google.api.client.util.ClassInfo; public class GenericXmlParser extends Xml { @@ -102,8 +104,11 @@ public void mapCollection(final Class fieldClass, final String fieldName, fin @Override - public void mapArrayWithClassTypeSetValue(final Object fieldName, final Object value){ - setValue(fieldName, value); + public boolean mapArrayWithClassType(final ParserParameter parameter, + final Field field, final String fieldName, + final Type fieldType, final Class fieldClass) + { + throw new RuntimeException("No mapArrayWithClassType in GenericXml"); } } diff --git a/google-http-client-xml/src/main/java/com/google/api/client/xml/MapParser.java b/google-http-client-xml/src/main/java/com/google/api/client/xml/MapParser.java index 4bdc443d0..f7356948c 100644 --- a/google-http-client-xml/src/main/java/com/google/api/client/xml/MapParser.java +++ b/google-http-client-xml/src/main/java/com/google/api/client/xml/MapParser.java @@ -85,15 +85,13 @@ public void mapCollection(final Class fieldClass, final String fieldName, fin destinationMap.put(fieldName, list); } list.add(mapValue); - - } - @Override - public void mapArrayWithClassTypeSetValue(final Object fieldName, final Object value) { - setValue(fieldName, value); + public boolean mapArrayWithClassType(final ParserParameter parameter, + final Field field, final String fieldName, + final Type fieldType, final Class fieldClass) { + throw new RuntimeException("No mapArrayWithClassType in MapParser"); } - } diff --git a/google-http-client-xml/src/main/java/com/google/api/client/xml/Xml.java b/google-http-client-xml/src/main/java/com/google/api/client/xml/Xml.java index eb2186b85..7cf74d018 100644 --- a/google-http-client-xml/src/main/java/com/google/api/client/xml/Xml.java +++ b/google-http-client-xml/src/main/java/com/google/api/client/xml/Xml.java @@ -70,7 +70,9 @@ protected Xml(final ParserParameter parameter) { public abstract void mapCollection(final Class fieldClass, final String fieldName, final Map mapValue); - public abstract void mapArrayWithClassTypeSetValue(final Object destination, final Object value); + public abstract boolean mapArrayWithClassType(final ParserParameter parameter, + final Field field, final String fieldName, + final Type fieldType, final Class fieldClass) throws IOException, XmlPullParserException; /** * {@code "application/xml; charset=utf-8"} media type used as a default for XML parsing. @@ -233,7 +235,7 @@ public ParserParameter(XmlPullParser parser, * @throws XmlPullParserException */ - private static boolean parseElementInternal(final ParserParameter parameter) + protected static boolean parseElementInternal(final ParserParameter parameter) throws IOException, XmlPullParserException { // TODO(yanivi): method is too long; needs to be broken down into smaller methods and comment // better @@ -296,11 +298,9 @@ private static boolean parseElementInternal(final ParserParameter parameter) if ((parser instanceof DedicatedObjectParser)) { parser.setDestination(field); } - - sanityCheck(parser, field); + parser.sanityCheck(parser, field); parameter.valueType = field == null ? parameter.valueType : field.getGenericType(); - - mapTextToElementValue(parameter, parser, field, TEXT_CONTENT); + parser.mapTextToElementValue(parameter, field, TEXT_CONTENT); } break; case XmlPullParser.START_TAG: @@ -365,7 +365,7 @@ private static boolean parseElementInternal(final ParserParameter parameter) case XmlPullParser.TEXT: if (!ignore && level == 1) { parameter.valueType = field == null ? parameter.valueType : field.getGenericType(); - sanityCheck(parser, field); + parser.sanityCheck(parser, field); if (field == null) { throw new RuntimeException("Field can not be null here"); @@ -418,15 +418,6 @@ private static boolean parseElementInternal(final ParserParameter parameter) throw new RuntimeException("Field can not be null here. "); // if field would be null, we have to pass the destination Map; not sure how such a case looks like yet } - - if (parser instanceof MapParser) { - throw new RuntimeException("MapParser"); - } - - if (parser instanceof GenericXmlParser) { - throw new RuntimeException("GenericXmlParser"); - } - // done. isStopped = parser.mapArrayWithClassType(parameter, field, fieldName, fieldType, fieldClass); @@ -460,53 +451,22 @@ private static boolean parseElementInternal(final ParserParameter parameter) return isStopped; } - private static void sanityCheck(final Xml parser, final Field field) { + private void sanityCheck(final Xml parser, final Field field) { if (field != null && !(parser instanceof DedicatedObjectParser)) { throw new RuntimeException("Incorrect Parser"); } } - private static void mapTextToElementValue(final ParserParameter parameter, final Xml parser, final Field field, final String textContent) { + private void mapTextToElementValue(final ParserParameter parameter, final Field field, final String textContent) { if (field != null) { - if (!(parser instanceof DedicatedObjectParser)) { + if (!(this instanceof DedicatedObjectParser)) { throw new RuntimeException("DedicatedObjectParser required"); } - parser.parseAttributeOrTextContent(parameter.parser.getText(), parameter.destination); + parseAttributeOrTextContent(parameter.parser.getText(), parameter.destination); } else { - parser.parseAttributeOrTextContent(parameter.parser.getText(), textContent); - } - } - - // done - private boolean mapAsClassOrObjectType(final ParserParameter parameter, final String fieldName, - final Type fieldType, final Class fieldClass) - throws IOException, XmlPullParserException { - final boolean isStopped; // store the element as a map - Map mapValue = Data.newMapInstance(fieldClass); - int contextSize = parameter.context.size(); - if (fieldType != null) { - parameter.context.add(fieldType); - } - - Type subValueType = fieldType != null && Map.class.isAssignableFrom(fieldClass) - ? Types.getMapValueParameter(fieldType) : null; - subValueType = Data.resolveWildcardTypeOrTypeVariable(parameter.context, subValueType); - isStopped = parseElementInternal(new ParserParameter(parameter.parser, - parameter.context, - mapValue, // destination; never null - subValueType, - parameter.namespaceDictionary, - parameter.customizeParser)); - if (fieldType != null) { - parameter.context.remove(contextSize); + parseAttributeOrTextContent(parameter.parser.getText(), textContent); } - - mapCollection(fieldClass, fieldName, mapValue); - - // Handle as Array - return isStopped; } - private static boolean mapAsArrayOrCollection(final XmlPullParser parser, final ArrayList context, final Object destination, @@ -605,36 +565,35 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser, return isStopped; } // ----------------------------------------------------------------- - // done. - private boolean mapArrayWithClassType(final ParserParameter parameter, - final Field field, final String fieldName, - final Type fieldType, final Class fieldClass) + + private boolean mapAsClassOrObjectType(final ParserParameter parameter, final String fieldName, + final Type fieldType, final Class fieldClass) throws IOException, XmlPullParserException { - final boolean isStopped; // not an array/iterable or a map, but we do have a field - Object value = Types.newInstance(fieldClass); + final boolean isStopped; // store the element as a map + Map mapValue = Data.newMapInstance(fieldClass); int contextSize = parameter.context.size(); - parameter.context.add(fieldType); + if (fieldType != null) { + parameter.context.add(fieldType); + } + + Type subValueType = fieldType != null && Map.class.isAssignableFrom(fieldClass) + ? Types.getMapValueParameter(fieldType) : null; + subValueType = Data.resolveWildcardTypeOrTypeVariable(parameter.context, subValueType); isStopped = parseElementInternal(new ParserParameter(parameter.parser, parameter.context, - value, // destination; never null. - null, + mapValue, // destination; never null + subValueType, parameter.namespaceDictionary, parameter.customizeParser)); - parameter.context.remove(contextSize); - - - if (field != null) { - mapArrayWithClassTypeSetValue(parameter.destination, value); - } else { - // we never end up here? - mapArrayWithClassTypeSetValue(fieldName, value); + if (fieldType != null) { + parameter.context.remove(contextSize); } - + mapCollection(fieldClass, fieldName, mapValue); + // Handle as Array return isStopped; } - protected static String getFieldName( boolean isAttribute, String alias, String name) { if (!isAttribute && alias.length() == 0) {