package org.javers.core.json.typeadapter.commit; import com.google.gson.*; import org.javers.common.collections.Lists; import org.javers.core.json.JsonTypeAdapter; import org.javers.core.metamodel.object.*; import org.javers.core.metamodel.type.EntityType; import org.javers.core.metamodel.type.TypeMapper; import org.slf4j.Logger; import java.util.List; import static org.slf4j.LoggerFactory.getLogger; /** * @author bartosz walacik */ class GlobalIdTypeAdapter implements JsonTypeAdapter<GlobalId> { private static final Logger logger = getLogger(GlobalIdTypeAdapter.class); static final String ENTITY_FIELD = "entity"; static final String CDO_ID_FIELD = "cdoId"; static final String OWNER_ID_FIELD = "ownerId"; static final String VALUE_OBJECT_FIELD = "valueObject"; static final String FRAGMENT_FIELD = "fragment"; private final GlobalIdFactory globalIdFactory; private final TypeMapper typeMapper; public GlobalIdTypeAdapter(GlobalIdFactory globalIdFactory, TypeMapper typeMapper) { this.globalIdFactory = globalIdFactory; this.typeMapper = typeMapper; } @Override public GlobalId fromJson(JsonElement json, JsonDeserializationContext context) { JsonObject jsonObject = (JsonObject) json; logger.debug("deserializing "+json); if (jsonObject.get(ENTITY_FIELD) != null) { return parseInstanceId(jsonObject, context); } else if (jsonObject.get(OWNER_ID_FIELD) != null) { return parseValueObjectId(jsonObject, context); } else { return parseUnboundedValueObject(jsonObject); } } private UnboundedValueObjectId parseUnboundedValueObject(JsonObject jsonObject){ String typeName = jsonObject.get(VALUE_OBJECT_FIELD).getAsString(); return new UnboundedValueObjectId(typeName); } private ValueObjectId parseValueObjectId(JsonObject jsonObject, JsonDeserializationContext context) { String typeName = jsonObject.get(VALUE_OBJECT_FIELD).getAsString(); String fragment = jsonObject.get(FRAGMENT_FIELD).getAsString(); GlobalId ownerId = context.deserialize(jsonObject.get(OWNER_ID_FIELD), GlobalId.class); return new ValueObjectId(typeName, ownerId, fragment); } private InstanceId parseInstanceId(JsonObject jsonObject, JsonDeserializationContext context) { EntityType entity = parseEntity(jsonObject); JsonElement cdoIdElement = jsonObject.get(CDO_ID_FIELD); Object cdoId = context.deserialize(cdoIdElement, entity.getIdProperty().getGenericType()); return globalIdFactory.createInstanceId(cdoId, entity); } @Override public JsonElement toJson(GlobalId globalId, JsonSerializationContext context) { if (globalId == null) { return JsonNull.INSTANCE; } logger.debug("serializing "+globalId.getClass().getSimpleName()+":"+globalId); JsonObject jsonObject = new JsonObject(); //managedClass if (globalId instanceof InstanceId) { jsonObject.addProperty(ENTITY_FIELD, globalId.getTypeName()); jsonObject.add(CDO_ID_FIELD, context.serialize(((InstanceId)globalId).getCdoId())); } else { jsonObject.addProperty(VALUE_OBJECT_FIELD, globalId.getTypeName()); } //owningId & fragment if (globalId instanceof ValueObjectId) { ValueObjectId valueObjectId = (ValueObjectId) globalId; jsonObject.add(OWNER_ID_FIELD, context.serialize(valueObjectId.getOwnerId())); jsonObject.addProperty(FRAGMENT_FIELD, valueObjectId.getFragment()); } return jsonObject; } @Override public List<Class> getValueTypes() { return (List) Lists.immutableListOf(GlobalId.class, InstanceId.class, UnboundedValueObjectId.class, ValueObjectId.class); } private EntityType parseEntity(JsonObject object){ String entityName = object.get(ENTITY_FIELD).getAsString(); return typeMapper.getJaversManagedType(entityName, EntityType.class); } }