@Override
public Object demarshall(EJValue o, MarshallingSession ctx) {
try {
if (o.isObject() != null) {
EJObject oMap = o.isObject();
Object newInstance;
if (oMap.containsKey(SerializationParts.OBJECT_ID)) {
if (oMap.containsKey(SerializationParts.NUMERIC_VALUE)) {
return NumbersUtils.getNumber(oMap.get(SerializationParts.ENCODED_TYPE).isString().stringValue(),
oMap.get(SerializationParts.NUMERIC_VALUE));
}
if (oMap.containsKey(SerializationParts.OBJECT_ID)) {
String hash = oMap.get(SerializationParts.OBJECT_ID).isString().stringValue();
if (ctx.hasObjectHash(hash)) {
newInstance = ctx.getObject(Object.class, hash);
/**
* If this only contains 2 fields, it is only a graph reference.
*/
if (oMap.size() == 2) {
return newInstance;
}
}
else {
if (oMap.containsKey(SerializationParts.INSTANTIATE_ONLY)) {
newInstance = getTypeHandled().newInstance();
ctx.recordObjectHash(hash, newInstance);
return newInstance;
}
InstantiationMapping cMapping = definition.getInstantiationMapping();
Object[] parms = new Object[cMapping.getMappings().length];
Class[] targetTypes = cMapping.getSignature();
int i = 0;
for (Mapping mapping : cMapping.getMappings()) {
parms[i] = DataConversion.convert(
ctx.demarshall(mapping.getType().asClass(), oMap.get(mapping.getKey())), targetTypes[i++]);
}
if (cMapping instanceof ConstructorMapping) {
newInstance = ((ConstructorMapping) cMapping).getMember().asConstructor().newInstance(parms);
}
else {
newInstance = ((FactoryMapping) cMapping).getMember().asMethod().invoke(null, parms);
}
ctx.recordObjectHash(hash, newInstance);
}
for (MemberMapping mapping : definition.getWritableMemberMappings()) {
if (mapping.getBindingMember() instanceof MetaField) {
MetaField f = (MetaField) mapping.getBindingMember();
setProperty(newInstance, f.asField(),
ctx.demarshall(mapping.getType().asClass(), oMap.get(mapping.getKey())));
}
else {
Method m = ((MetaMethod) mapping.getBindingMember()).asMethod();
m.invoke(newInstance, DataConversion.convert(
ctx.demarshall(mapping.getType().asClass(), oMap.get(mapping.getKey())),
m.getParameterTypes()[0]));
}
}
}
else {
throw new RuntimeException("unknown type to demarshall");
}
return newInstance;
}
else if (oMap.containsKey(SerializationParts.ENUM_STRING_VALUE)) {
return Enum.valueOf(getClassReference(oMap), oMap.get(SerializationParts.ENUM_STRING_VALUE).isString().stringValue());
}
else {
throw new RuntimeException("bad payload");
}
}