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

org.javers.core.diff.NodePair Maven / Gradle / Ivy

package org.javers.core.diff;

import org.javers.common.validation.Validate;
import org.javers.core.commit.CommitMetadata;
import org.javers.core.diff.changetype.PropertyChangeMetadata;
import org.javers.core.diff.changetype.PropertyChangeType;
import org.javers.core.graph.ObjectNode;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.property.MissingProperty;
import org.javers.core.metamodel.property.Property;
import org.javers.core.metamodel.type.*;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * holds two versions of the same {@link ObjectNode}
 *
 * @author bartosz walacik
 */
public class NodePair {
    private final ObjectNode left;
    private final ObjectNode right;
    private final Optional commitMetadata;

    NodePair(ObjectNode left, ObjectNode right) {
        this(left, right, Optional.empty());
    }

    public NodePair(ObjectNode left, ObjectNode right, Optional commitMetadata) {
        Validate.argumentsAreNotNull(left, right, commitMetadata);
        Validate.argumentCheck(left.getGlobalId().equals(right.getGlobalId()), "left & right should refer to the same Cdo");
        this.left = left;
        this.right = right;
        this.commitMetadata = commitMetadata;
    }

    public ManagedType getManagedType() {
        return right.getManagedType();
    }

    public boolean isNullOnBothSides(Property property) {
        return left.getPropertyValue(property) == null &&
                right.getPropertyValue(property) == null;
    }

    public Object getLeftPropertyValue(Property property) {
        return left.getPropertyValue(property);
    }

    public Object getRightPropertyValue(Property property) {
        return right.getPropertyValue(property);
    }

    public GlobalId getRightReference(Property property) {
        return right.getReference(property);
    }

    public GlobalId getLeftReference(Property property) {
        return left.getReference(property);
    }

    public List getRightReferences(JaversProperty property) {
        return right.getReferences(property);
    }

    public List getLeftReferences(JaversProperty property) {
        return left.getReferences(property);
    }

    public ObjectNode getRight() {
        return right;
    }

    public ObjectNode getLeft() {
        return left;
    }

    public ObjectNode getFirst() {
        return left;
    }

    boolean sameClass() {
        return right.getManagedType().getBaseJavaType() == left.getManagedType().getBaseJavaType();
    }

    public List getProperties() {
        if (sameClass()) {
            return getManagedType().getProperties();
        }
        else {
            return Collections.unmodifiableList(getPropertiesFromBothSides());
        }
    }

    private List getPropertiesFromBothSides() {
        Set leftNames = left.getManagedType().getProperties().stream()
                .map(it -> it.getName()).collect(Collectors.toSet());


        return Stream.concat(left.getManagedType().getProperties().stream(),
                              right.getManagedType().getProperties().stream().filter(it -> !leftNames.contains(it.getName())))
                       .collect(Collectors.toList());
    }

    public GlobalId getGlobalId() {
        return left.getGlobalId();
    }

    public Optional getCommitMetadata() {
        return commitMetadata;
    }

    public PropertyChangeType getChangeType(JaversProperty property) {
        if (getLeft().getManagedType().getBaseJavaClass() == getRight().getManagedType().getBaseJavaClass()) {
            return PropertyChangeType.PROPERTY_VALUE_CHANGED;
        }

        if (getLeftPropertyValue(property) == MissingProperty.INSTANCE) {
            return PropertyChangeType.PROPERTY_ADDED;
        }

        if (getRightPropertyValue(property) == MissingProperty.INSTANCE) {
            return PropertyChangeType.PROPERTY_REMOVED;
        }

        return PropertyChangeType.PROPERTY_VALUE_CHANGED;
    }

    public Object getRightDehydratedPropertyValueAndSanitize(JaversProperty property) {
        return sanitize(getRight().getDehydratedPropertyValue(property), property.getType());
    }

    public Object getLeftDehydratedPropertyValueAndSanitize(JaversProperty property) {
        return sanitize(getLeft().getDehydratedPropertyValue(property), property.getType());
    }

    public Object sanitize(Object value, JaversType expectedType) {
        //all Enumerables (except Arrays) are sanitized
        if (expectedType instanceof EnumerableType && !(expectedType instanceof ArrayType)) {
            EnumerableType enumerableType = (EnumerableType)expectedType;
            if (value == null || !enumerableType.getEnumerableInterface().isAssignableFrom(value.getClass())) {
                return ((EnumerableType)expectedType).empty();
            }
        }
        return value;
    }

    public PropertyChangeMetadata createPropertyChangeMetadata(JaversProperty property) {
        return new PropertyChangeMetadata(getGlobalId(), property.getName(), getCommitMetadata(), getChangeType(property));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy