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

org.javers.core.metamodel.type.InstanceIdFactory Maven / Gradle / Ivy

package org.javers.core.metamodel.type;

import org.javers.common.exception.JaversException;
import org.javers.common.exception.JaversExceptionCode;
import org.javers.common.validation.Validate;
import org.javers.core.metamodel.object.InstanceId;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class InstanceIdFactory {
    private final EntityType entityType;

    InstanceIdFactory(EntityType entityType) {
        this.entityType = entityType;
    }

    InstanceId create(Object localId) {
        Validate.argumentsAreNotNull(entityType, localId);

        DehydratedLocalId dehydratedLocalId = dehydratedLocalId(localId);

        return new InstanceId(entityType.getName(),
                dehydratedLocalId.getId(),
                dehydratedLocalId.toLocalIdString());
    }

    InstanceId createFromDeserializedJsonLocalId(Object deserializedLocalId) {
        Validate.argumentsAreNotNull(entityType, deserializedLocalId);

        String localIdAsString = localIdAsStringFromJson(deserializedLocalId);

        return new InstanceId(entityType.getName(), deserializedLocalId, localIdAsString);
    }

    private String localIdAsStringFromJson(Object deserializedJsonLocalId) {
        if (deserializedJsonLocalId instanceof String) {
            return (String) deserializedJsonLocalId;
        }

        JaversProperty idProperty = entityType.getIdProperty();
        if (idProperty.isEntityType()) {
            EntityType idPropertyType = idProperty.getType();
            return idPropertyType.getInstanceIdFactory().localIdAsStringFromJson(deserializedJsonLocalId);
        }
        if (idProperty.isValueObjectType()) {
            ValueObjectType valueObjectType = idProperty.getType();
            return valueObjectType.smartToString(deserializedJsonLocalId);
         }
        if (idProperty.isPrimitiveOrValueType()) {
            PrimitiveOrValueType primitiveOrValueType = idProperty.getType();
            return primitiveOrValueType.valueToString(deserializedJsonLocalId);
        }

        throw idTypeNotSupported();
    }

    private DehydratedLocalId dehydratedLocalId(JaversProperty idProperty, Object localId) {
        if (idProperty.isEntityType()) {
            EntityType idPropertyType = idProperty.getType();
            return idPropertyType.getInstanceIdFactory().dehydratedLocalId(idPropertyType.getIdOf(localId));
        }
        if (idProperty.isValueObjectType()) {
            ValueObjectType valueObjectType = idProperty.getType();
            String localIdAsString = valueObjectType.smartToString(localId);
            return new SimpleDehydratedLocalId(localIdAsString, valueObjectType.smartToString(localId));
        }
        if (idProperty.isPrimitiveOrValueType()) {
            PrimitiveOrValueType primitiveOrValueType = idProperty.getType();
            return new SimpleDehydratedLocalId(localId, primitiveOrValueType.valueToString(localId));
        }

        throw idTypeNotSupported();
    }


    private DehydratedLocalId dehydratedLocalId(Object localId) {

        if (entityType.hasCompositeId()) {
            Map compositeLocalId = (Map)localId;

            return new CompositeDehydratedLocalId( compositeLocalId
                    .entrySet()
                    .stream()
                    .sorted(Map.Entry.comparingByKey())
                    .map(e -> dehydratedLocalId(entityType.getProperty(e.getKey()), e.getValue()))
                    .collect(Collectors.toList()));
        }

        return dehydratedLocalId(entityType.getIdProperty(), localId);
    }

    private JaversException idTypeNotSupported() {
        return new JaversException(JaversExceptionCode.ID_TYPE_NOT_SUPPORTED,
                entityType.getIdProperty().getType().getClass().getSimpleName(),
                entityType.getIdProperty().getType().getName(),
                entityType.getBaseJavaClass().getName());
    }

    Type getLocalIdDehydratedJsonType() {
        if (entityType.hasCompositeId()) {
            return String.class;
        }

        JaversProperty idProperty = entityType.getIdProperty();

        if (idProperty.isEntityType()) {
            EntityType idPropertyType = idProperty.getType();
            return idPropertyType.getLocalIdDehydratedJsonType();
        }
        if (idProperty.isValueObjectType()) {
            return String.class;
        }
        if (idProperty.isPrimitiveOrValueType()) {
            return idProperty.getGenericType();
        }

        throw idTypeNotSupported();
    }

    private interface DehydratedLocalId {
        String toLocalIdString();
        Object getId();
    }

    private static class SimpleDehydratedLocalId implements DehydratedLocalId {
        private final Object localId;
        private final String localIdAsString;

        private SimpleDehydratedLocalId(Object localId, String localIdAsString) {
            this.localId = localId;
            this.localIdAsString = localIdAsString;
        }

        @Override
        public String toLocalIdString() {
            return localIdAsString;
        }

        @Override
        public Object getId() {
            return localId;
        }
    }

    private static class CompositeDehydratedLocalId implements DehydratedLocalId {
        private final List dehydratedLocalIds;

        private CompositeDehydratedLocalId(List dehydratedLocalIds) {
            this.dehydratedLocalIds = dehydratedLocalIds;
        }

        @Override
        public Object getId() {
            return toLocalIdString();
        }

        @Override
        public String toLocalIdString() {
            return String.join(",", dehydratedLocalIds.stream().map(it -> it.toLocalIdString()).collect(Collectors.toList()));
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy