All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javers.core.json.typeadapter.change.ChangeTypeAdapter Maven / Gradle / Ivy

package org.javers.core.json.typeadapter.change;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import org.javers.common.exception.JaversException;
import org.javers.common.exception.JaversExceptionCode;
import org.javers.core.commit.CommitMetadata;
import org.javers.core.diff.Change;
import org.javers.core.diff.changetype.*;
import org.javers.core.diff.changetype.container.ArrayChange;
import org.javers.core.diff.changetype.container.ListChange;
import org.javers.core.diff.changetype.container.SetChange;
import org.javers.core.diff.changetype.map.MapChange;
import org.javers.core.json.JsonTypeAdapter;
import org.javers.core.json.JsonTypeAdapterTemplate;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.type.JaversProperty;
import org.javers.core.metamodel.type.ManagedType;
import org.javers.core.metamodel.type.TypeMapper;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

class ChangeTypeAdapter extends JsonTypeAdapterTemplate {

    private static final String CHANGE_TYPE_FIELD = "changeType";
    private static final String AFFECTED_CDO_ID_FIELD = "globalId";
    private static final String PROPERTY_FIELD = "property";
    private static final String COMMIT_METADATA = "commitMetadata";
    private static final String PROPERTY_CHANGE_TYPE = "propertyChangeType";

    private final Map> changeTypeMap;
    protected final TypeMapper typeMapper;

    public ChangeTypeAdapter(TypeMapper typeMapper) {
        this.changeTypeMap = new HashMap<>();
        this.typeMapper = typeMapper;
        initEntry(ValueChange.class);
        initEntry(InitialValueChange.class);
        initEntry(TerminalValueChange.class);
        initEntry(ReferenceChange.class);
        initEntry(NewObject.class);
        initEntry(ObjectRemoved.class);
        initEntry(MapChange.class);
        initEntry(ListChange.class);
        initEntry(ArrayChange.class);
        initEntry(SetChange.class);
    }

    protected CommitMetadata deserializeCommitMetadata(JsonObject jsonObject, JsonDeserializationContext context) {
        return context.deserialize(jsonObject.get(COMMIT_METADATA), CommitMetadata.class);
    }

    protected ManagedType getManagedType(PropertyChangeMetadata stub) {
        return typeMapper.getJaversManagedType(stub.getAffectedCdoId());
    }

    protected JaversProperty getJaversProperty(PropertyChangeMetadata stub) {
        return getManagedType(stub).getProperty(stub.getPropertyName());
    }

    @Override
    public T fromJson(JsonElement json, JsonDeserializationContext context) {
        Class changeType = decodeChangeType((JsonObject) json);
        return context.deserialize(json, changeType);
    }

    @Override
    public JsonElement toJson(T change, JsonSerializationContext context) {
        return createJsonObject(change, context);
    }

    protected PropertyChangeMetadata deserializeStub(JsonObject jsonObject, JsonDeserializationContext context) {
        GlobalId id = deserializeAffectedCdoId(jsonObject, context);
        String propertyName = jsonObject.get(PROPERTY_FIELD).getAsString();
        CommitMetadata commitMetadata = deserializeCommitMetadata(jsonObject, context);

        PropertyChangeType propertyChangeType = jsonObject.get(PROPERTY_CHANGE_TYPE) != null
            ? PropertyChangeType.valueOf(jsonObject.get(PROPERTY_CHANGE_TYPE).getAsString())
            : PropertyChangeType.PROPERTY_VALUE_CHANGED;

        return new PropertyChangeMetadata(id, propertyName, Optional.ofNullable(commitMetadata), propertyChangeType);
    }

    protected GlobalId deserializeAffectedCdoId(JsonObject jsonObject, JsonDeserializationContext context) {
        return context.deserialize(jsonObject.get(AFFECTED_CDO_ID_FIELD), GlobalId.class);
    }

    protected JsonObject createJsonObject(T change, JsonSerializationContext context) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty(CHANGE_TYPE_FIELD, encode(change.getClass()));
        jsonObject.add(AFFECTED_CDO_ID_FIELD, context.serialize(change.getAffectedGlobalId()));

        if (change.getCommitMetadata().isPresent()) {
            jsonObject.add(COMMIT_METADATA, context.serialize(change.getCommitMetadata().get()));
        }

        if (change instanceof PropertyChange) {
            jsonObject.addProperty(PROPERTY_FIELD, ((PropertyChange) change).getPropertyName());
            PropertyChangeType changeType =  ((PropertyChange) change).getChangeType();
            if (changeType != null) {
                jsonObject.addProperty(PROPERTY_CHANGE_TYPE, changeType.name());
            }
        }
        return jsonObject;
    }

    @Override
    public Class getValueType() {
        return Change.class;
    }

    private void initEntry(Class changeClass) {
        changeTypeMap.put(encode(changeClass), changeClass);
    }

    private String encode(Class valueChangeClass) {
        return valueChangeClass.getSimpleName();
    }

    Class decodeChangeType(JsonObject jsonObject){
        String changeTypeField = jsonObject.get(CHANGE_TYPE_FIELD).getAsString();
        if (!changeTypeMap.containsKey(changeTypeField)) {
            throw new JaversException(JaversExceptionCode.MALFORMED_CHANGE_TYPE_FIELD, changeTypeField);
        }
        return changeTypeMap.get(changeTypeField);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy