throw new ConversionException("Cannot convert type "
+ value.getClass().getName()
+ " to type "
+ type.getName());
}
seenFields.add(new FastField(classDefiningField, attrName));
reflectionProvider.writeField(result, attrName, value, classDefiningField);
}
}
}
Map<String, Collection<? super Object>> implicitCollectionsForCurrentObject = null;
while (reader.hasMoreChildren()) {
reader.moveDown();
final String originalNodeName = reader.getNodeName();
final Class<?> explicitDeclaringClass = readDeclaringClass(reader);
final Class<?> fieldDeclaringClass = explicitDeclaringClass == null ? resultType : explicitDeclaringClass;
final String fieldName = mapper.realMember(fieldDeclaringClass, originalNodeName);
final Mapper.ImplicitCollectionMapping implicitCollectionMapping = mapper
.getImplicitCollectionDefForFieldName(fieldDeclaringClass, fieldName);
final Object value;
String implicitFieldName = null;
Field field = null;
Class<?> type = null;
if (implicitCollectionMapping == null) {
// no item of an implicit collection for this name ... do we have a field?
field = reflectionProvider.getFieldOrNull(fieldDeclaringClass, fieldName);
if (field == null) {
// it is not a field ... do we have a field alias?
final Class<?> itemType = mapper.getItemTypeForItemFieldName(resultType, fieldName);
if (itemType != null) {
final String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper);
if (classAttribute != null) {
type = mapper.realClass(classAttribute);
} else {
type = itemType;
}
} else {
// it is not an alias ... do we have an element of an implicit
// collection based on type only?
try {
type = mapper.realClass(originalNodeName);
implicitFieldName = mapper.getFieldNameForItemTypeAndName(context.getRequiredType(), type,
originalNodeName);
} catch (final CannotResolveClassException e) {
// type stays null ...
}
if (type == null || type != null && implicitFieldName == null) {
// either not a type or element is a type alias, but does not
// belong to an implicit field
handleUnknownField(explicitDeclaringClass, fieldName, resultType, originalNodeName);
// element is unknown in declaring class, ignore it now
type = null;
}
}
if (type == null) {
// no type, no value
value = null;
} else {
if (Map.Entry.class.equals(type)) {
// it is an element of an implicit map with two elements now for
// key and value
reader.moveDown();
final Object key = context.convertAnother(result, HierarchicalStreams.readClassType(reader,
mapper));
reader.moveUp();
reader.moveDown();
final Object v = context.convertAnother(result, HierarchicalStreams.readClassType(reader,
mapper));
reader.moveUp();
value = Collections.singletonMap(key, v).entrySet().iterator().next();
} else {
// recurse info hierarchy
value = context.convertAnother(result, type);
}
}
} else {
boolean fieldAlreadyChecked = false;
// we have a field, but do we have to address a hidden one?
if (explicitDeclaringClass == null) {
while (field != null
&& !(fieldAlreadyChecked = shouldUnmarshalField(field)
&& mapper.shouldSerializeMember(field.getDeclaringClass(), fieldName))) {
field = reflectionProvider.getFieldOrNull(field.getDeclaringClass().getSuperclass(),
fieldName);
}
}
if (field != null
&& (fieldAlreadyChecked || shouldUnmarshalField(field)
&& mapper.shouldSerializeMember(field.getDeclaringClass(), fieldName))) {
final String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper);
if (classAttribute != null) {
type = mapper.realClass(classAttribute);
} else {
type = mapper.defaultImplementationOf(field.getType());
}
// TODO the reflection provider should already return the proper field
value = unmarshallField(context, result, type, field);
final Class<?> definedType = field.getType();
if (!definedType.isPrimitive()) {
type = definedType;
}
} else {
value = null;
}
}
} else {
// we have an implicit collection with defined names
implicitFieldName = implicitCollectionMapping.getFieldName();
type = implicitCollectionMapping.getItemType();
if (type == null) {
final String classAttribute = HierarchicalStreams.readClassAttribute(reader, mapper);
type = mapper.realClass(classAttribute != null ? classAttribute : originalNodeName);
}
value = context.convertAnother(result, type);
}
if (value != null && !type.isAssignableFrom(value.getClass())) {
throw new ConversionException("Cannot convert type "
+ value.getClass().getName()
+ " to type "
+ type.getName());
}
if (field != null) {
reflectionProvider.writeField(result, fieldName, value, field.getDeclaringClass());
seenFields.add(new FastField(field.getDeclaringClass(), fieldName));
} else if (type != null) {
if (implicitFieldName == null) {
// look for implicit field
implicitFieldName = mapper.getFieldNameForItemTypeAndName(context.getRequiredType(), value != null
? value.getClass()