# HG changeset patch # User dirk # Date 1316185437 -7200 # Node ID e60d38aa42fe4a13a0a1169a67d6c5690a38ab7c # Parent f2daf738299fea44bc88b2dd3a90d2aa6c7373c9 generate differences for missing keys either in the original document or in the conflicting document. diff -r f2daf738299f -r e60d38aa42fe conflict-editor/src/main/java/de/codedo/conflicteditor/DocumentMatcher.java --- a/conflict-editor/src/main/java/de/codedo/conflicteditor/DocumentMatcher.java Fri Sep 16 11:38:15 2011 +0200 +++ b/conflict-editor/src/main/java/de/codedo/conflicteditor/DocumentMatcher.java Fri Sep 16 17:03:57 2011 +0200 @@ -21,6 +21,7 @@ private JsonNode _original; private JsonNode _other; + private List _differences; public DocumentMatcher(JsonNode original, JsonNode other) { @@ -31,22 +32,92 @@ public List compare() { - List differences = new ArrayList(); + if (_differences == null) + { + _differences = new ArrayList(); + createDifferencesFromFieldsOnlyAvailableInOriginal(); + createDifferencesFromFieldsOnlyAvailableInConflict(); + createDifferencesFromFieldValues(); + } + return _differences; + } + private void createDifferencesFromFieldsOnlyAvailableInOriginal() + { Set originalFieldNames = getFieldNames(_original); + Set otherFieldNames = getFieldNames(_other); + originalFieldNames.removeAll(otherFieldNames); + for (String name : originalFieldNames) { - // TODO better handling of values - could be of non-string type really - Object originalValue = _original.findValue(name).getValueAsText(); - Object otherValue = _other.findValue(name).getValueAsText(); - if (originalValue.equals(otherValue) == false) + // TODO value may not be text + String value = _original.findValue(name).getTextValue(); + Difference diff = new Difference(name, value, null); + _differences.add(diff); + } + } + + private void createDifferencesFromFieldsOnlyAvailableInConflict() + { + Set originalFieldNames = getFieldNames(_original); + Set otherFieldNames = getFieldNames(_other); + otherFieldNames.removeAll(originalFieldNames); + + for (String name : otherFieldNames) + { + // TODO value may not be text + String value = _other.findValue(name).getTextValue(); + Difference diff = new Difference(name, null, value); + _differences.add(diff); + } + } + + private void createDifferencesFromFieldValues() + { + Set originalFieldNames = getFieldNames(_original); + Set otherFieldNames = getFieldNames(_other); + originalFieldNames.retainAll(otherFieldNames); + + for (String name : originalFieldNames) + { + Difference difference = compareValuesForKey(name); + if (difference != null) { - Difference diff = new Difference(name, originalValue, otherValue); - differences.add(diff); + _differences.add(difference); } } + } - return differences; + private Difference compareValuesForKey(String key) + { + JsonNode original = _original.findValue(key); + JsonNode other = _other.findValue(key); + + if ((original != null) && (other == null)) + { + // TODO this may be something different than plain text, e.g. some structured object + return new Difference(key, original.getValueAsText(), null); + } + else if ((original == null) && (other != null)) + { + // TODO this may be something different than plain text, e.g. some structured object + return new Difference(key, null, other.getValueAsText()); + } + else + { + return compareValues(key, original, other); + } + } + + private Difference compareValues(String key, JsonNode original, JsonNode other) + { + Object originalValue = original.getValueAsText(); + Object otherValue = other.getValueAsText(); + if (originalValue.equals(otherValue) == false) + { + return new Difference(key, originalValue, otherValue); + } + return null; } private Set getFieldNames(JsonNode node) diff -r f2daf738299f -r e60d38aa42fe conflict-editor/src/test/java/de/codedo/conflicteditor/DocumentMatcherTestCase.java --- a/conflict-editor/src/test/java/de/codedo/conflicteditor/DocumentMatcherTestCase.java Fri Sep 16 11:38:15 2011 +0200 +++ b/conflict-editor/src/test/java/de/codedo/conflicteditor/DocumentMatcherTestCase.java Fri Sep 16 17:03:57 2011 +0200 @@ -1,6 +1,10 @@ package de.codedo.conflicteditor; +import static de.codedo.conflicteditor.matchers.ObjectEqualityMatcher.isEqualTo; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasSize; import static org.junit.Assert.assertEquals; @@ -10,7 +14,6 @@ import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.map.ObjectMapper; -import org.junit.Ignore; import org.junit.Test; public class DocumentMatcherTestCase extends Object @@ -39,20 +42,27 @@ assertEquals("other-value", diff.otherValue); } - @Ignore("does not work yet") @Test public void valuePresentOnlyInOriginalShouldProduceDifference() throws Exception { - JsonNode original = parse("{ 'key' : 'value', 'only-here' : 'test' }"); + JsonNode original = parse("{ 'key' : 'value', 'only-here' : 'value' }"); JsonNode conflict = parse("{ 'key' : 'value' }"); List diffs = new DocumentMatcher(original, conflict).compare(); assertThat(diffs, hasSize(1)); + + Difference diff = diffs.get(0); + assertThat(diff.key, is("only-here")); + assertThat(diff.currentValue, isEqualTo("value")); + assertThat(diff.otherValue, is(nullValue())); } - @Ignore("not yet implemented") @Test - public void valueOnlyInConflict() throws Exception + public void valuePresentOnlyInConflictShouldProduceDifference() throws Exception { + JsonNode original = parse("{ 'key' : 'value' }"); + JsonNode conflict = parse("{ 'key' : 'value', 'only-here' : 'test' }"); + List diffs = new DocumentMatcher(original, conflict).compare(); + assertThat(diffs, hasSize(1)); } private JsonNode parse(String input) throws IOException diff -r f2daf738299f -r e60d38aa42fe conflict-editor/src/test/java/de/codedo/conflicteditor/matchers/ObjectEqualityMatcher.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/conflict-editor/src/test/java/de/codedo/conflicteditor/matchers/ObjectEqualityMatcher.java Fri Sep 16 17:03:57 2011 +0200 @@ -0,0 +1,20 @@ + +package de.codedo.conflicteditor.matchers; + +import org.hamcrest.Factory; +import org.hamcrest.Matcher; +import org.hamcrest.core.IsEqual; + +public class ObjectEqualityMatcher extends IsEqual +{ + public ObjectEqualityMatcher(Object equalArg) + { + super(equalArg); + } + + @Factory + public static Matcher isEqualTo(Object operand) + { + return new ObjectEqualityMatcher(operand); + } +}