Skip to content

Commit

Permalink
https://github.com/javers/javers/issues/795
Browse files Browse the repository at this point in the history
tests are green
  • Loading branch information
bartoszwalacik committed Mar 10, 2019
1 parent 47bcd7f commit f292850
Show file tree
Hide file tree
Showing 41 changed files with 277 additions and 296 deletions.
Expand Up @@ -18,6 +18,14 @@ public class Sets {
private Sets() {
}


public static Set wrapNull(Object set) {
if (set == null) {
return Collections.emptySet();
}
return (Set) set;
}

/**
* null args are allowed
*/
Expand Down
Expand Up @@ -40,7 +40,7 @@ public enum JaversExceptionCode {

MISSING_PROPERTY("There is no property '%s' in type '%s'."),

NOT_IMPLEMENTED("not implemented, %"),
NOT_IMPLEMENTED("not implemented, %s"),

IGNORED_AND_INCLUDED_PROPERTIES_MIX("Mapping error in class '%s'. You can either specify Included Properties or Ignored Properties, not both."),

Expand Down
Expand Up @@ -110,7 +110,7 @@ protected JaversBuilder() {
if (isClassPresent("org.joda.time.LocalDate")){
conditionalTypesPlugins.add(new JodaAddOns());
}
if (isClassPresent("com.google.common.mapToList.Multimap")) {
if (isClassPresent("com.google.common.collect.Multimap")) {
conditionalTypesPlugins.add(new GuavaAddOns());
}

Expand Down
13 changes: 12 additions & 1 deletion javers-core/src/main/java/org/javers/core/diff/FakeNodePair.java
@@ -1,6 +1,8 @@
package org.javers.core.diff;

import org.javers.common.collections.Defaults;
import org.javers.common.exception.JaversException;
import org.javers.common.exception.JaversExceptionCode;
import org.javers.core.graph.ObjectNode;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.property.Property;
Expand Down Expand Up @@ -38,6 +40,16 @@ public ObjectNode getRight() {
return right;
}

@Override
public ObjectNode getLeft() {
throw new JaversException(JaversExceptionCode.NOT_IMPLEMENTED, "FakeNodePair.getLeft()");
}

@Override
public Object getLeftDehydratedPropertyValueAndSanitize(JaversProperty property) {
return Defaults.defaultValue(property.getGenericType());
}

@Override
public List<JaversProperty> getProperties() {
return getManagedType().getProperties();
Expand All @@ -52,7 +64,6 @@ public Object getLeftPropertyValue(Property property) {
public Object getRightPropertyValue(Property property) {
return right.getPropertyValue(property);
}

@Override
public GlobalId getRightReference(Property property) {
return right.getReference(property);
Expand Down
47 changes: 12 additions & 35 deletions javers-core/src/main/java/org/javers/core/diff/NodePair.java
Expand Up @@ -14,6 +14,8 @@ public interface NodePair {

ObjectNode getRight();

ObjectNode getLeft();

List<JaversProperty> getProperties();

Object getLeftPropertyValue(Property property);
Expand All @@ -30,47 +32,22 @@ public interface NodePair {

ManagedType getManagedType();

default Object getLeftPropertyValueAndSanitize(Property property, JaversType expectedType) {
return sanitize(getLeftPropertyValue(property), expectedType);
}

default Object getRightPropertyValueAndSanitize(Property property, JaversType expectedType) {
return sanitize(getRightPropertyValue(property), expectedType);
}

default Collection getLeftPropertyCollectionAndSanitize(Property property) {
return sanitizeCollection(getLeftPropertyValue(property));
default Object getRightDehydratedPropertyValueAndSanitize(JaversProperty property) {
return sanitize(getRight().getDehydratedPropertyValue(property), property.getType());
}

default Collection getRightPropertyCollectionAndSanitize(Property property) {
return sanitizeCollection(getRightPropertyValue(property));
}

default Collection sanitizeCollection(Object value) {
if (value == null) {
return Collections.emptyList();
}

if (value instanceof Collection) {
return (Collection)value;
}

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

default Object sanitize(Object value, JaversType expectedType) {
if (value == null) {
return null;
}

if (expectedType.isInstance(value)) {
return value;
//all Enumerables (except Arrays) are sanitized
if (expectedType instanceof EnumerableType && !(expectedType instanceof ArrayType)) {
if (value == null || !expectedType.isInstance(value)) {
return ((EnumerableType)expectedType).empty();
}
}

if (expectedType instanceof EnumerableType) {
return ((EnumerableType)expectedType).empty();
}

return null;
return value;
}
}
Expand Up @@ -72,6 +72,11 @@ public ObjectNode getRight() {
return right;
}

@Override
public ObjectNode getLeft() {
return left;
}

@Override
public List<JaversProperty> getProperties() {
return getManagedType().getProperties();
Expand Down
Expand Up @@ -2,9 +2,11 @@

import org.javers.common.collections.Arrays;
import org.javers.common.collections.Lists;
import org.javers.core.diff.NodePair;
import org.javers.core.diff.changetype.container.ArrayChange;
import org.javers.core.diff.changetype.container.ContainerElementChange;
import org.javers.core.diff.changetype.map.EntryChange;
import org.javers.core.diff.changetype.map.MapChange;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.object.OwnerContext;
import org.javers.core.metamodel.object.PropertyOwnerContext;
Expand All @@ -16,7 +18,7 @@
/**
* @author pawel szymczyk
*/
class ArrayChangeAppender extends CorePropertyChangeAppender<ArrayChange>{
class ArrayChangeAppender implements PropertyChangeAppender<ArrayChange>{
private final MapChangeAppender mapChangeAppender;
private final TypeMapper typeMapper;

Expand All @@ -31,21 +33,20 @@ public boolean supports(JaversType propertyType) {
}

@Override
public ArrayChange calculateChanges(Object leftValue, Object rightValue, GlobalId affectedId, JaversProperty property) {
public ArrayChange calculateChanges(NodePair pair, JaversProperty property) {

Map leftMap = Arrays.asMap(leftValue);
Map rightMap = Arrays.asMap(rightValue);
Map leftMap = Arrays.asMap(pair.getLeftDehydratedPropertyValueAndSanitize(property));
Map rightMap = Arrays.asMap(pair.getRightDehydratedPropertyValueAndSanitize(property));

ArrayType arrayType = property.getType();
OwnerContext owner = new PropertyOwnerContext(affectedId, property.getName());
MapContentType mapContentType = typeMapper.getMapContentType(arrayType);

List<EntryChange> entryChanges =
mapChangeAppender.calculateEntryChanges(leftMap, rightMap, owner, mapContentType);
mapChangeAppender.calculateEntryChanges(leftMap, rightMap, mapContentType);

if (!entryChanges.isEmpty()){
List<ContainerElementChange> elementChanges = Lists.transform(entryChanges, new MapChangesToListChangesFunction());
return new ArrayChange(affectedId, property.getName(), elementChanges);
return new ArrayChange(pair.getGlobalId(), property.getName(), elementChanges);
}
else {
return null;
Expand Down
Expand Up @@ -7,7 +7,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Type;
import java.util.Optional;

import static org.javers.core.metamodel.type.JaversType.DEFAULT_TYPE_PARAMETER;

Expand Down Expand Up @@ -41,8 +40,8 @@ public static void renderNotParametrizedWarningIfNeeded(Type parameterType, Stri

@Override
final public T calculateChanges(NodePair pair, JaversProperty property) {
Object leftValue = pair.getLeftPropertyValueAndSanitize(property, property.getType());
Object rightValue = pair.getRightPropertyValueAndSanitize(property, property.getType());
Object leftValue = pair.getLeftDehydratedPropertyValueAndSanitize(property);
Object rightValue = pair.getRightDehydratedPropertyValueAndSanitize(property);
return calculateChanges(leftValue, rightValue, pair.getGlobalId(), property);
}

Expand Down
Expand Up @@ -27,11 +27,10 @@ abstract class ListToMapAppenderAdapter extends CorePropertyChangeAppender<ListC

ListChange calculateChanges(List leftList, List rightList, GlobalId affectedId, JaversProperty property) {
CollectionType listType = ((JaversProperty) property).getType();
OwnerContext owner = new PropertyOwnerContext(affectedId, property.getName());
MapContentType mapContentType = typeMapper.getMapContentType(listType);

List<EntryChange> entryChanges =
mapChangeAppender.calculateEntryChanges(asMap(leftList), asMap(rightList), owner, mapContentType);
mapChangeAppender.calculateEntryChanges(asMap(leftList), asMap(rightList), mapContentType);

if (!entryChanges.isEmpty()){
List<ContainerElementChange> elementChanges = Lists.transform(entryChanges, new MapChangesToListChangesFunction());
Expand Down
Expand Up @@ -3,21 +3,22 @@
import org.javers.common.collections.Maps;
import org.javers.common.exception.JaversException;
import org.javers.common.validation.Validate;
import org.javers.core.diff.NodePair;
import org.javers.core.diff.changetype.map.*;
import org.javers.core.metamodel.object.*;
import org.javers.core.metamodel.object.GlobalIdFactory;
import org.javers.core.metamodel.type.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.javers.common.exception.JaversExceptionCode.VALUE_OBJECT_IS_NOT_SUPPORTED_AS_MAP_KEY;
import static org.javers.core.diff.appenders.CorePropertyChangeAppender.renderNotParametrizedWarningIfNeeded;

/**
* @author bartosz walacik
*/
class MapChangeAppender extends CorePropertyChangeAppender<MapChange> {
private static final Logger logger = LoggerFactory.getLogger(MapChangeAppender.class);
class MapChangeAppender implements PropertyChangeAppender<MapChange> {

private final TypeMapper typeMapper;
private final GlobalIdFactory globalIdFactory;
Expand All @@ -42,20 +43,21 @@ public boolean supports(JaversType propertyType) {
return true;
}

public MapChange calculateChanges(Object leftValue, Object rightValue, GlobalId affectedId, JaversProperty property) {
Map leftRawMap = (Map) leftValue;
Map rightRawMap = (Map) rightValue;
@Override
public MapChange calculateChanges(NodePair pair, JaversProperty property) {

Map left = (Map) pair.getLeftDehydratedPropertyValueAndSanitize(property);
Map right = (Map) pair.getRightDehydratedPropertyValueAndSanitize(property);

MapType mapType = ((JaversProperty) property).getType();
MapContentType mapContentType = typeMapper.getMapContentType(mapType);

OwnerContext owner = new PropertyOwnerContext(affectedId, property.getName());
List<EntryChange> changes = calculateEntryChanges(leftRawMap, rightRawMap, owner, mapContentType);
List<EntryChange> changes = calculateEntryChanges(left, right, mapContentType);

if (!changes.isEmpty()){
renderNotParametrizedWarningIfNeeded(mapContentType.getKeyType().getBaseJavaType(), "key", "Map", property);
renderNotParametrizedWarningIfNeeded(mapContentType.getValueType().getBaseJavaType(), "value", "Map", property);
return new MapChange(affectedId, property.getName(), changes);
return new MapChange(pair.getGlobalId(), property.getName(), changes);
}
else {
return null;
Expand All @@ -65,12 +67,7 @@ public MapChange calculateChanges(Object leftValue, Object rightValue, GlobalId
/**
* @return never returns null
*/
List<EntryChange> calculateEntryChanges(Map leftRawMap, Map rightRawMap, OwnerContext owner, MapContentType mapContentType) {

DehydrateMapFunction dehydrateFunction = new DehydrateMapFunction(globalIdFactory, mapContentType);

Map leftMap = MapType.mapStatic(leftRawMap, dehydrateFunction, owner);
Map rightMap = MapType.mapStatic(rightRawMap, dehydrateFunction, owner);
List<EntryChange> calculateEntryChanges(Map leftMap, Map rightMap, MapContentType mapContentType) {

List<EntryChange> changes = new ArrayList<>();

Expand Down
Expand Up @@ -2,7 +2,7 @@

import org.javers.core.diff.Change;
import org.javers.core.diff.GraphPair;
import org.javers.core.diff.changetype.NewObject;
import org.javers.core.diff.changetype.ObjectRemoved;

import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -12,7 +12,7 @@ class ObjectRemovedAppender implements NodeChangeAppender {
@Override
public Set<Change> getChangeSet(GraphPair graphPair) {
return (Set)graphPair.getOnlyOnLeft().stream()
.map(input -> new NewObject(input.getGlobalId(), input.wrappedCdo()))
.map(input -> new ObjectRemoved(input.getGlobalId(), input.wrappedCdo()))
.collect(Collectors.toSet());
}
}

0 comments on commit f292850

Please sign in to comment.