Class<?> targetClass = targetType.asClass();
// get the descriptors
LinkedList<ObjectDescriptor> descriptors = registry.getDescriptorsForType(targetClass);
if (descriptors.isEmpty()) {
throw new MjormException("Unable to find ObjectDescriptor for "+targetClass);
}
// get descriptor
ObjectDescriptor descriptor = descriptors.get(descriptors.size()-1);
// get the discriminator name
String discriminatorName = descriptor.getDiscriminatorName();
Object discriminator = null;
if (discriminatorName!=null && discriminatorName.trim().length()>0) {
discriminator = DBObjectUtil.getNestedProperty(source, discriminatorName);
}
// if we have a discriminiator - figure out which
// subclass to use
if (discriminator!=null) {
ObjectDescriptor subClass = descriptor.getSubClassObjectDescriptor(discriminator);
if (subClass==null && Modifier.isAbstract(descriptor.getType().getModifiers())) {
throw new MjormException(
"Sublcass for discriminiator value "+discriminator
+" was not found on abstract ObjectDescriptor for "
+ descriptor.getType().getName());
} else if (subClass!=null) {
descriptor = subClass;
descriptors.addFirst(subClass);
}
}
// create the return object
Object ret;
try {
ret = ReflectionUtil.instantiate(descriptor.getType());
} catch (Exception e) {
throw new MjormException(
"Error creating class: "+targetClass, e);
}
// loop through each descriptor
for (ObjectDescriptor desc : descriptors) {
// loop through each property
for (PropertyDescriptor prop : desc.getProperties()) {
try {
// the field name
String fieldName = prop.isIdentifier() ? "_id" : prop.getFieldName();
// get the value
Object value = source.get(fieldName);
// convert
if (value!=null) {
// setup hints
TypeConversionHints nextHints = new TypeConversionHints();
if (prop.getConversionHints()!=null && !prop.getConversionHints().isEmpty()) {
for (Entry<String, Object> entry : prop.getConversionHints().entrySet()) {
nextHints.set(entry.getKey(), entry.getValue());
}
}
// add generic type parameter hints
Type[] genericParameterTypes = prop.getGenericParameterTypes();
if (genericParameterTypes!=null && genericParameterTypes.length>0) {
nextHints.set(TypeConversionHints.HINT_GENERIC_TYPE_PARAMETERS, genericParameterTypes);
}
// convert
value = context.convert(value, prop.getType(), nextHints);
}
// set
prop.set(ret, value);
} catch (Exception e) {
throw new MjormException(
"Error mapping property "+prop.getName()
+" of class "+descriptor.getType(), e);
}
}