ValueCompositeType actualValueType = (ValueCompositeType) valueType;
String actualType = jsonObject.optString( "_type" );
if( !actualType.equals( "" ) )
{
ValueDescriptor descriptor = module.valueDescriptor( actualType );
if( descriptor == null )
{
throw new IllegalArgumentException( "Could not find any value of type '" + actualType + "' in module" + module );
}
actualValueType = descriptor.valueType();
}
final Map<QualifiedName, Object> values = new HashMap<QualifiedName, Object>();
for( PropertyDescriptor persistentProperty : actualValueType.properties() )
{
Object valueJson = null;
try
{
valueJson = jsonObject.opt( persistentProperty.qualifiedName().name() );
Object value = null;
if( valueJson != null && !valueJson.equals( JSONObject.NULL ) )
{
value = deserialize( valueJson, persistentProperty.valueType() );
if (persistentProperty.isImmutable())
{
if (value instanceof Set)
{
value = Collections.unmodifiableSet( (Set<? extends Object>) value);
} else if (value instanceof List)
{
value = Collections.unmodifiableList( (List<? extends Object>) value);
} else if (value instanceof Map)
{
value = Collections.unmodifiableMap( (Map<? extends Object, ? extends Object>) value);
}
}
}
values.put( persistentProperty.qualifiedName(), value );
} catch( JSONException e )
{
// Not found in JSON or wrong format - try defaulting it
try
{
Object defaultValue = DefaultValues.getDefaultValue( persistentProperty.valueType().type() );
values.put( persistentProperty.qualifiedName(), defaultValue );
} catch( RuntimeException e1 )
{
// Didn't work, throw the exception
throw e;
}
}
}
for( AssociationDescriptor associationDescriptor : actualValueType.associations() )
{
Object valueJson = jsonObject.optString( associationDescriptor.qualifiedName().name() );
if (valueJson != null)
values.put( associationDescriptor.qualifiedName(), EntityReference.parseEntityReference( valueJson.toString() ) );
}
for( AssociationDescriptor associationDescriptor : actualValueType.manyAssociations() )
{
JSONArray jsonArray = jsonObject.optJSONArray( associationDescriptor.qualifiedName().name() );
if (jsonArray != null)
{
List<EntityReference> refs = new ArrayList<EntityReference>();
for (int i = 0; i < jsonArray.length(); i++)
{
refs.add( EntityReference.parseEntityReference( jsonArray.getString( i ) ) );
}
}
}
ValueBuilder valueBuilder = module
.newValueBuilderWithState( actualValueType.type(), new Function<PropertyDescriptor, Object>()
{
@Override
public Object map( PropertyDescriptor descriptor )
{
return values.get( descriptor.qualifiedName() );
}
},new Function<AssociationDescriptor, EntityReference>()
{
@Override
public EntityReference map( AssociationDescriptor associationDescriptor )
{
Object ref = values.get( associationDescriptor.qualifiedName() );
if (ref == null)
return null;
else
return (EntityReference) ref;
}
},new Function<AssociationDescriptor, Iterable<EntityReference>>()
{
@Override
public Iterable<EntityReference> map( AssociationDescriptor associationDescriptor )
{
Object ref = values.get( associationDescriptor.qualifiedName() );
if (ref == null)
return Iterables.empty();
else
return (Iterable<EntityReference>) ref;
}
});
return valueBuilder.newInstance();
} else
{
try
{
if( json instanceof JSONObject )
{
// ValueComposite deserialization
JSONObject jsonObject = (JSONObject) json;
String type = jsonObject.getString( "_type" );
ValueDescriptor valueDescriptor = module.valueDescriptor( type );
return deserialize( json, valueDescriptor.valueType() );
} else
{
String serializedString = (String) json;
byte[] bytes = serializedString.getBytes( "UTF-8" );
bytes = Base64Encoder.decode( bytes );