Skip to content

Commit

Permalink
Move destination Map to Parser from Main Loop (googleapis#490)
Browse files Browse the repository at this point in the history
  • Loading branch information
geri-m committed Oct 27, 2018
1 parent 34ec724 commit d3d0b73
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ public class MapParser extends Xml<Map<String,Object>> {

protected Map<String, Object> destinationMap;

public MapParser(final ParserParameter parameter, final Map<String, Object> destinationMap, final ClassInfo classInfo) {
@SuppressWarnings("unchecked")
public MapParser(final ParserParameter parameter, final ClassInfo classInfo) {
super(parameter, classInfo);
this.destinationMap = destinationMap;
this.destinationMap = (Map) parameter.destination;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,31 +233,11 @@ private static boolean parseElementInternal(final ParserParameter parameter)
// TODO(yanivi): method is too long; needs to be broken down into smaller methods and comment
// better

// if the destination is GenericXML and the destination is a Map, create a destination Map.
@SuppressWarnings("unchecked")
Map<String, Object> destinationMap =
!(parameter.destination instanceof GenericXml) && parameter.destination instanceof Map<?, ?> ? Map.class.cast(parameter.destination) : null;

// if there is a class, we want to put the data into, create the class Info for this
ClassInfo classInfo =
!(parameter.destination instanceof GenericXml) && parameter.destination instanceof Map<?, ?> || parameter.destination == null ? null : ClassInfo.of(parameter.destination.getClass());


if(classInfo != null){
if(destinationMap != null)
throw new RuntimeException("destinationMap XML Must be null!");
}



if(destinationMap != null){
if(classInfo != null)
throw new RuntimeException("classInfo Musst be null!");

}



// if we are the very beginning of the document, get the next element/event
if (parameter.parser.getEventType() == XmlPullParser.START_DOCUMENT) {
parameter.parser.next();
Expand All @@ -269,7 +249,7 @@ private static boolean parseElementInternal(final ParserParameter parameter)
final Xml parser;
// if we have a dedicated destination
if (!(parameter.destination instanceof GenericXml) && parameter.destination instanceof Map<?, ?>) {
parser = new MapParser(parameter, destinationMap, classInfo);
parser = new MapParser(parameter, classInfo);
} else if (parameter.destination instanceof GenericXml) {
// if we have a generic XML, set the namespace
parser = new GenericXmlParser(parameter, classInfo);
Expand Down Expand Up @@ -303,16 +283,13 @@ private static boolean parseElementInternal(final ParserParameter parameter)
case XmlPullParser.TEXT:
// parse text content
if (parameter.destination != null) {



field = classInfo == null ? null : classInfo.getField(TEXT_CONTENT);

if ((parser instanceof DedicatedObjectParser)) {
parser.setDestination(field);
}

sanityCheck(parser, destinationMap, field);
sanityCheck(parser, field);
parameter.valueType = field == null ? parameter.valueType : field.getGenericType();

mapTextToElementValue(parameter, parser, field, TEXT_CONTENT);
Expand Down Expand Up @@ -341,7 +318,7 @@ private static boolean parseElementInternal(final ParserParameter parameter)
// fetch the field from the classInfo
field = classInfo == null ? null : classInfo.getField(fieldName);

if((parser instanceof DedicatedObjectParser)){
if ((parser instanceof DedicatedObjectParser)) {
parser.setDestination(field);
}

Expand All @@ -356,7 +333,6 @@ private static boolean parseElementInternal(final ParserParameter parameter)
fieldClass = Types.getRawClass((ParameterizedType) fieldType);
}


boolean isArray = Types.isArray(fieldType);
// text content
boolean ignore = field == null && (parser instanceof DedicatedObjectParser);
Expand All @@ -381,9 +357,9 @@ private static boolean parseElementInternal(final ParserParameter parameter)
case XmlPullParser.TEXT:
if (!ignore && level == 1) {
parameter.valueType = field == null ? parameter.valueType : field.getGenericType();
sanityCheck(parser, destinationMap, field);
sanityCheck(parser, field);

if(field == null){
if (field == null) {
throw new RuntimeException("Field can not be null here");
}

Expand All @@ -406,6 +382,7 @@ private static boolean parseElementInternal(final ParserParameter parameter)
}

// we need a dedicate class for a dedicate Object Parser
// THis is ALWAYS false => DedicatedObjectParser always ha a fieldClass
if (fieldClass == null && (parser instanceof DedicatedObjectParser)) {
throw new RuntimeException("fieldClass 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
Expand All @@ -419,25 +396,26 @@ private static boolean parseElementInternal(final ParserParameter parameter)
// 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){
if (parser instanceof MapParser) {
throw new RuntimeException("MapParser");
}


// Destination Map is always NULL!
isStopped = mapAsArrayOrCollection(parameter.parser, parameter.context, parameter.destination, parameter.namespaceDictionary,
parameter.customizeParser, destinationMap, field, arrayValueMap,
parameter.customizeParser, field, arrayValueMap,
fieldName, fieldType, isArray, parser);
} else {

if (field == null) {
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){
if (parser instanceof MapParser) {
throw new RuntimeException("MapParser");
}

if(parser instanceof GenericXmlParser){
if (parser instanceof GenericXmlParser) {
throw new RuntimeException("GenericXmlParser");
}

Expand All @@ -448,7 +426,7 @@ private static boolean parseElementInternal(final ParserParameter parameter)
}

// Never reached while Testing
if(parameter.parser.getEventType() == XmlPullParser.END_DOCUMENT){
if (parameter.parser.getEventType() == XmlPullParser.END_DOCUMENT) {
isStopped = true;
}

Expand All @@ -474,32 +452,18 @@ private static boolean parseElementInternal(final ParserParameter parameter)
return isStopped;
}

private static void sanityCheck(final Xml parser, final Map<String, Object> destinationMap, final Field field) {
private static void sanityCheck(final Xml parser, final Field field) {
if (field != null) {

if (!(parser instanceof DedicatedObjectParser))
if (!(parser instanceof DedicatedObjectParser)) {
throw new RuntimeException("Incorrect Parser");


if (destinationMap != null)
throw new RuntimeException("destinationMap XML Must be null!");
}


if (destinationMap != null) {

if (!(parser instanceof MapParser))
throw new RuntimeException("Incorrect Parser");

if (field != null)
throw new RuntimeException("field Must be null!");
}

}
}

private static void mapTextToElementValue(final ParserParameter parameter, final Xml parser, final Field field, final String textContent) {
if (field != null) {
if(!(parser instanceof DedicatedObjectParser)){
if (!(parser instanceof DedicatedObjectParser)) {
throw new RuntimeException("DedicatedObjectParser required");
}
parser.parseAttributeOrTextContent(parameter.parser.getText(), parameter.destination);
Expand Down Expand Up @@ -544,7 +508,6 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser,
final XmlNamespaceDictionary namespaceDictionary,
final CustomizeParser customizeParser,

final Map<String, Object> destinationMap,
final Field field,
final ArrayValueMap arrayValueMap,
final String fieldName,
Expand All @@ -562,6 +525,7 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser,
Class<?> subFieldClass =
subFieldType instanceof Class<?> ? (Class<?>) subFieldType : null;
if (subFieldType instanceof ParameterizedType) {
// how do we get there?
subFieldClass = Types.getRawClass((ParameterizedType) subFieldType);
}
boolean isSubEnum = subFieldClass != null && subFieldClass.isEnum();
Expand Down Expand Up @@ -608,48 +572,39 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser,
if (isArray) {
// array field: add new element to array value map
if (field == null) {
// can we end up here?
arrayValueMap.put(fieldName, rawArrayComponentType, elementValue);
} else {
arrayValueMap.put(field, rawArrayComponentType, elementValue);
}
} else {
mapToCollection(destination, destinationMap, field, fieldName, fieldType,

mapToCollection(destination, field, fieldName, fieldType,
fieldInfo, elementValue, parserObj);
}
return isStopped;
}

private static void mapToCollection(final Object destination,
final Map<String, Object> destinationMap, final Field field,
final Field field,
final String fieldName, final Type fieldType,
final FieldInfo fieldInfo, final Object elementValue, final Xml parser) {
// collection: add new element to collection NOT YET Covered!
@SuppressWarnings("unchecked")
Collection<Object> collectionValue;

if (field == null) {
collectionValue = (Collection<Object>)destinationMap.get(fieldName);
} else {
collectionValue =(Collection<Object>)fieldInfo.getValue(destination);
}
Collection<Object> collectionValue = (Collection<Object>)fieldInfo.getValue(destination);

if (collectionValue == null) {
collectionValue = Data.newCollectionInstance(fieldType);

if(destinationMap != null){
throw new RuntimeException(" This should not happen, as Array != destinationMap. Remove if problem");
}

// super hacky for the moment.
if (field != null && parser instanceof DedicatedObjectParser) {
parser.setValue(destination, collectionValue);
} else if (parser instanceof GenericXmlParser) {
parser.setValue(fieldName, collectionValue);
} else {
throw new RuntimeException("We must not endup here");
throw new RuntimeException("We must not end up here");
// parser.setValue(fieldName, collectionValue);
}

}
collectionValue.add(elementValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.junit.Ignore;
import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
Expand Down Expand Up @@ -38,7 +40,6 @@ public static class ListWithClassTypeGeneric extends GenericXml {
public List<XmlTest.AnyType> rep;
}


public static class MultiGenericWithClassType {
@Key
public GenericXml[] rep;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.junit.Ignore;
import org.junit.Test;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
Expand Down Expand Up @@ -225,6 +227,34 @@ public void testParseListTypeString() throws Exception {
}



private static final String MULTIPLE_STRING_ELEMENT_IN_COLLECTION =
"<?xml version=\"1.0\"?><any xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<coll><rep>rep1</rep><rep>rep2</rep></coll></any>";

public static class AnyTypeWithCollectionString {
@Key
public CollectionTypeString coll;
}

@Test
public void testParseAnyTypeWithACollectionString() throws Exception {
AnyTypeWithCollectionString xml = new AnyTypeWithCollectionString();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(MULTIPLE_STRING_ELEMENT_IN_COLLECTION));
XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary();
Xml.parseElement(parser, xml, namespaceDictionary, null);
// check type
assertNotNull(xml.coll);
// serialize
XmlSerializer serializer = Xml.createSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.setOutput(out, "UTF-8");
namespaceDictionary.serialize(serializer, "any", xml);
assertEquals(MULTIPLE_STRING_ELEMENT_IN_COLLECTION, out.toString());
}


private static final String MULTIPLE_INTEGER_ELEMENT =
"<?xml version=\"1.0\"?><any xmlns=\"http://www.w3.org/2005/Atom\">"
+ "<rep>1</rep><rep>2</rep></any>";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public void testParseToAnyTypeMissingField() throws Exception {
*/
@SuppressWarnings("cast")
@Test
public void testparseToAnyTypeAdditionalField() throws Exception {
public void testParseToAnyTypeAdditionalField() throws Exception {
AnyTypeAdditionalField xml = new AnyTypeAdditionalField();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(ANY_TYPE_XML));
Expand Down

0 comments on commit d3d0b73

Please sign in to comment.