Skip to content

Commit 62d5b9a

Browse files
jonpereiradevJonathan Pereira
authored andcommitted
Documentation, tests and DiffBuilder.
1 parent 7ec8024 commit 62d5b9a

23 files changed

Lines changed: 589 additions & 435 deletions

src/main/java/com/github/jonpereiradev/diffobjects/DiffObjects.java

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,52 @@
44
import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata;
55
import com.github.jonpereiradev.diffobjects.strategy.DiffReflections;
66

7+
import java.util.LinkedList;
78
import java.util.List;
9+
import java.util.Objects;
810

911
/**
1012
* @author jonpereiradev@gmail.com
1113
*/
1214
public final class DiffObjects {
1315

1416
/**
15-
* Executa o builder entre o antes e o depois.
17+
* Executa o instance entre o antes e o depois.
1618
*
17-
* @param <T> tipo do objeto comparado.
18-
* @param before objeto com as informações antes da alteração.
19-
* @param after objeto com as informaçnoes depois da alteração.
20-
* @return resultado do builder.
19+
* @param <T> tipo do objeto comparado.
20+
* @param beforeState objeto com as informações antes da alteração.
21+
* @param afterState objeto com as informaçnoes depois da alteração.
22+
* @return resultado do instance.
2123
*/
22-
public static <T> DiffResults diff(T before, T after) {
23-
DiffResults result = new DiffResults();
24-
List<DiffMetadata> metadatas = DiffReflections.discover(before.getClass());
24+
public static <T> List<DiffResult<?>> diff(T beforeState, T afterState) {
25+
Objects.requireNonNull(beforeState, "Before state is required.");
26+
Objects.requireNonNull(afterState, "After state is required.");
27+
28+
List<DiffResult<?>> results = new LinkedList<>();
29+
List<DiffMetadata> metadatas = DiffReflections.mapAnnotations(beforeState.getClass());
2530

2631
for (DiffMetadata metadata : metadatas) {
27-
result.getResults().add(metadata.getStrategy().diff(before, after, metadata));
32+
results.add(metadata.getStrategy().diff(beforeState, afterState, metadata));
2833
}
2934

30-
return result;
35+
return results;
3136
}
3237

3338
/**
34-
* Verifica se os objetos são iguais no builder.
39+
* Verifica se os objetos são iguais no instance.
3540
*
36-
* @param <T> tipo do objeto comparado.
37-
* @param before objeto com as informações antes da alteração.
38-
* @param after objeto com as informações depois da alteração.
39-
* @return resultado do builder.
41+
* @param <T> tipo do objeto comparado.
42+
* @param beforeState objeto com as informações antes da alteração.
43+
* @param afterState objeto com as informações depois da alteração.
44+
* @return resultado do instance.
4045
*/
41-
public static <T> boolean isEquals(T before, T after) {
42-
List<DiffMetadata> metadatas = DiffReflections.discover(before.getClass());
46+
public static <T> boolean isEquals(T beforeState, T afterState) {
47+
Objects.requireNonNull(beforeState, "Before state is required.");
48+
Objects.requireNonNull(afterState, "After state is required.");
49+
List<DiffMetadata> metadatas = DiffReflections.mapAnnotations(beforeState.getClass());
4350

4451
for (DiffMetadata metadata : metadatas) {
45-
DiffResult<T> result = metadata.getStrategy().diff(before, after, metadata);
52+
DiffResult<T> result = metadata.getStrategy().diff(beforeState, afterState, metadata);
4653

4754
if (!result.isEquals()) {
4855
return false;
@@ -53,34 +60,42 @@ public static <T> boolean isEquals(T before, T after) {
5360
}
5461

5562
/**
56-
* Executa o builder entre o antes e o depois.
63+
* Executa o instance entre o antes e o depois.
5764
*
58-
* @param <T> tipo do objeto comparado.
59-
* @param before objeto com as informações antes da alteração.
60-
* @param after objeto com as informaçnoes depois da alteração.
61-
* @return resultado do builder.
65+
* @param <T> tipo do objeto comparado.
66+
* @param beforeState objeto com as informações antes da alteração.
67+
* @param afterState objeto com as informaçnoes depois da alteração.
68+
* @return resultado do instance.
6269
*/
63-
public static <T> DiffResults diff(T before, T after, DiffConfigurationBuilder configuration) {
64-
DiffResults result = new DiffResults();
70+
public static <T> List<DiffResult<?>> diff(T beforeState, T afterState, DiffConfigurationBuilder configuration) {
71+
Objects.requireNonNull(beforeState, "Before state is required.");
72+
Objects.requireNonNull(afterState, "After state is required.");
73+
Objects.requireNonNull(configuration, "Configuration is required.");
74+
75+
List<DiffResult<?>> results = new LinkedList<>();
6576

66-
for (DiffMetadata metadata : configuration.getConfigurations()) {
67-
result.getResults().add(metadata.getStrategy().diff(before, after, metadata));
77+
for (DiffMetadata metadata : configuration.build()) {
78+
results.add(metadata.getStrategy().diff(beforeState, afterState, metadata));
6879
}
6980

70-
return result;
81+
return results;
7182
}
7283

7384
/**
74-
* Verifica se os objetos são iguais no builder.
85+
* Verifica se os objetos são iguais no instance.
7586
*
76-
* @param <T> tipo do objeto comparado.
77-
* @param before objeto com as informações antes da alteração.
78-
* @param after objeto com as informações depois da alteração.
79-
* @return resultado do builder.
87+
* @param <T> tipo do objeto comparado.
88+
* @param beforeState objeto com as informações antes da alteração.
89+
* @param afterState objeto com as informações depois da alteração.
90+
* @return resultado do instance.
8091
*/
81-
public static <T> boolean isEquals(T before, T after, DiffConfigurationBuilder configuration) {
82-
for (DiffMetadata metadata : configuration.getConfigurations()) {
83-
DiffResult<T> result = metadata.getStrategy().diff(before, after, metadata);
92+
public static <T> boolean isEquals(T beforeState, T afterState, DiffConfigurationBuilder configuration) {
93+
Objects.requireNonNull(beforeState, "Before state is required.");
94+
Objects.requireNonNull(afterState, "After state is required.");
95+
Objects.requireNonNull(configuration, "Configuration is required.");
96+
97+
for (DiffMetadata metadata : configuration.build()) {
98+
DiffResult<T> result = metadata.getStrategy().diff(beforeState, afterState, metadata);
8499

85100
if (!result.isEquals()) {
86101
return false;

src/main/java/com/github/jonpereiradev/diffobjects/annotation/Diff.java renamed to src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
@Retention(RetentionPolicy.RUNTIME)
1616
@Target({ElementType.METHOD, ElementType.TYPE})
17-
public @interface Diff {
17+
public @interface DiffMapping {
1818

1919
/**
2020
* Defines the property that will be evaluated for equality. It can be nested property like user.address.id.

src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffGroup.java renamed to src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMappings.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
*/
1111
@Retention(RetentionPolicy.RUNTIME)
1212
@Target({ElementType.FIELD, ElementType.METHOD})
13-
public @interface DiffGroup {
13+
public @interface DiffMappings {
1414

15-
Diff[] value();
15+
DiffMapping[] value();
1616

1717
}

src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffStrategy.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilder.java

Lines changed: 90 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55
import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType;
66
import org.apache.commons.lang.StringUtils;
77

8+
import java.lang.reflect.Field;
89
import java.lang.reflect.Method;
9-
import java.util.Collection;
10-
import java.util.LinkedList;
11-
import java.util.List;
12-
10+
import java.util.*;
11+
12+
/**
13+
* Responsible to map a class and fields to be able to generate diffs.
14+
*
15+
* @author jonpereiradev@gmail.com
16+
* @see DiffInstanceBuilder
17+
* @see DiffMappingBuilder
18+
* @see DiffConfigurationBuilder
19+
*/
1320
public final class DiffBuilder implements DiffInstanceBuilder, DiffMappingBuilder, DiffConfigurationBuilder {
1421

1522
private final Class<?> classMap;
@@ -20,20 +27,69 @@ private DiffBuilder(Class<?> classMap) {
2027
this.metadatas = new LinkedList<>();
2128
}
2229

23-
public static DiffInstanceBuilder map(Class<?> classMap) {
24-
return new DiffBuilder(classMap);
30+
/**
31+
* Creates a diff instance instance to map the diff elements of a class.
32+
*
33+
* @param clazz the class that will be registry to make diffs.
34+
* @return the diff instance instance.
35+
*/
36+
public static DiffInstanceBuilder map(Class<?> clazz) {
37+
Objects.requireNonNull(clazz, "Class is required.");
38+
return new DiffBuilder(clazz);
2539
}
2640

41+
/**
42+
* Gets the mapping instance to registry the fields used in the diff.
43+
*
44+
* @return a mapping instance instance.
45+
*/
2746
@Override
2847
public DiffMappingBuilder mapper() {
2948
return this;
3049
}
3150

51+
/**
52+
* Maps all the field of a class.
53+
*
54+
* @return the instance instance responsible for this mapping.
55+
*/
56+
@Override
57+
public DiffInstanceBuilder mappingAll() {
58+
Class<?> clazz = classMap;
59+
60+
if (!metadatas.isEmpty()) {
61+
throw new IllegalStateException("The mappingAll cannot be used after a mapping(field) call.");
62+
}
63+
64+
while (clazz != null && !clazz.equals(Object.class)) {
65+
for (Field parentField : clazz.getDeclaredFields()) {
66+
mapping(parentField.getName());
67+
}
68+
69+
clazz = clazz.getSuperclass();
70+
}
71+
72+
return this;
73+
}
74+
75+
/**
76+
* Maps the getter of the field for the class.
77+
*
78+
* @param field name of the field that will me used to find the getter method.
79+
* @return the instance of this mapping instance.
80+
*/
3281
@Override
3382
public DiffMappingBuilder mapping(String field) {
3483
return mapping(field, StringUtils.EMPTY);
3584
}
3685

86+
/**
87+
* Maps the getter of the field for the class with the value property to allow deep diff.
88+
*
89+
* @param field name of the field that will me used to find the getter method.
90+
* @param value the nested property of the object to make the diff.
91+
* @return the instance of this mapping instance.
92+
*/
3793
@Override
3894
public DiffMappingBuilder mapping(String field, String value) {
3995
Method method = DiffReflections.discoverGetter(classMap, field);
@@ -43,31 +99,52 @@ public DiffMappingBuilder mapping(String field, String value) {
4399
throw new IllegalArgumentException("Method " + field + " not found in class " + classMap.getName());
44100
}
45101

46-
if (value != null && value.split("\\.").length > 1) {
102+
if (value != null && !value.isEmpty()) {
47103
diffStrategyType = DiffStrategyType.DEEP;
48104
}
49105

50-
if (method.getReturnType().isAssignableFrom(Collection.class)) {
106+
if (Collection.class.isAssignableFrom(method.getReturnType())) {
51107
diffStrategyType = DiffStrategyType.COLLECTION;
52108
}
53109

54-
metadatas.add(new DiffMetadata(value, method, diffStrategyType));
110+
DiffMetadata diffMetadata = new DiffMetadata(value, method, diffStrategyType);
111+
112+
if (metadatas.contains(diffMetadata)) {
113+
throw new IllegalStateException("Field \"" + field + "\" already mapped in this builder.");
114+
}
115+
116+
metadatas.add(diffMetadata);
55117

56118
return this;
57119
}
58120

121+
/**
122+
* Returns to the instance instance to allow the fluent interface.
123+
*
124+
* @return the instance instance responsible for this mapping.
125+
*/
59126
@Override
60-
public DiffInstanceBuilder builder() {
127+
public DiffInstanceBuilder instance() {
61128
return this;
62129
}
63130

131+
/**
132+
* Gets the configuration instance to get the configuration generated by this instance instance.
133+
*
134+
* @return a configuration instance instance.
135+
*/
64136
@Override
65-
public DiffConfigurationBuilder getConfiguration() {
137+
public DiffConfigurationBuilder configuration() {
66138
return this;
67139
}
68140

141+
/**
142+
* Gets the configuration for the instance instance.
143+
*
144+
* @return the metadata generated by the instance instance.
145+
*/
69146
@Override
70-
public List<DiffMetadata> getConfigurations() {
71-
return metadatas;
147+
public List<DiffMetadata> build() {
148+
return Collections.unmodifiableList(metadatas);
72149
}
73150
}

src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationBuilder.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,20 @@
44

55
import java.util.List;
66

7+
/**
8+
* Responsible for generate the configuration of the instance.
9+
*
10+
* @see DiffBuilder
11+
* @see DiffInstanceBuilder
12+
* @see DiffMappingBuilder
13+
*/
714
public interface DiffConfigurationBuilder {
815

9-
List<DiffMetadata> getConfigurations();
16+
/**
17+
* Gets the configuration for the instance instance.
18+
*
19+
* @return the metadata generated by the instance instance.
20+
*/
21+
List<DiffMetadata> build();
1022

1123
}
Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
package com.github.jonpereiradev.diffobjects.builder;
22

3-
interface DiffInstanceBuilder {
3+
/**
4+
* Builder with the methods of a instance instance.
5+
*
6+
* @author jonpereiradev@gmail.com
7+
* @see DiffBuilder
8+
* @see DiffMappingBuilder
9+
* @see DiffConfigurationBuilder
10+
*/
11+
public interface DiffInstanceBuilder {
412

13+
/**
14+
* Gets the mapping instance to registry the fields used in the diff.
15+
*
16+
* @return a mapping instance instance.
17+
*/
518
DiffMappingBuilder mapper();
619

7-
DiffConfigurationBuilder getConfiguration();
20+
/**
21+
* Gets the configuration instance to get the configuration generated by this instance instance.
22+
*
23+
* @return a configuration instance instance.
24+
*/
25+
DiffConfigurationBuilder configuration();
826

927
}
1028

0 commit comments

Comments
 (0)