Skip to content

Commit

Permalink
remove java object diff, wire in our implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
syjer committed Sep 8, 2019
1 parent 94152c7 commit 2711084
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 109 deletions.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ dependencies {
compile 'com.atlassian.commonmark:commonmark-ext-gfm-tables:0.13.0'
compile 'com.ryantenney.passkit4j:passkit4j:2.0.1'
compile 'com.github.ben-manes.caffeine:caffeine:2.7.0'
compile 'de.danielbechler:java-object-diff:0.95'
compile 'com.github.scribejava:scribejava-core:5.0.0'
compile 'ch.digitalfondue.vatchecker:vatchecker:1.2'
compile 'ch.digitalfondue.basicxlsx:basicxlsx:0.5.1'
Expand Down
52 changes: 11 additions & 41 deletions src/main/java/alfio/manager/TicketReservationManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@
import alfio.repository.user.UserRepository;
import alfio.util.*;
import ch.digitalfondue.npjt.AffectedRowCountAndKey;
import de.danielbechler.diff.ObjectDifferBuilder;
import de.danielbechler.diff.node.DiffNode;
import de.danielbechler.diff.node.Visit;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
Expand Down Expand Up @@ -1421,49 +1418,22 @@ boolean isTicketBeingReassigned(Ticket original, UpdateTicketOwnerForm updated,
}

private void auditUpdateTicket(Ticket preUpdateTicket, Map<String, String> preUpdateTicketFields, Ticket postUpdateTicket, Map<String, String> postUpdateTicketFields, int eventId) {
DiffNode diffTicket = ObjectDifferBuilder.buildDefault().compare(postUpdateTicket, preUpdateTicket);
DiffNode diffTicketFields = ObjectDifferBuilder.buildDefault().compare(postUpdateTicketFields, preUpdateTicketFields);
FieldChangesSaver diffTicketVisitor = new FieldChangesSaver(preUpdateTicket, postUpdateTicket);
FieldChangesSaver diffTicketFieldsVisitor = new FieldChangesSaver(preUpdateTicketFields, postUpdateTicketFields);
diffTicket.visit(diffTicketVisitor);
diffTicketFields.visit(diffTicketFieldsVisitor);

List<Map<String, Object>> changes = new ArrayList<>(diffTicketVisitor.changes);
changes.addAll(diffTicketFieldsVisitor.changes);
List<ObjectDiffUtil.Change> diffTicket = ObjectDiffUtil.diff(preUpdateTicket, postUpdateTicket);
List<ObjectDiffUtil.Change> diffTicketFields = ObjectDiffUtil.diff(preUpdateTicketFields, postUpdateTicketFields);

List<Map<String, Object>> changes = Stream.concat(diffTicket.stream(), diffTicketFields.stream()).map(change -> {
var v = new HashMap<String, Object>();
v.put("propertyName", change.getPropertyName());
v.put("state", change.getState());
v.put("oldValue", change.getOldValue());
v.put("newValue", change.getNewValue());
return v;
}).collect(Collectors.toList());

auditingRepository.insert(preUpdateTicket.getTicketsReservationId(), null, eventId,
Audit.EventType.UPDATE_TICKET, new Date(), Audit.EntityType.TICKET, Integer.toString(preUpdateTicket.getId()), changes);
}


private static class FieldChangesSaver implements DiffNode.Visitor {

private final Object preBase;
private final Object postBase;

private final List<Map<String, Object>> changes = new ArrayList<>();


FieldChangesSaver(Object preBase, Object postBase) {
this.preBase = preBase;
this.postBase = postBase;
}

@Override
public void node(DiffNode node, Visit visit) {
if(node.hasChanges() && node.getState() != DiffNode.State.UNTOUCHED && !node.isRootNode()) {
Object baseValue = node.canonicalGet(preBase);
Object workingValue = node.canonicalGet(postBase);
HashMap<String, Object> change = new HashMap<>();
change.put("propertyName", node.getPath().toString());
change.put("state", node.getState());
change.put("oldValue", baseValue);
change.put("newValue", workingValue);
changes.add(change);
}
}
}

private boolean isAdmin(Optional<UserDetails> userDetails) {
return userDetails.flatMap(u -> u.getAuthorities().stream().map(a -> Role.fromRoleName(a.getAuthority())).filter(Role.ADMIN::equals).findFirst()).isPresent();
}
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/alfio/util/ObjectDiffUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@
public class ObjectDiffUtil {

public static List<Change> diff(Map<String, String> before, Map<String, String> after) {
return diffUntyped(before, after);
return diffUntyped(before, after, "/{", "}");
}

private static List<Change> diffUntyped(Map<String, ?> before, Map<String, ?> after) {
private static String formatPropertyName(String k, String propertyNameBefore, String propertyNameAfter) {
return new StringBuilder(propertyNameBefore).append(k).append(propertyNameAfter).toString();
}

private static List<Change> diffUntyped(Map<String, ?> before, Map<String, ?> after, String propertyNameBefore, String propertyNameAfter) {
var removed = new HashSet<>(before.keySet());
removed.removeAll(after.keySet());

Expand All @@ -48,13 +52,13 @@ private static List<Change> diffUntyped(Map<String, ?> before, Map<String, ?> af

var changes = new ArrayList<Change>();

removed.stream().map(k -> new Change(k, State.REMOVED, before.get(k), null)).forEach(changes::add);
added.stream().map(k -> new Change(k, State.ADDED, null, after.get(k))).forEach(changes::add);
removed.stream().map(k -> new Change(formatPropertyName(k, propertyNameBefore, propertyNameAfter), State.REMOVED, before.get(k), null)).forEach(changes::add);
added.stream().map(k -> new Change(formatPropertyName(k, propertyNameBefore, propertyNameAfter), State.ADDED, null, after.get(k))).forEach(changes::add);
changedOrUntouched.stream().forEach(k -> {
var beforeValue = before.get(k);
var afterValue = after.get(k);
if(!Objects.equals(beforeValue, afterValue)) {
changes.add(new Change(k, State.CHANGED, beforeValue, afterValue));
changes.add(new Change(formatPropertyName(k, propertyNameBefore, propertyNameAfter), State.CHANGED, beforeValue, afterValue));
}
});
changes.sort(Change::compareTo);
Expand All @@ -73,7 +77,7 @@ public static List<Change> diff(Ticket before, Ticket after) {
afterAsMap.put(name, ReflectionUtils.invokeMethod(method, after));
}
});
return diffUntyped(beforeAsMap, afterAsMap);
return diffUntyped(beforeAsMap, afterAsMap, "/", "");
}

@AllArgsConstructor
Expand Down
65 changes: 4 additions & 61 deletions src/test/java/alfio/util/ObjectDiffTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,11 @@
package alfio.util;

import alfio.model.Ticket;
import de.danielbechler.diff.ObjectDifferBuilder;
import de.danielbechler.diff.node.DiffNode;
import de.danielbechler.diff.node.Visit;
import org.junit.Assert;
import org.junit.Test;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ObjectDiffTest {
Expand All @@ -43,30 +38,6 @@ public class ObjectDiffTest {
false, "en",
0, 0, 0, 0, null, null);


@Test
public void diffTest() {



var postUpdateTicketFields = new HashMap<String, String>();
postUpdateTicketFields.put("hello", "world");
var preUpdateTicketFields = new HashMap<String, String>();

DiffNode diffTicket = ObjectDifferBuilder.buildDefault().compare(postUpdateTicket, preUpdateTicket);
DiffNode diffTicketFields = ObjectDifferBuilder.buildDefault().compare(postUpdateTicketFields, preUpdateTicketFields);
FieldChangesSaver diffTicketVisitor = new FieldChangesSaver(preUpdateTicket, postUpdateTicket);
FieldChangesSaver diffTicketFieldsVisitor = new FieldChangesSaver(preUpdateTicketFields, postUpdateTicketFields);
diffTicket.visit(diffTicketVisitor);
diffTicketFields.visit(diffTicketFieldsVisitor);

List<Map<String, Object>> changes = new ArrayList<>(diffTicketVisitor.changes);
changes.addAll(diffTicketFieldsVisitor.changes);

Assert.assertEquals(2, changes.size());

}

@Test
public void diffMapTest() {
Map<String, String> empty = Map.of();
Expand All @@ -76,21 +47,21 @@ public void diffMapTest() {
var newElement = Map.of("new", "element");
var newElementRes = ObjectDiffUtil.diff(emptyAfter, newElement);
Assert.assertEquals(1, newElementRes.size());
Assert.assertEquals("new", newElementRes.get(0).getPropertyName());
Assert.assertEquals("/{new}", newElementRes.get(0).getPropertyName());
Assert.assertEquals("element", newElementRes.get(0).getNewValue());
Assert.assertEquals(null, newElementRes.get(0).getOldValue());
Assert.assertEquals(ObjectDiffUtil.State.ADDED, newElementRes.get(0).getState());

var removedElementRes = ObjectDiffUtil.diff(newElement, empty);
Assert.assertEquals(1, removedElementRes.size());
Assert.assertEquals("new", removedElementRes.get(0).getPropertyName());
Assert.assertEquals("/{new}", removedElementRes.get(0).getPropertyName());
Assert.assertEquals(null, removedElementRes.get(0).getNewValue());
Assert.assertEquals("element", removedElementRes.get(0).getOldValue());
Assert.assertEquals(ObjectDiffUtil.State.REMOVED, removedElementRes.get(0).getState());

var changedElem = ObjectDiffUtil.diff(newElement, Map.of("new", "changed"));
Assert.assertEquals(1, changedElem.size());
Assert.assertEquals("new", changedElem.get(0).getPropertyName());
Assert.assertEquals("/{new}", changedElem.get(0).getPropertyName());
Assert.assertEquals("changed", changedElem.get(0).getNewValue());
Assert.assertEquals("element", changedElem.get(0).getOldValue());
Assert.assertEquals(ObjectDiffUtil.State.CHANGED, changedElem.get(0).getState());
Expand All @@ -105,37 +76,9 @@ public void testTicketDiff() {
var res = ObjectDiffUtil.diff(preUpdateTicket, postUpdateTicket);

Assert.assertEquals(1, res.size());
Assert.assertEquals("status", res.get(0).getPropertyName());
Assert.assertEquals("/status", res.get(0).getPropertyName());
Assert.assertEquals(Ticket.TicketStatus.CANCELLED, res.get(0).getNewValue());
Assert.assertEquals(Ticket.TicketStatus.ACQUIRED, res.get(0).getOldValue());
Assert.assertEquals(ObjectDiffUtil.State.CHANGED, res.get(0).getState());
}

private static class FieldChangesSaver implements DiffNode.Visitor {

private final Object preBase;
private final Object postBase;

private final List<Map<String, Object>> changes = new ArrayList<>();


FieldChangesSaver(Object preBase, Object postBase) {
this.preBase = preBase;
this.postBase = postBase;
}

@Override
public void node(DiffNode node, Visit visit) {
if(node.hasChanges() && node.getState() != DiffNode.State.UNTOUCHED && !node.isRootNode()) {
Object baseValue = node.canonicalGet(preBase);
Object workingValue = node.canonicalGet(postBase);
HashMap<String, Object> change = new HashMap<>();
change.put("propertyName", node.getPath().toString());
change.put("state", node.getState());
change.put("oldValue", baseValue);
change.put("newValue", workingValue);
changes.add(change);
}
}
}
}

0 comments on commit 2711084

Please sign in to comment.