Skip to content

Commit

Permalink
abstract mapAsClassOrObjectType (googleapis#490)
Browse files Browse the repository at this point in the history
  • Loading branch information
geri-m committed Oct 27, 2018
1 parent d3d0b73 commit 2a711f2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 262 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ public class MapParser extends Xml<Map<String,Object>> {
protected Map<String, Object> destinationMap;

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ protected Xml(final ParserParameter parameter, final ClassInfo classInfo) {
this.classInfo = classInfo;
}

protected Xml(final ParserParameter parameter) {
this.parameter = parameter;
this.classInfo = null;
}

public abstract void parseAttributesFromElement();

public abstract void parseAttributeOrTextContent(String stringValue, Object name);
Expand Down Expand Up @@ -248,9 +253,12 @@ 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, classInfo);
} else if (parameter.destination instanceof GenericXml) {
if (parameter.destination != null && !(parameter.destination instanceof GenericXml) && parameter.destination instanceof Map<?, ?>) {
if (classInfo != null) {
throw new RuntimeException("We must not have a classInfo here");
}
parser = new MapParser(parameter);
} else if (parameter.destination != null && parameter.destination instanceof GenericXml) {
// if we have a generic XML, set the namespace
parser = new GenericXmlParser(parameter, classInfo);
} else {
Expand Down Expand Up @@ -389,7 +397,7 @@ private static boolean parseElementInternal(final ParserParameter parameter)
}

// field could be null here.
isStopped = mapAsClassOrObjectType(parameter, fieldName, fieldType, fieldClass, parser);
isStopped = parser.mapAsClassOrObjectType(parameter, fieldName, fieldType, fieldClass);
} else if (isArray || Types.isAssignableToOrFrom(fieldClass, Collection.class)) {
if (field == null) {
throw new RuntimeException("Field can not be null here. ");
Expand Down Expand Up @@ -453,11 +461,8 @@ private static boolean parseElementInternal(final ParserParameter parameter)
}

private static void sanityCheck(final Xml parser, final Field field) {
if (field != null) {
if (!(parser instanceof DedicatedObjectParser)) {
if (field != null && !(parser instanceof DedicatedObjectParser)) {
throw new RuntimeException("Incorrect Parser");
}

}
}

Expand All @@ -472,16 +477,17 @@ private static void mapTextToElementValue(final ParserParameter parameter, final
}
}


private static boolean mapAsClassOrObjectType(final ParserParameter parameter, final String fieldName,
final Type fieldType, final Class<?> fieldClass, final Xml parserObj)
// 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<String, Object> 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);
Expand All @@ -495,8 +501,7 @@ private static boolean mapAsClassOrObjectType(final ParserParameter parameter, f
parameter.context.remove(contextSize);
}


parserObj.mapCollection(fieldClass, fieldName, mapValue);
mapCollection(fieldClass, fieldName, mapValue);

// Handle as Array
return isStopped;
Expand Down Expand Up @@ -569,6 +574,8 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser,
customizeParser));
context.remove(contextSize);
}

// this is the switch between an Array an a Parameter Tye (Collection<>, List<>)
if (isArray) {
// array field: add new element to array value map
if (field == null) {
Expand All @@ -578,37 +585,26 @@ private static boolean mapAsArrayOrCollection(final XmlPullParser parser,
arrayValueMap.put(field, rawArrayComponentType, elementValue);
}
} else {

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

private static void mapToCollection(final Object destination,
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 = (Collection<Object>)fieldInfo.getValue(destination);

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

// 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 end up here");
// parser.setValue(fieldName, collectionValue);
@SuppressWarnings("unchecked")
Collection<Object> collectionValue = (Collection<Object>)fieldInfo.getValue(destination);
if (collectionValue == null) {
collectionValue = Data.newCollectionInstance(fieldType);

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

// -----------------------------------------------------------------
// done.
private boolean mapArrayWithClassType(final ParserParameter parameter,
final Field field, final String fieldName,
Expand Down Expand Up @@ -637,7 +633,7 @@ private boolean mapArrayWithClassType(final ParserParameter parameter,
return isStopped;
}

// -----------------------------------------------------------------


protected static String getFieldName(
boolean isAttribute, String alias, String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ public static class CollectionWithClassTypeGeneric extends GenericXml {
public Collection<XmlTest.AnyType> rep;
}

public static class ListWithClassTypeGeneric extends GenericXml {
@Key
public List<XmlTest.AnyType> rep;
}

public static class MultiGenericWithClassType {
@Key
public GenericXml[] rep;
Expand Down Expand Up @@ -116,38 +111,6 @@ public void testParseCollectionWithClassType() throws Exception {
assertEquals(MULTI_TYPE_WITH_CLASS_TYPE, out.toString());
}


@Test
public void testParseListWithClassType() throws Exception {
ListWithClassTypeGeneric xml = new ListWithClassTypeGeneric();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(MULTI_TYPE_WITH_CLASS_TYPE));
XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary();
Xml.parseElement(parser, xml, namespaceDictionary, null);
// check type
assertTrue(xml.rep instanceof List);
List<XmlTest.AnyType> rep = xml.rep;
assertNotNull(rep);
assertEquals(3, rep.size());
ArrayList<ArrayMap<String, String>> elem0 = (ArrayList<ArrayMap<String, String>>) rep.get(0).elem;
assertEquals(1, elem0.size());
assertEquals("content1", elem0.get(0).get("text()"));
ArrayList<ArrayMap<String, String>> elem1 = (ArrayList<ArrayMap<String, String>>) rep.get(1).elem;
assertEquals(1, elem1.size());
assertEquals("content2", elem1.get(0).get("text()"));
ArrayList<ArrayMap<String, String>> elem2 = (ArrayList<ArrayMap<String, String>>) rep.get(2).elem;
assertEquals(1, elem2.size());
assertEquals("content3", elem2.get(0).get("text()"));

// serialize
XmlSerializer serializer = Xml.createSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.setOutput(out, "UTF-8");
namespaceDictionary.serialize(serializer, "any", xml);
assertEquals(MULTI_TYPE_WITH_CLASS_TYPE, out.toString());
}


@Test
public void testParseMultiGenericWithClassType() throws Exception {
MultiGenericWithClassType xml = new MultiGenericWithClassType();
Expand Down Expand Up @@ -217,11 +180,6 @@ public static class ArrayTypeStringGeneric extends GenericXml{
public String[] rep;
}

public static class ListTypeStringGeneric extends GenericXml {
@Key
public List<String> rep;
}

/**
* The Purpose of this test is to map a given list of elements (Strings) to a {@link Collection}
* of Strings. This test uses the {@link DedicatedObjectParser} only, as all field/types are
Expand Down Expand Up @@ -269,31 +227,6 @@ public void testParseArrayTypeString() throws Exception {
assertEquals(MULTIPLE_STRING_ELEMENT, out.toString());
}

/**
* The Purpose of this test is to map a given list of elements (Strings) to a {@link List}
* of Strings. This test uses the {@link DedicatedObjectParser} only, as all field/types are
* specified.
*/
@Test
public void testParseListTypeString() throws Exception {
ListTypeStringGeneric xml = new ListTypeStringGeneric();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(MULTIPLE_STRING_ELEMENT));
XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary();
Xml.parseElement(parser, xml, namespaceDictionary, null);
// check type
assertEquals(2, xml.rep.size());
assertEquals("rep1", xml.rep.get(0));
assertEquals("rep2", xml.rep.get(1));
// serialize
XmlSerializer serializer = Xml.createSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.setOutput(out, "UTF-8");
namespaceDictionary.serialize(serializer, "any", xml);
assertEquals(MULTIPLE_STRING_ELEMENT, 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 All @@ -313,11 +246,6 @@ public static class ArrayTypeIntGeneric extends GenericXml {
public int[] rep;
}

public static class ListTypeIntegerGeneric extends GenericXml {
@Key
public List<Integer> rep;
}

/**
* The Purpose of this test is to map a given list of elements (Strings) to a {@link Collection}
* of Strings. This test uses the {@link DedicatedObjectParser} only, as all field/types are
Expand Down Expand Up @@ -365,31 +293,6 @@ public void testParseArrayTypeInteger() throws Exception {
assertEquals(MULTIPLE_INTEGER_ELEMENT, out.toString());
}

/**
* The Purpose of this test is to map a given list of elements (Strings) to a {@link List}
* of Strings. This test uses the {@link DedicatedObjectParser} only, as all field/types are
* specified.
*/
@Test
public void testParseListTypeInteger() throws Exception {
ListTypeIntegerGeneric xml = new ListTypeIntegerGeneric();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(MULTIPLE_INTEGER_ELEMENT));
XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary();
Xml.parseElement(parser, xml, namespaceDictionary, null);
// check type
assertEquals(2, xml.rep.size());
assertEquals(1, xml.rep.get(0).intValue());
assertEquals(2, xml.rep.get(1).intValue());
// serialize
XmlSerializer serializer = Xml.createSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.setOutput(out, "UTF-8");
namespaceDictionary.serialize(serializer, "any", xml);
assertEquals(MULTIPLE_INTEGER_ELEMENT, out.toString());
}


/**
* The Purpose of this test is to map a given list of elements (int) to a {@link List}
* of Strings. This test uses the {@link DedicatedObjectParser} only, as all field/types are
Expand Down Expand Up @@ -470,11 +373,6 @@ public static class ArrayTypeEnumGeneric extends GenericXml{
public XmlEnumTest.AnyEnum[] rep;
}

public static class ListTypeEnumGeneric extends GenericXml {
@Key
public List<XmlEnumTest.AnyEnum> rep;
}


@Test
public void testParseCollectionTypeWithEnum() throws Exception {
Expand Down Expand Up @@ -514,24 +412,4 @@ public void testParseArrayTypeWithEnum() throws Exception {
assertEquals(MULTIPLE_ENUM_ELEMENT, out.toString());
}


@Test
public void testParseListTypeWithEnum() throws Exception {
ListTypeEnumGeneric xml = new ListTypeEnumGeneric();
XmlPullParser parser = Xml.createParser();
parser.setInput(new StringReader(MULTIPLE_ENUM_ELEMENT));
XmlNamespaceDictionary namespaceDictionary = new XmlNamespaceDictionary();
Xml.parseElement(parser, xml, namespaceDictionary, null);
// check type
assertEquals(2, xml.rep.size());
assertEquals(XmlEnumTest.AnyEnum.ENUM_1, xml.rep.get(0));
assertEquals(XmlEnumTest.AnyEnum.ENUM_2, xml.rep.get(1));
// serialize
XmlSerializer serializer = Xml.createSerializer();
ByteArrayOutputStream out = new ByteArrayOutputStream();
serializer.setOutput(out, "UTF-8");
namespaceDictionary.serialize(serializer, "any", xml);
assertEquals(MULTIPLE_ENUM_ELEMENT, out.toString());
}

}
Loading

0 comments on commit 2a711f2

Please sign in to comment.