Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit db25c53

Browse files
committed
Merge pull request #69 from j1ee/master
Added ability to compare a bean, map or collection by the result of a method call
2 parents 64f4c4b + 151d38d commit db25c53

24 files changed

+546
-3
lines changed

‎src/main/java/de/danielbechler/diff/BeanDiffer.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ public final Node compare(final Node parentNode, final Instances instances)
4949
{
5050
beanNode.setState(Node.State.IGNORED);
5151
}
52+
else if (nodeInspector.hasEqualsOnlyValueProviderMethod(beanNode)){
53+
String method = nodeInspector.getEqualsOnlyValueProviderMethod(beanNode);
54+
if (instances.areMethodResultsEqual(method))
55+
{
56+
beanNode.setState(Node.State.UNTOUCHED);
57+
}
58+
else
59+
{
60+
beanNode.setState(Node.State.CHANGED);
61+
}
62+
}
5263
else if (instances.areNull() || instances.areSame())
5364
{
5465
beanNode.setState(Node.State.UNTOUCHED);

‎src/main/java/de/danielbechler/diff/CollectionDiffer.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ else if (nodeInspector.isEqualsOnly(collectionNode))
6161
collectionNode.setState(Node.State.CHANGED);
6262
}
6363
}
64+
else if (nodeInspector.hasEqualsOnlyValueProviderMethod(collectionNode)){
65+
String method = nodeInspector.getEqualsOnlyValueProviderMethod(collectionNode);
66+
if (collectionInstances.areMethodResultsEqual(method))
67+
{
68+
collectionNode.setState(Node.State.UNTOUCHED);
69+
}
70+
else
71+
{
72+
collectionNode.setState(Node.State.CHANGED);
73+
}
74+
}
6475
else if (collectionInstances.hasBeenAdded())
6576
{
6677
compareItems(collectionNode, collectionInstances, collectionInstances.getWorking(Collection.class));

‎src/main/java/de/danielbechler/diff/Configuration.java‎

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@ public enum PrimitiveDefaultValueMode
7777
private final Collection<PropertyPath> includedProperties = new HashSet<PropertyPath>(10);
7878
private final Collection<PropertyPath> excludedProperties = new HashSet<PropertyPath>(10);
7979
private final Collection<PropertyPath> equalsOnlyProperties = new LinkedHashSet<PropertyPath>(10);
80+
private final Collection<PropertyPathAndMethod> equalsOnlyValueProviderMethods = new LinkedHashSet<PropertyPathAndMethod>(10);
8081
private final Collection<Class<?>> compareToOnlyTypes = new LinkedHashSet<Class<?>>(10);
8182
private final Collection<Class<?>> equalsOnlyTypes = new LinkedHashSet<Class<?>>(10);
83+
private final Collection<ClassAndMethod> equalsOnlyValueProviderTypes = new LinkedHashSet<ClassAndMethod>(10);
8284
private boolean returnUnchangedNodes = false;
8385
private boolean returnIgnoredNodes = false;
8486
private boolean returnCircularNodes = true;
@@ -124,7 +126,7 @@ public Configuration withoutProperty(final PropertyPath propertyPath)
124126
this.excludedProperties.add(propertyPath);
125127
return this;
126128
}
127-
129+
128130
public Configuration withCompareToOnlyType(final Class<?> type)
129131
{
130132
this.compareToOnlyTypes.add(type);
@@ -143,12 +145,22 @@ public Configuration withEqualsOnlyProperty(final PropertyPath propertyPath)
143145
return this;
144146
}
145147

148+
public Configuration withEqualsOnlyValueProviderMethod(final PropertyPath propertyPath, final String methodName) {
149+
this.equalsOnlyValueProviderMethods.add(new PropertyPathAndMethod(propertyPath, methodName));
150+
return this;
151+
}
152+
153+
public Configuration withEqualsOnlyValueProviderMethod(PropertyPathAndMethod propertyPathEqualsMethod) {
154+
this.equalsOnlyValueProviderMethods.add(propertyPathEqualsMethod);
155+
return this;
156+
}
157+
146158
public Configuration withIgnoredNodes()
147159
{
148160
this.returnIgnoredNodes = true;
149161
return this;
150162
}
151-
163+
152164
public Configuration withoutIgnoredNodes()
153165
{
154166
this.returnIgnoredNodes = false;
@@ -309,6 +321,57 @@ public boolean isEqualsOnly(final Node node)
309321
}
310322
return false;
311323
}
324+
325+
public boolean hasEqualsOnlyValueProviderMethod(Node node){
326+
return getEqualsOnlyValueProviderMethod(node) != null;
327+
}
328+
329+
public String getEqualsOnlyValueProviderMethod(Node node){
330+
final Class<?> propertyType = node.getType();
331+
if (propertyType != null)
332+
{
333+
ObjectDiffEqualsOnlyValueProvidedType annotation = propertyType.getAnnotation(ObjectDiffEqualsOnlyValueProvidedType.class);
334+
if (annotation != null)
335+
{
336+
return annotation.method();
337+
}
338+
339+
ClassAndMethod applicable = findEqualsOnlyValueProviderMethodForClass(propertyType);
340+
if (applicable != null)
341+
{
342+
return applicable.getMethod();
343+
}
344+
}
345+
if (node.hasEqualsOnlyValueProviderMethod())
346+
{
347+
return node.getEqualsOnlyValueProviderMethod();
348+
}
349+
PropertyPathAndMethod applicable = findEqualsOnlyValueProviderMethodForPath(node.getPropertyPath());
350+
if (applicable != null)
351+
{
352+
return applicable.getMethod();
353+
}
354+
return null;
355+
}
356+
357+
private ClassAndMethod findEqualsOnlyValueProviderMethodForClass(Class<?> clazz){
358+
for(ClassAndMethod propertyPathEqualsOnValueProviderType: equalsOnlyValueProviderTypes){
359+
if(clazz.equals(propertyPathEqualsOnValueProviderType.getClazz())){
360+
return propertyPathEqualsOnValueProviderType;
361+
}
362+
}
363+
return null;
364+
365+
}
366+
367+
private PropertyPathAndMethod findEqualsOnlyValueProviderMethodForPath(PropertyPath propertyPath){
368+
for(PropertyPathAndMethod propertyPathEqualsOnValueProviderMethod: equalsOnlyValueProviderMethods){
369+
if(propertyPath.equals(propertyPathEqualsOnValueProviderMethod.getPropertyPath())){
370+
return propertyPathEqualsOnValueProviderMethod;
371+
}
372+
}
373+
return null;
374+
}
312375

313376
public boolean isReturnable(final Node node)
314377
{
@@ -347,4 +410,5 @@ else if (node.isRemoved())
347410
}
348411
return true;
349412
}
413+
350414
}

‎src/main/java/de/danielbechler/diff/Instances.java‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,19 @@ public boolean areEqual()
172172
{
173173
return isEqual(base, working);
174174
}
175+
176+
public boolean areMethodResultsEqual(String method) {
177+
try {
178+
Object baseMethodResult = base.getClass().getMethod(method).invoke(base);
179+
Object workingMethodResult = working.getClass().getMethod(method).invoke(working);
180+
if(baseMethodResult == null){
181+
return workingMethodResult == null;
182+
}
183+
return baseMethodResult.equals(workingMethodResult);
184+
} catch (Exception e) {
185+
throw new RuntimeException(e);
186+
}
187+
}
175188

176189
public boolean areEqualByComparison()
177190
{

‎src/main/java/de/danielbechler/diff/MapDiffer.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ else if (nodeInspector.isEqualsOnly(mapNode))
6161
mapNode.setState(Node.State.CHANGED);
6262
}
6363
}
64+
else if (nodeInspector.hasEqualsOnlyValueProviderMethod(mapNode)){
65+
String method = nodeInspector.getEqualsOnlyValueProviderMethod(mapNode);
66+
if (instances.areMethodResultsEqual(method))
67+
{
68+
mapNode.setState(Node.State.UNTOUCHED);
69+
}
70+
else
71+
{
72+
mapNode.setState(Node.State.CHANGED);
73+
}
74+
}
6475
else if (instances.hasBeenAdded())
6576
{
6677
compareEntries(mapNode, instances, instances.getWorking(Map.class).keySet());

‎src/main/java/de/danielbechler/diff/NodeInspector.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ interface NodeInspector
3030
boolean isCompareToOnly(Node node);
3131

3232
boolean isEqualsOnly(Node node);
33+
34+
boolean hasEqualsOnlyValueProviderMethod(Node node);
35+
36+
String getEqualsOnlyValueProviderMethod(Node node);
3337

3438
boolean isReturnable(Node node);
3539

‎src/main/java/de/danielbechler/diff/accessor/AbstractAccessor.java‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public abstract class AbstractAccessor implements Accessor
2424
private Set<String> categories = new TreeSet<String>();
2525
private boolean equalsOnly;
2626
private boolean ignored;
27+
private String equalsOnlyValueProviderMethod;
2728

2829
public final Set<String> getCategories()
2930
{
@@ -54,5 +55,17 @@ public void setIgnored(final boolean ignored)
5455
{
5556
this.ignored = ignored;
5657
}
58+
59+
public boolean hasEqualsOnlyValueProviderMethod(){
60+
return this.equalsOnlyValueProviderMethod != null && !this.equalsOnlyValueProviderMethod.equals("");
61+
}
62+
63+
public void setEqualsOnlyValueProviderMethod(String equalsOnlyValueProviderMethod) {
64+
this.equalsOnlyValueProviderMethod = equalsOnlyValueProviderMethod;
65+
}
66+
67+
public String getEqualsOnlyValueProviderMethod(){
68+
return equalsOnlyValueProviderMethod;
69+
}
5770

5871
}

‎src/main/java/de/danielbechler/diff/accessor/PropertyDescriptor.java‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@ public interface PropertyDescriptor
3030
boolean isIgnored();
3131

3232
boolean isEqualsOnly();
33+
34+
boolean hasEqualsOnlyValueProviderMethod();
35+
36+
String getEqualsOnlyValueProviderMethod();
3337
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package de.danielbechler.diff.annotation;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Inherited;
5+
import java.lang.annotation.Retention;
6+
import java.lang.annotation.RetentionPolicy;
7+
import java.lang.annotation.Target;
8+
9+
@Retention(RetentionPolicy.RUNTIME)
10+
@Target(ElementType.TYPE)
11+
@Inherited
12+
@ObjectDiffAnnotation
13+
public @interface ObjectDiffEqualsOnlyValueProvidedType {
14+
public String method();
15+
}

‎src/main/java/de/danielbechler/diff/annotation/ObjectDiffProperty.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,6 @@
5151
* @return The categories for this property.
5252
*/
5353
public String[] categories() default {};
54+
55+
public String equalsOnlyValueProviderMethod() default "";
5456
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /