diff --git a/README.md b/README.md index b2d9955..55f238e 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ this project in two ways: com.github.jonpereiradev diff-objects - 1.1.0 + 1.3.0 ``` @@ -48,24 +48,26 @@ public class Email { ``` ```java +import com.github.jonpereiradev.diffobjects.DiffConfig; + public class Main { - + public static void main(String[] args) { User u1 = new User("user1", "123456", LocalDate.now().minusDays(1), true); User u2 = new User("user2", "12345678", LocalDate.now(), true); - + u1.getEmails().add(new Email("user@gmail.com", true)); u2.getEmails().add(new Email("user@gmail.com", false)); - - DiffConfiguration configuration = DiffBuilder - .map(User.class) - .mapping("login") - .mapping("password") - .mapping("emails", "description") - .configuration(); - + + DiffConfig configuration = DiffBuilder + .map(User.class) + .mapping("login") + .mapping("password") + .mapping("emails", "description") + .configuration(); + List diffs = DiffObjects.forClass(User.class).diff(u1, u2, configuration); - + for (DiffResult diff : diffs) { if (!diff.isEquals()) { System.out.println("Field: " + diff.getProperties().get("field")); diff --git a/pom.xml b/pom.xml index 6b402c3..47f796f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.jonpereiradev diff-objects - 1.2.0 + 1.3.0 jar ${project.groupId}:${project.artifactId} API to compare the difference between two objects diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfig.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfig.java new file mode 100644 index 0000000..c818144 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfig.java @@ -0,0 +1,25 @@ +package com.github.jonpereiradev.diffobjects; + + +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; + +import java.util.List; + + +/** + * Contract of the diff config object that maps the properties being check for diff. + * + * @author Jonathan Pereira + * @version 1.2.0 + * @since 1.0.0 + */ +public interface DiffConfig { + + /** + * Build the configuration for the instance. + * + * @return the metadata generated by the instance. + */ + List build(); + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfigImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfigImpl.java new file mode 100644 index 0000000..e01bc8c --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffConfigImpl.java @@ -0,0 +1,60 @@ +package com.github.jonpereiradev.diffobjects; + + +import com.github.jonpereiradev.diffobjects.annotation.DiffOrder; +import com.github.jonpereiradev.diffobjects.builder.DiffBuilderContext; +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + + +/** + * Responsible for generate the configuration of the instance. + * + * @author Jonathan Pereira + * @since 1.0.0 + */ + +public final class DiffConfigImpl implements DiffConfig { + + private final DiffBuilderContext context; + private final List metadataList; + + public DiffConfigImpl(DiffBuilderContext context) { + this.context = context; + this.metadataList = new ArrayList<>(context.getMetadataMap().size()); + } + + /** + * Gets the configuration for the instance. + * + * @return the metadata generated by the instance. + */ + @Override + public List build() { + if (metadataList.isEmpty()) { + boolean sortable = false; + + for (Map.Entry entry : context.getMetadataMap().entrySet()) { + DiffOrder annotation = entry.getValue().getMethod().getAnnotation(DiffOrder.class); + + if (annotation != null) { + entry.getValue().setOrder(annotation.value()); + sortable = true; + } + + metadataList.add(entry.getValue()); + } + + if (sortable) { + Collections.sort(metadataList); + } + } + + return metadataList; + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffException.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffException.java index 64a2aa1..421787d 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/DiffException.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffException.java @@ -12,4 +12,5 @@ public class DiffException extends RuntimeException { public DiffException(String message) { super(message); } + } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjects.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjects.java index 553aafc..df45681 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjects.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjects.java @@ -1,35 +1,21 @@ package com.github.jonpereiradev.diffobjects; -import com.github.jonpereiradev.diffobjects.builder.DiffConfiguration; -import com.github.jonpereiradev.diffobjects.builder.DiffReflections; import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; -import com.github.jonpereiradev.diffobjects.strategy.DiffStrategy; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; /** - * Responsible for execute the diff between two objects. + * Responsible for check the difference between two objects. * - * @param type of object been compared. + * @param type of object being compared. * * @author Jonathan Pereira + * @see DiffObjectsImpl * @since 1.0.0 */ -public final class DiffObjects { - - private final DiffConfiguration annotations; - - private DiffObjects(Class clazz) { - this.annotations = DiffReflections.mapAnnotations(clazz); - } +public interface DiffObjects { /** * Creates a DiffObjects for a specific class. @@ -39,236 +25,105 @@ private DiffObjects(Class clazz) { * * @return the DiffObjects for the class. */ - public static DiffObjects forClass(Class clazz) { - return new DiffObjects<>(clazz); + static DiffObjects forClass(Class clazz) { + return new DiffObjectsImpl<>(clazz); } /** - * Execute the diff between two objects using annotations. + * Execute the diff between two objects. + *

+ * If the class supports annotation diff configuration, it's used in the diff context. + * Otherwise, makes the diff using all fields of the class. * - * @param expected the expected object state to compare with current object. - * @param current the current object state to compare with expected object. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. * - * @return a list with the results of the diff. + * @return the diff result with all configured fields checked. */ - public List diff(T expected, T current) { - Objects.requireNonNull(expected, "Expected state is required."); - Objects.requireNonNull(current, "Current state is required."); - - return diff(expected, current, annotations); - } + DiffResults diff(T expected, T current); /** * Execute the diff between two objects using a configuration. * - * @param expected the expected object state to compare with after object. - * @param current the current object state to compare with before object. - * @param configuration the configuration of the diff. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param config the diff configuration metadata. * - * @return a list with the results of the diff. + * @return the diff result with all configured fields checked. */ - public List diff(T expected, T current, DiffConfiguration configuration) { - Objects.requireNonNull(expected, "Expected state is required."); - Objects.requireNonNull(current, "Current state is required."); - Objects.requireNonNull(configuration, "Configuration is required."); - - List metadatas = configuration.build(); - List results = new ArrayList<>(metadatas.size()); - - for (DiffMetadata metadata : metadatas) { - DiffStrategy strategy = metadata.getStrategy(); - DiffResult diff = strategy.diff(expected, current, metadata); - - diff.setProperties(Collections.unmodifiableMap(metadata.getProperties())); - - results.add(diff); - } - - return results; - } + DiffResults diff(T expected, T current, DiffConfig config); /** - * Execute the diff between two objects using annotations. + * Execute the diff between two collection of objects. + *

+ * If the class supports annotation diff configuration, it's used in the diff context. + * Otherwise, makes the diff using all fields of the class. * - * @param expected the expected object state to compare with after object. - * @param current the current object state to compare with before object. - * @param matcher the matcher that will define how an object from list is equals to other. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param matcher compares if one object from the expected collection is representable by one in the current. * - * @return a list with the results of the diff. + * @return the diff result with all configured fields checked. */ - public List diff(Collection expected, Collection current, DiffComparator matcher) { - Objects.requireNonNull(expected, "Expected state is required."); - Objects.requireNonNull(current, "Current state is required."); - return diff(expected, current, annotations, matcher); - } + DiffResults diff(Collection expected, Collection current, DiffComparator matcher); /** - * Execute the diff between two objects using a configuration. + * Execute the diff between two collection of objects using the diff config metadata. * - * @param expectedCollection the expected object state to compare with after object. - * @param currentCollection the current object state to compare with before object. - * @param configuration the configuration of the diff. - * @param matcher the matcher that will define how an object from list is equals to other. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param config the diff configuration metadata. + * @param matcher compares if one object from the expected collection is representable by one in the current. * - * @return a list with the results of the diff. + * @return the diff result with all configured fields checked. */ - public List diff( - Collection expectedCollection, - Collection currentCollection, - DiffConfiguration configuration, - DiffComparator matcher) { - Objects.requireNonNull(expectedCollection, "Before state is required."); - Objects.requireNonNull(currentCollection, "After state is required."); - Objects.requireNonNull(configuration, "Configuration is required."); - - List results = new ArrayList<>(); - - for (T expected : expectedCollection) { - Stream stream = currentCollection.stream().filter((current) -> matcher.isEquals(expected, current)); - T after = stream.findFirst().orElse(null); - - // check the elements that exist on expectedCollection and not exists on currentCollection - if (after == null) { - results.add(new DiffResult(expected, null, false)); - continue; - } - - boolean equals = true; - - // check the elements that exist on both collections - for (DiffMetadata metadata : configuration.build()) { - DiffStrategy strategy = metadata.getStrategy(); - DiffResult diff = strategy.diff(expected, after, metadata); - - if (!diff.isEquals()) { - equals = false; - break; - } - } - - results.add(new DiffResult(expected, after, equals)); - } - - // check the elements that exist on currentCollection and not exists on expectedCollection - for (T current : currentCollection) { - Stream stream = expectedCollection.stream().filter((expected) -> matcher.isEquals(current, expected)); - T expected = stream.findFirst().orElse(null); - - if (expected == null) { - results.add(new DiffResult(null, current, false)); - } - } - - return results; - } + DiffResults diff(Collection expected, Collection current, DiffConfig config, DiffComparator matcher); /** - * Check if exists any difference between the two objects using annotations. + * Check if exists the expected and current state are equals. + *

+ * If the class supports annotation diff configuration, it's used in the diff context. + * Otherwise, makes the diff using all fields of the class. * - * @param expected the expected object state to compare with after object. - * @param current the current object state to compare with before object. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. * * @return {@code true} if no difference exists between the objects or {@code false} otherwise. */ - public boolean isEquals(T expected, T current) { - Objects.requireNonNull(expected, "Expected state is required."); - Objects.requireNonNull(current, "Current state is required."); - return isEquals(expected, current, annotations); - } + boolean isEquals(T expected, T current); /** - * Check if exists any difference between the two objects. + * Check if exists the expected and current state are equals. * - * @param expected the expected object state to compare with after object. - * @param current the current object state to compare with before object. - * @param configuration the configuration of the diff. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param config the diff configuration metadata. * * @return {@code true} if no difference exists between the objects or {@code false} otherwise. */ - public boolean isEquals(T expected, T current, DiffConfiguration configuration) { - Objects.requireNonNull(expected, "Before state is required."); - Objects.requireNonNull(current, "After state is required."); - Objects.requireNonNull(configuration, "Configuration is required."); - - for (DiffMetadata metadata : configuration.build()) { - DiffStrategy strategy = metadata.getStrategy(); - DiffResult result = strategy.diff(expected, current, metadata); - - if (!result.isEquals()) { - return false; - } - } - - return true; - } + boolean isEquals(T expected, T current, DiffConfig config); /** - * Check if exists any difference between the two objects using annotations. + * Check if exists the expected and current state are equals. * - * @param expectedCollection the expected object state to compare with after object. - * @param currentCollection the current object state to compare with before object. - * @param matcher the matcher that will define how an object from list is equals to other. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param matcher compares if one object from the expected collection is representable by one in the current. * * @return {@code true} if no difference exists between the objects or {@code false} otherwise. */ - public boolean isEquals( - Collection expectedCollection, - Collection currentCollection, - DiffComparator matcher) { - Objects.requireNonNull(expectedCollection, "Expected Collection state is required."); - Objects.requireNonNull(currentCollection, "Current Collection state is required."); - return isEquals(expectedCollection, currentCollection, annotations, matcher); - } + boolean isEquals(Collection expected, Collection current, DiffComparator matcher); /** - * Check if exists any difference between the two objects. + * Check if exists the expected and current state are equals. * - * @param expectedCollection the expected object state to compare with after object. - * @param currentCollection the current object state to compare with before object. - * @param configuration the configuration of the diff. - * @param matcher the matcher that will define how an object from list is equals to other. + * @param expected the expected object state to check for diff. + * @param current the current object state to check for diff. + * @param config the diff configuration metadata. + * @param matcher compares if one object from the expected collection is representable by one in the current. * * @return {@code true} if no difference exists between the objects or {@code false} otherwise. */ - public boolean isEquals( - Collection expectedCollection, - Collection currentCollection, - DiffConfiguration configuration, - DiffComparator matcher) { - Objects.requireNonNull(expectedCollection, "Before state is required."); - Objects.requireNonNull(currentCollection, "After state is required."); - Objects.requireNonNull(configuration, "Configuration is required."); - - List currentCollectionCopy = new ArrayList<>(currentCollection); - - for (T expected : expectedCollection) { - Stream stream = currentCollection.stream().filter((current) -> matcher.isEquals(expected, current)); - T current = stream.findFirst().orElse(null); - - // check the elements that exist on expectedCollection and not exists on currentCollection - if (current == null) { - return false; - } - - currentCollectionCopy.remove(current); - - // check the elements that exist on both collections - if (!isEquals(expected, current, configuration)) { - return false; - } - } - - // check the elements that exist on currentCollection and not exists on expectedCollection - for (T current : currentCollectionCopy) { - Stream stream = expectedCollection.stream().filter((expected) -> matcher.isEquals(current, expected)); - T expected = stream.findFirst().orElse(null); - - if (expected == null) { - return false; - } - } - - return true; - } + boolean isEquals(Collection expected, Collection current, DiffConfig config, DiffComparator matcher); } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjectsImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjectsImpl.java new file mode 100644 index 0000000..43bfd08 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffObjectsImpl.java @@ -0,0 +1,240 @@ +package com.github.jonpereiradev.diffobjects; + + +import com.github.jonpereiradev.diffobjects.builder.DiffConfigBuilder; +import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; +import com.github.jonpereiradev.diffobjects.strategy.DiffStrategy; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.stream.Stream; + +import static java.util.Objects.requireNonNull; + + +/** + * Responsible for check the difference between two objects. + * + * @param type of object being compared. + * + * @author Jonathan Pereira + * @since 1.0.0 + */ +final class DiffObjectsImpl implements DiffObjects { + + private final Class ofType; + + DiffObjectsImpl(Class ofType) { + this.ofType = ofType; + } + + /** + * {@inheritDoc} + */ + @Override + public DiffResults diff(T expected, T current) { + requireNonNull(expected, "Expected state is required"); + requireNonNull(current, "Current state is required"); + + DiffConfig config = createDiffConfig(); + return diff(expected, current, config); + } + + /** + * {@inheritDoc} + */ + @Override + public DiffResults diff(T expected, T current, DiffConfig config) { + requireNonNull(expected, "Expected state is required"); + requireNonNull(current, "Current state is required"); + requireNonNull(config, "Config is required"); + + List metadata = config.build(); + List results = new ArrayList<>(metadata.size()); + + for (DiffMetadata value : metadata) { + DiffStrategy strategy = value.getStrategy(); + DiffResult diff = strategy.diff(expected, current, value); + results.add(diff); + } + + return new DiffResultsImpl(results); + } + + /** + * {@inheritDoc} + */ + @Override + public DiffResults diff(Collection expected, Collection current, DiffComparator matcher) { + requireNonNull(expected, "Expected state is required"); + requireNonNull(current, "Current state is required"); + + DiffConfig config = createDiffConfig(); + return diff(expected, current, config, matcher); + } + + /** + * {@inheritDoc} + */ + @Override + public DiffResults diff( + Collection expectedCollection, + Collection currentCollection, + DiffConfig config, + DiffComparator matcher) { + + requireNonNull(expectedCollection, "Expected state is required"); + requireNonNull(currentCollection, "Current state is required"); + requireNonNull(config, "Config is required"); + + List results = new ArrayList<>(); + List currentCollectionCopy = new ArrayList<>(currentCollection); + List metadataList = config.build(); + DiffResult result; + + for (T expected : expectedCollection) { + Stream stream = currentCollection.stream().filter((current) -> matcher.isEquals(expected, current)); + T current = stream.findFirst().orElse(null); + + // check the elements that exist on expectedCollection and not exists on currentCollection + if (current == null) { + result = DiffResult.forValue(expected, null, false); + results.add(result); + continue; + } + + currentCollectionCopy.remove(current); + + boolean equals = true; + + // check the elements that exist on both collections + for (DiffMetadata metadata : metadataList) { + DiffStrategy strategy = metadata.getStrategy(); + DiffResult diff = strategy.diff(expected, current, metadata); + + if (!diff.isEquals()) { + equals = false; + break; + } + } + + result = DiffResult.forValue(expected, current, equals); + results.add(result); + } + + // check the elements that exist on currentCollection but not exists on expectedCollection + for (T current : currentCollectionCopy) { + Stream stream = expectedCollection.stream().filter((expected) -> matcher.isEquals(current, expected)); + T expected = stream.findFirst().orElse(null); + + if (expected == null) { + result = DiffResult.forValue(null, current, false); + results.add(result); + } + } + + return new DiffResultsImpl(results); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEquals(T expected, T current) { + requireNonNull(expected, "Expected state is required"); + requireNonNull(current, "Current state is required"); + + DiffConfig config = createDiffConfig(); + return isEquals(expected, current, config); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEquals(T expected, T current, DiffConfig config) { + requireNonNull(expected, "Expected state is required"); + requireNonNull(current, "Current state is required"); + requireNonNull(config, "Config is required"); + + for (DiffMetadata metadata : config.build()) { + DiffStrategy strategy = metadata.getStrategy(); + DiffResult result = strategy.diff(expected, current, metadata); + + if (!result.isEquals()) { + return false; + } + } + + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEquals( + Collection expectedCollection, + Collection currentCollection, + DiffComparator matcher) { + + requireNonNull(expectedCollection, "Expected Collection state is required."); + requireNonNull(currentCollection, "Current Collection state is required."); + + DiffConfig config = createDiffConfig(); + return isEquals(expectedCollection, currentCollection, config, matcher); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isEquals( + Collection expectedCollection, + Collection currentCollection, + DiffConfig config, + DiffComparator matcher) { + + requireNonNull(expectedCollection, "Expected state is required"); + requireNonNull(currentCollection, "Current state is required"); + requireNonNull(config, "Config is required"); + + List currentCollectionCopy = new ArrayList<>(currentCollection); + + for (T expected : expectedCollection) { + Stream stream = currentCollection.stream().filter((current) -> matcher.isEquals(expected, current)); + T current = stream.findFirst().orElse(null); + + // check the elements that exist on expectedCollection and not exists on currentCollection + if (current == null) { + return false; + } + + currentCollectionCopy.remove(current); + + // check the elements that exist on both collections + if (!isEquals(expected, current, config)) { + return false; + } + } + + // check the elements that exist on currentCollection and not exists on expectedCollection + for (T current : currentCollectionCopy) { + Stream stream = expectedCollection.stream().filter((expected) -> matcher.isEquals(current, expected)); + T expected = stream.findFirst().orElse(null); + + if (expected == null) { + return false; + } + } + + return true; + } + + private DiffConfig createDiffConfig() { + return DiffConfigBuilder.forClass(ofType).mapping().annotations().build(); + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffResult.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResult.java index d5a8999..e32084c 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/DiffResult.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResult.java @@ -1,46 +1,25 @@ package com.github.jonpereiradev.diffobjects; - import java.util.Map; +import static java.util.Collections.emptyMap; +import static java.util.Collections.unmodifiableMap; -/** - * Result of a diff with the before and after state. - * - * @author Jonathan Pereira - * @since 1.0.0 - */ -public final class DiffResult { - - private final Object expected; - private final Object current; - private final boolean equals; - private Map properties; +public interface DiffResult { - public DiffResult(Object expected, Object current, boolean equals) { - this.expected = expected; - this.current = current; - this.equals = equals; + static DiffResult forValue(Object expected, Object current, boolean equals) { + return new DiffResultImpl(expected, current, equals, emptyMap()); } - public Object getExpected() { - return expected; + static DiffResult forValue(Object expected, Object current, boolean equals, Map properties) { + return new DiffResultImpl(expected, current, equals, unmodifiableMap(properties)); } - public Object getCurrent() { - return current; - } + Object getExpected(); - public boolean isEquals() { - return equals; - } + Object getCurrent(); - public Map getProperties() { - return properties; - } - - void setProperties(Map properties) { - this.properties = properties; - } + boolean isEquals(); + Map getProperties(); } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultImpl.java new file mode 100644 index 0000000..e6fb00f --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultImpl.java @@ -0,0 +1,47 @@ +package com.github.jonpereiradev.diffobjects; + + +import java.util.Map; + + +/** + * Result of a diff with the before and after state. + * + * @author Jonathan Pereira + * @since 1.0.0 + */ +final class DiffResultImpl implements DiffResult { + + private final Object expected; + private final Object current; + private final boolean equals; + private final Map properties; + + DiffResultImpl(Object expected, Object current, boolean equals, Map properties) { + this.expected = expected; + this.current = current; + this.equals = equals; + this.properties = properties; + } + + @Override + public Object getExpected() { + return expected; + } + + @Override + public Object getCurrent() { + return current; + } + + @Override + public boolean isEquals() { + return equals; + } + + @Override + public Map getProperties() { + return properties; + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffResults.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResults.java new file mode 100644 index 0000000..82ffd12 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResults.java @@ -0,0 +1,39 @@ +package com.github.jonpereiradev.diffobjects; + +import java.util.Iterator; +import java.util.List; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.stream.Stream; + +public interface DiffResults extends Iterable { + + List getResults(); + + default Stream stream() { + return getResults().stream(); + } + + default boolean isEmpty() { + return getResults().isEmpty(); + } + + default int size() { + return getResults().size(); + } + + @Override + default Iterator iterator() { + return getResults().iterator(); + } + + @Override + default void forEach(Consumer action) { + getResults().forEach(action); + } + + @Override + default Spliterator spliterator() { + return getResults().spliterator(); + } +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultsImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultsImpl.java new file mode 100644 index 0000000..63fbf36 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/DiffResultsImpl.java @@ -0,0 +1,19 @@ +package com.github.jonpereiradev.diffobjects; + +import java.util.Collections; +import java.util.List; + +final class DiffResultsImpl implements DiffResults { + + private final List results; + + DiffResultsImpl(List results) { + this.results = Collections.unmodifiableList(results); + } + + @Override + public List getResults() { + return results; + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMapping.java b/src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMapping.java index affaa05..a5af481 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMapping.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/annotation/DiffMapping.java @@ -12,9 +12,9 @@ /** - * A method annotated with this will be checked for difference between two objects. When annotated on a method without - * value(), the equals method of this object will be executed. When annotated on a method with value(), the property - * will be evaluated for equality. + * A field or method annotated with this will be checked for difference between two objects. + * When annotated on a method without value(), the equals method of this object will be executed. + * When annotated on a method with value(), the property will be evaluated for equality. * * @author Jonathan Pereira * @since 1.0.0 @@ -25,7 +25,10 @@ public @interface DiffMapping { /** - * @return defines the property that will be evaluated for equality. It can be nested property like user.address.id. + * Defines the property that will be evaluated for equality. + * It can be nested property like user.address.id. + * + * @return path to the property */ String value() default ""; diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilder.java deleted file mode 100644 index b06caf7..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilder.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; - -import java.lang.reflect.Field; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; - - -/** - * Responsible to map a class and fields to be able to generate diffs. - * - * @author Jonathan Pereira - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -public final class DiffBuilder implements DiffInstanceBuilder { - - private final Class classMap; - private final Map metadatas; - - private DiffBuilder(Class classMap) { - this.classMap = classMap; - this.metadatas = new LinkedHashMap<>(); - } - - /** - * Creates a diff instance instance to map the diff elements of a class. - * - * @param the type of class the builder will create the mappings. - * @param clazz the class that will be registry to make diffs. - * - * @return the diff instance instance. - */ - public static DiffBuilder map(Class clazz) { - Objects.requireNonNull(clazz, "Class is required."); - return new DiffBuilder<>(clazz); - } - - /** - * Maps all the field of a class. - * - * @return the instance instance responsible for this mapping. - */ - @Override - public DiffMappingAllBuilder mappingAll() { - Class clazz = classMap; - - while (clazz != null && !clazz.equals(Object.class)) { - for (Field parentField : clazz.getDeclaredFields()) { - if (!metadatas.containsKey(parentField.getName())) { - mapping(parentField.getName()); - } - } - - clazz = clazz.getSuperclass(); - } - - return new DiffMappingAllBuilderImpl(metadatas); - } - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * - * @return the instance of this mapping instance. - */ - @Override - public DiffQueryMappingBuilder mapping(String field) { - return new DiffMappingBuilderImpl<>(classMap, metadatas).mapping(field); - } - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * @param fieldComparator implementation that define how two objects will be check for equality. - * - * @return the instance of this mapping. - */ - @Override - public DiffQueryMappingBuilder mapping( - String field, - DiffComparator fieldComparator) { - return new DiffMappingBuilderImpl<>(classMap, metadatas).mapping(field, fieldComparator); - } - - Map getMetadatas() { - return metadatas; - } -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderContext.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderContext.java new file mode 100644 index 0000000..4a4c287 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderContext.java @@ -0,0 +1,42 @@ +package com.github.jonpereiradev.diffobjects.builder; + +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +public class DiffBuilderContext { + + private final Class ofType; + private final Map metadata; + + public DiffBuilderContext(Class ofType) { + this.ofType = ofType; + this.metadata = new LinkedHashMap<>(); + } + + public Map getMetadataMap() { + return Collections.unmodifiableMap(metadata); + } + + public DiffMetadata get(String name) { + return metadata.get(name); + } + + public boolean containsKey(String name) { + return metadata.containsKey(name); + } + + public DiffMetadata remove(String name) { + return metadata.remove(name); + } + + public DiffMetadata put(String name, DiffMetadata diffMetadata) { + return metadata.put(name, diffMetadata); + } + + public Class getOfType() { + return ofType; + } +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilder.java new file mode 100644 index 0000000..cd4eb95 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilder.java @@ -0,0 +1,33 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import java.util.Objects; + +/** + * Diff config builder contract to create a configuration for a diff operation. + * + * @param the type of object associated to the builder. + * + * @author Jonathan Pereira + * @version 1.2.0 + * @since 1.0.0 + */ +public interface DiffConfigBuilder { + + /** + * Creates a diff builder to map the diff elements of a class. + * + * @param the type of class the builder will create the mappings. + * @param ofType the class that will be registry to make diffs. + * + * @return the diff config builder instance. + */ + static DiffConfigBuilder forClass(Class ofType) { + Objects.requireNonNull(ofType, "Class is required"); + DiffBuilderContext context = new DiffBuilderContext<>(ofType); + return new DiffConfigBuilderImpl<>(context); + } + + DiffMappingTypeBuilder mapping(); + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImpl.java new file mode 100644 index 0000000..14a91c9 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImpl.java @@ -0,0 +1,17 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +final class DiffConfigBuilderImpl implements DiffConfigBuilder { + + private final DiffBuilderContext context; + + DiffConfigBuilderImpl(DiffBuilderContext context) { + this.context = context; + } + + @Override + public DiffMappingTypeBuilder mapping() { + return new DiffMappingTypeBuilderImpl<>(context); + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfiguration.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfiguration.java deleted file mode 100644 index 977e260..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfiguration.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; - -import java.util.List; - - -/** - * Responsible for generate the configuration of the instance. - * - * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @since 1.0.0 - */ -public interface DiffConfiguration { - - /** - * Gets the configuration for the instance instance. - * - * @return the metadata generated by the instance instance. - */ - List build(); - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImpl.java deleted file mode 100644 index ae55dc8..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImpl.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.annotation.DiffOrder; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - - -/** - * Responsible for generate the configuration of the instance. - * - * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @since 1.0.0 - */ -final class DiffConfigurationImpl implements DiffConfiguration { - - private final Map metadatas; - private final List diffMetadatas; - - DiffConfigurationImpl(Map metadatas) { - this.metadatas = metadatas; - this.diffMetadatas = new ArrayList<>(metadatas.keySet().size()); - } - - /** - * Gets the configuration for the instance instance. - * - * @return the metadata generated by the instance instance. - */ - @Override - public List build() { - if (diffMetadatas.isEmpty()) { - boolean sortable = false; - - for (Map.Entry entry : metadatas.entrySet()) { - DiffOrder annotation = entry.getValue().getMethod().getAnnotation(DiffOrder.class); - - if (annotation != null) { - entry.getValue().setOrder(annotation.value()); - sortable = true; - } - - diffMetadatas.add(entry.getValue()); - } - - if (sortable) { - Collections.sort(diffMetadatas); - } - } - - return diffMetadatas; - } - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffInstanceBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffInstanceBuilder.java deleted file mode 100644 index 126bed5..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffInstanceBuilder.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; - -/** - * Builder with the methods of a instance instance. - * - * @param the type of object associated to the builder. - * - * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffMappingBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -public interface DiffInstanceBuilder { - - /** - * Maps all the field of a class. - * - * @return the instance responsible for this mapping. - */ - DiffMappingAllBuilder mappingAll(); - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * - * @return the instance of this mapping. - */ - DiffQueryMappingBuilder mapping(String field); - - /** - * Maps the getter of the field for the class. - * - * @param the type of object been mapped for the field. - * @param field name of the field that will me used to find the getter method. - * @param comparator implementation that define how two objects will be check for equality. - * - * @return the instance of this mapping. - */ - DiffQueryMappingBuilder mapping(String field, DiffComparator comparator); - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffManualMappingBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffManualMappingBuilder.java new file mode 100644 index 0000000..95e1504 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffManualMappingBuilder.java @@ -0,0 +1,34 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; + +/** + * Responsible for make available a manual mapping of fields. + * + * @author Jonathan Pereira + * @version 1.2.0 + * @since 1.0.0 + */ +public interface DiffManualMappingBuilder extends DiffMappingBuilder { + + /** + * Maps a property by name. + * + * @param name the name that identifies the property for mapping. + * + * @return instance of the mapped property. + */ + DiffManualMappingBuilder map(String name); + + /** + * Maps a property by name using a custom comparator. + * + * @param name the name that identifies the property for mapping. + * @param comparator custom comparator that checks a property for equality. + * + * @return instance of the mapped property. + */ + DiffManualMappingBuilder map(String name, DiffComparator comparator); + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilder.java deleted file mode 100644 index 42f461a..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -/** - * Builder responsible for mapping the fields of a class to create a configuration of diff. - * - * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -public interface DiffMappingAllBuilder { - - /** - * Gets the object responsible for query mappings for change. - * - * @param field the name of the field mapped in the builder. - * - * @return the instance of the builder. - */ - DiffQueryBuilder query(String field); - - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ - DiffConfiguration configuration(); - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilderImpl.java index bdd5a41..838a5ef 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilderImpl.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAllBuilderImpl.java @@ -1,47 +1,40 @@ package com.github.jonpereiradev.diffobjects.builder; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.DiffConfigImpl; -import java.util.Map; +import java.lang.reflect.Field; -/** - * Responsible to map a class and fields to be able to generate diffs. - * - * @author Jonathan Pereira - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -final class DiffMappingAllBuilderImpl implements DiffMappingAllBuilder { +final class DiffMappingAllBuilderImpl implements DiffMappingBuilder { - private final Map metadatas; + private final DiffBuilderContext context; - DiffMappingAllBuilderImpl(Map metadatas) { - this.metadatas = metadatas; + DiffMappingAllBuilderImpl(DiffBuilderContext context) { + this.context = context; + + Class ofType = context.getOfType(); + DiffManualMappingBuilder fieldMapping = new DiffMappingFieldBuilderImpl<>(context); + + while (ofType != null && !ofType.equals(Object.class)) { + for (Field parentField : ofType.getDeclaredFields()) { + if (!context.containsKey(parentField.getName())) { + fieldMapping.map(parentField.getName()); + } + } + + ofType = ofType.getSuperclass(); + } } - /** - * Finds a mapping in the builder to make operations. - * - * @param field the name of the field mapped in the builder. - * - * @return the instance of this mapping. - */ @Override - public DiffQueryBuilder query(String field) { - return new DiffQueryBuilderImpl(field, metadatas, this); + public DiffQueryBuilder query() { + return new DiffQueryBuilderImpl<>(context); } - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ @Override - public DiffConfiguration configuration() { - return new DiffConfigurationImpl(metadatas); + public DiffConfig build() { + return new DiffConfigImpl(context); } } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAnnotationsBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAnnotationsBuilderImpl.java new file mode 100644 index 0000000..0ea331c --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingAnnotationsBuilderImpl.java @@ -0,0 +1,101 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.DiffConfigImpl; +import com.github.jonpereiradev.diffobjects.annotation.DiffIgnore; +import com.github.jonpereiradev.diffobjects.annotation.DiffMapping; +import com.github.jonpereiradev.diffobjects.annotation.DiffMappings; +import com.github.jonpereiradev.diffobjects.annotation.DiffProperty; +import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; + +import java.lang.reflect.Method; +import java.util.Collection; + + +final class DiffMappingAnnotationsBuilderImpl implements DiffMappingBuilder { + + private final DiffBuilderContext context; + + DiffMappingAnnotationsBuilderImpl(DiffBuilderContext context) { + this.context = context; + + if (context.getOfType().isAnnotationPresent(DiffMappings.class)) { + mapAllMethods(); + } else { + mapAnnotationsMethods(); + } + } + + /** + * Map all methods from a class for diff. + */ + private void mapAllMethods() { + DiffManualMappingBuilder mapping = new DiffMappingFieldBuilderImpl<>(context); + + for (Method method : context.getOfType().getMethods()) { + if (!method.isAnnotationPresent(DiffIgnore.class)) { + mapping.map(method.getName()); + } + } + } + + /** + * Map all method annotations from a class. + */ + private void mapAnnotationsMethods() { + DiffManualMappingBuilder mapping = new DiffMappingFieldBuilderImpl<>(context); + + for (Method method : context.getOfType().getMethods()) { + if (method.isAnnotationPresent(DiffMapping.class)) { + mapping(mapping, method, method.getAnnotation(DiffMapping.class)); + } else if (method.isAnnotationPresent(DiffMappings.class)) { + for (DiffMapping diffMapping : method.getAnnotation(DiffMappings.class).value()) { + mapping(mapping, method, diffMapping); + } + } + } + } + + private static void mapping(DiffManualMappingBuilder builder, Method method, DiffMapping diffMapping) { + if (Collection.class.isAssignableFrom(method.getReturnType())) { + mappingCollection(builder, method, diffMapping); + } else { + mappingField(builder, method, diffMapping); + } + } + + private static void mappingField(DiffManualMappingBuilder builder, Method method, DiffMapping diffMapping) { + String field = method.getName(); + DiffComparator comparator = DiffReflections.newInstance(diffMapping.comparator()); + + if (!diffMapping.value().isEmpty()) { + field += "." + diffMapping.value(); + } + + DiffQueryFoundBuilder query = builder.map(field, comparator).query().find(field); + + for (DiffProperty diffProperty : diffMapping.properties()) { + query.property(diffProperty.key(), diffProperty.value()); + } + } + + private static void mappingCollection(DiffManualMappingBuilder builder, Method method, DiffMapping diffMapping) { + DiffComparator comparator = DiffReflections.newInstance(diffMapping.comparator()); + DiffManualMappingBuilder collectionBuilder = builder.map(method.getName(), comparator); + + if (!diffMapping.value().isEmpty()) { + collectionBuilder.map(method.getName() + "." + diffMapping.value(), comparator); + } + } + + @Override + public DiffQueryBuilder query() { + return new DiffQueryBuilderImpl<>(context); + } + + @Override + public DiffConfig build() { + return new DiffConfigImpl(context); + } +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilder.java index 8a73a2a..b1cfa03 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilder.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilder.java @@ -1,44 +1,29 @@ package com.github.jonpereiradev.diffobjects.builder; -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; +import com.github.jonpereiradev.diffobjects.DiffConfig; /** - * Builder responsible for mapping the fields of a class to create a configuration of diff. + * Contract of a class with mapped fields for final operations. * * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffConfiguration + * @version 1.2.0 * @since 1.0.0 */ public interface DiffMappingBuilder { /** - * Maps the getter of the field for the class. + * Allows the change of the current mapped fields. * - * @param field name of the field that will me used to find the getter method. - * - * @return the instance of this mapping. - */ - DiffQueryMappingBuilder mapping(String field); - - /** - * Maps the getter of the field for the class. - * - * @param the type of object been mapped for the field. - * @param field name of the field that will me used to find the getter method. - * @param fieldComparator implementation that define how two objects will be check for equality. - * - * @return the instance of this mapping. + * @return instance for search mapped fields for mutable operations. */ - DiffQueryMappingBuilder mapping(String field, DiffComparator fieldComparator); + DiffQueryBuilder query(); /** - * Gets the configuration instance to get the configuration generated by this instance instance. + * Constructs the final configuration object with the mapped fields. * - * @return a configuration instance instance. + * @return instance of the configuration for the mapped fields. */ - DiffConfiguration configuration(); + DiffConfig build(); } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImpl.java deleted file mode 100644 index cfc3fc4..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImpl.java +++ /dev/null @@ -1,119 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; -import com.github.jonpereiradev.diffobjects.comparator.EqualsComparator; -import com.github.jonpereiradev.diffobjects.comparator.IndexComparator; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; -import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType; -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; - - -/** - * Responsible to map a class and fields to be able to generate diffs. - * - * @author Jonathan Pereira - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -final class DiffMappingBuilderImpl implements DiffMappingBuilder { - - private static final String REGEX_PROPERTY_SEPARATOR = "\\."; - - private final Class classMap; - private final Map metadatas; - - DiffMappingBuilderImpl(Class classMap, Map metadatas) { - this.classMap = classMap; - this.metadatas = metadatas; - } - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * - * @return the instance of this mapping instance. - */ - @Override - public DiffQueryMappingBuilder mapping(String field) { - String[] fields = field.split(REGEX_PROPERTY_SEPARATOR); - Method method = DiffReflections.discoverGetter(classMap, fields[0]); - - if (Collection.class.isAssignableFrom(method.getReturnType()) && fields.length == 1) { - return mapping(field, new IndexComparator<>()); - } - - return mapping(field, new EqualsComparator<>()); - } - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * @param fieldComparator implementation that define how two objects will be check for equality. - * - * @return the instance of this mapping. - */ - @Override - public DiffQueryMappingBuilder mapping( - String field, - DiffComparator fieldComparator) { - Objects.requireNonNull(field, "Field name is required."); - - String nestedFields = StringUtils.EMPTY; - String[] fields = field.split(REGEX_PROPERTY_SEPARATOR); - Method method = DiffReflections.discoverGetter(classMap, fields[0]); - DiffStrategyType diffStrategyType = DiffStrategyType.SINGLE; - - if (fields.length > 1) { - diffStrategyType = DiffStrategyType.NESTED; - nestedFields = field.substring(field.indexOf(".") + 1); - } - - boolean isCollectionType = Collection.class.isAssignableFrom(method.getReturnType()); - - if (isCollectionType) { - diffStrategyType = DiffStrategyType.COLLECTION; - } - - DiffMetadata diffMetadata = new DiffMetadata( - nestedFields, - method, - diffStrategyType, - fieldComparator - ); - - diffMetadata.getProperties().put("field", field); - - if (isCollectionType && !nestedFields.isEmpty()) { - metadatas.remove(fields[0]); - } - - metadatas.put(field, diffMetadata); - - return new DiffQueryMappingBuilderImpl<>(diffMetadata, this); - } - - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ - @Override - public DiffConfiguration configuration() { - return new DiffConfigurationImpl(metadatas); - } - - Map getMetadatas() { - return metadatas; - } - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingFieldBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingFieldBuilderImpl.java new file mode 100644 index 0000000..9da1365 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingFieldBuilderImpl.java @@ -0,0 +1,87 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.DiffConfigImpl; +import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; +import com.github.jonpereiradev.diffobjects.comparator.EqualsComparator; +import com.github.jonpereiradev.diffobjects.comparator.IndexComparator; +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; +import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Objects; + + +final class DiffMappingFieldBuilderImpl implements DiffManualMappingBuilder { + + private static final String REGEX_PROPERTY_SEPARATOR = "\\."; + + private final DiffBuilderContext context; + + DiffMappingFieldBuilderImpl(DiffBuilderContext context) { + this.context = context; + } + + @Override + public DiffManualMappingBuilder map(String name) { + String[] fields = name.split(REGEX_PROPERTY_SEPARATOR); + Method method = DiffReflections.discoverGetter(context.getOfType(), fields[0]); + + if (Collection.class.isAssignableFrom(method.getReturnType()) && fields.length == 1) { + return map(name, new IndexComparator<>()); + } + + return map(name, new EqualsComparator<>()); + } + + @Override + public DiffManualMappingBuilder map(String name, DiffComparator comparator) { + Objects.requireNonNull(name, "Field name is required."); + + String nestedFields = StringUtils.EMPTY; + String[] fields = name.split(REGEX_PROPERTY_SEPARATOR); + Method method = DiffReflections.discoverGetter(context.getOfType(), fields[0]); + DiffStrategyType diffStrategyType = DiffStrategyType.SINGLE; + + if (fields.length > 1) { + diffStrategyType = DiffStrategyType.NESTED; + nestedFields = name.substring(name.indexOf(".") + 1); + } + + boolean isCollectionType = Collection.class.isAssignableFrom(method.getReturnType()); + + if (isCollectionType) { + diffStrategyType = DiffStrategyType.COLLECTION; + } + + DiffMetadata diffMetadata = new DiffMetadata( + nestedFields, + method, + diffStrategyType, + comparator + ); + + diffMetadata.getProperties().put("field", name); + + if (isCollectionType && !nestedFields.isEmpty()) { + context.remove(fields[0]); + } + + context.put(name, diffMetadata); + + return this; + } + + @Override + public DiffQueryBuilder query() { + return new DiffQueryBuilderImpl<>(context); + } + + @Override + public DiffConfig build() { + return new DiffConfigImpl(context); + } +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilder.java new file mode 100644 index 0000000..ae0ef3d --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilder.java @@ -0,0 +1,34 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +/** + * Responsible for make available the supported types of mappings. + * + * @author Jonathan Pereira + * @version 1.2.0 + * @since 1.0.0 + */ +public interface DiffMappingTypeBuilder { + + /** + * Identifies and maps all fields from a class using Reflection. + * + * @return instance with all the fields mapped. + */ + DiffMappingBuilder all(); + + /** + * Identifies and maps all fields from a class with supported annotations. + * + * @return instance with all the fields with supported annotations mapped. + */ + DiffMappingBuilder annotations(); + + /** + * Make available a manually mapping of fields. + * + * @return instance for manully configure mappings for fields. + */ + DiffManualMappingBuilder fields(); + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilderImpl.java new file mode 100644 index 0000000..6a47c9b --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingTypeBuilderImpl.java @@ -0,0 +1,26 @@ +package com.github.jonpereiradev.diffobjects.builder; + +final class DiffMappingTypeBuilderImpl implements DiffMappingTypeBuilder { + + private final DiffBuilderContext context; + + DiffMappingTypeBuilderImpl(DiffBuilderContext context) { + this.context = context; + } + + @Override + public DiffMappingBuilder all() { + return new DiffMappingAllBuilderImpl<>(context); + } + + @Override + public DiffMappingBuilder annotations() { + return new DiffMappingAnnotationsBuilderImpl<>(context); + } + + @Override + public DiffManualMappingBuilder fields() { + return new DiffMappingFieldBuilderImpl<>(context); + } + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilder.java index f86b4b6..fc74800 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilder.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilder.java @@ -5,34 +5,17 @@ * Builder responsible for modify the queried field of a class to create a configuration of diff. * * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffConfiguration * @since 1.0.0 */ -public interface DiffQueryBuilder { +public interface DiffQueryBuilder { /** - * Define a property for the last mapping. + * Gets the object responsible for query mappings for change. * - * @param key the identifier of the property. - * @param value the value of the property. + * @param name the name of the object mapped in the builder. * - * @return the instance of this builder. + * @return the instance of the builder. */ - DiffQueryBuilder property(String key, String value); + DiffQueryFoundBuilder find(String name); - /** - * Removes the mapping that this current query represents. - * - * @return the instance of this builder. - */ - DiffMappingAllBuilder unmapping(); - - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ - DiffConfiguration configuration(); } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImpl.java index 77c6d74..832f323 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImpl.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImpl.java @@ -1,70 +1,36 @@ package com.github.jonpereiradev.diffobjects.builder; +import com.github.jonpereiradev.diffobjects.DiffConfig; import com.github.jonpereiradev.diffobjects.DiffException; import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; -import java.util.Map; - /** * Responsible to map a class and fields to be able to generate diffs. * * @author Jonathan Pereira - * @see DiffInstanceBuilder + * @see DiffConfigBuilder * @see DiffMappingBuilder - * @see DiffConfiguration + * @see DiffConfig * @since 1.0.0 */ -class DiffQueryBuilderImpl implements DiffQueryBuilder { - - private final DiffMetadata diffMetadata; - private final Map metadatas; - private final DiffMappingAllBuilder diffMappingAllBuilder; +class DiffQueryBuilderImpl implements DiffQueryBuilder { - DiffQueryBuilderImpl(String field, Map metadatas, DiffMappingAllBuilder diffMappingAllBuilder) { - this.diffMetadata = metadatas.get(field); + private final DiffBuilderContext context; - if (this.diffMetadata == null) { - throw new DiffException("No field \"" + field + "\" mapped in builder. You need to map the field before query."); - } - - this.diffMappingAllBuilder = diffMappingAllBuilder; - this.metadatas = metadatas; + DiffQueryBuilderImpl(DiffBuilderContext context) { + this.context = context; } - /** - * Define a property for the last mapping. - * - * @param key the identifier of the property. - * @param value the value of the property. - * - * @return the instance of this mapping. - */ @Override - public DiffQueryBuilder property(String key, String value) { - diffMetadata.getProperties().put(key, value); - return this; - } + public DiffQueryFoundBuilder find(String name) { + DiffMetadata metadata = context.get(name); - /** - * Removes the property from the mapping. - * - * @return the instance of this builder. - */ - @Override - public DiffMappingAllBuilder unmapping() { - metadatas.remove(diffMetadata.getProperties().get("field")); - return diffMappingAllBuilder; - } + if (metadata == null) { + throw new DiffException("No object \"" + name + "\" mapped in builder. You need to map the field before query."); + } - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ - @Override - public DiffConfiguration configuration() { - return new DiffConfigurationImpl(metadatas); + return new DiffQueryFoundBuilderImpl<>(context, metadata); } } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilder.java new file mode 100644 index 0000000..19f7e41 --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilder.java @@ -0,0 +1,41 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import com.github.jonpereiradev.diffobjects.DiffConfig; + +/** + * Builder responsible for modify the queried field of a class to create a configuration of diff. + * + * @author Jonathan Pereira + * @see DiffConfigBuilderImpl + * @see DiffConfigBuilder + * @see DiffConfig + * @since 1.0.0 + */ +public interface DiffQueryFoundBuilder extends DiffQueryBuilder { + + /** + * Define a property for the last mapping. + * + * @param key the identifier of the property. + * @param value the value of the property. + * + * @return the instance of this builder. + */ + DiffQueryFoundBuilder property(String key, String value); + + /** + * Removes the mapping that this current query represents. + * + * @return the instance of this builder. + */ + DiffQueryBuilder ignore(); + + /** + * Gets the configuration instance to get the configuration generated by this instance instance. + * + * @return a configuration instance instance. + */ + DiffConfig build(); + +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilderImpl.java new file mode 100644 index 0000000..686765b --- /dev/null +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryFoundBuilderImpl.java @@ -0,0 +1,65 @@ +package com.github.jonpereiradev.diffobjects.builder; + + +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.DiffConfigImpl; +import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; + + +/** + * Responsible to map a class and fields to be able to generate diffs. + * + * @author Jonathan Pereira + * @since 1.0.0 + */ +class DiffQueryFoundBuilderImpl implements DiffQueryFoundBuilder { + + private final DiffBuilderContext context; + private final DiffMetadata metadata; + + DiffQueryFoundBuilderImpl(DiffBuilderContext context, DiffMetadata metadata) { + this.context = context; + this.metadata = metadata; + } + + /** + * Define a property for the last mapping. + * + * @param key the identifier of the property. + * @param value the value of the property. + * + * @return the instance of this mapping. + */ + @Override + public DiffQueryFoundBuilder property(String key, String value) { + metadata.getProperties().put(key, value); + return this; + } + + /** + * Removes the property from the mapping. + * + * @return the instance of this builder. + */ + @Override + public DiffQueryBuilder ignore() { + String field = metadata.getProperties().get("field"); + context.remove(field); + return new DiffQueryBuilderImpl<>(context); + } + + @Override + public DiffQueryFoundBuilder find(String name) { + return new DiffQueryBuilderImpl<>(context).find(name); + } + + /** + * Gets the configuration instance to get the configuration generated by this instance. + * + * @return a configuration instance instance. + */ + @Override + public DiffConfig build() { + return new DiffConfigImpl(context); + } +} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilder.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilder.java index fcf84c1..cb50d1b 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilder.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilder.java @@ -1,60 +1,51 @@ package com.github.jonpereiradev.diffobjects.builder; +import com.github.jonpereiradev.diffobjects.DiffConfig; import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; /** - * Builder responsible for modify the queried field of a class to create a configuration of diff. + * Responsible for modify a mapped property. * * @author Jonathan Pereira - * @see DiffBuilder - * @see DiffInstanceBuilder - * @see DiffConfiguration + * @version 1.2.0 * @since 1.0.0 */ public interface DiffQueryMappingBuilder { /** - * Define a property for the last mapping. + * Adds a metadata property for a mapped property. * * @param key the identifier of the property. * @param value the value of the property. * - * @return the instance of this builder. + * @return instance of the mapped property with the new metadata property. */ DiffQueryMappingBuilder property(String key, String value); /** - * Removes the mapping that this current query represents. + * Maps a new property by name. * - * @return the instance of this builder. - */ - DiffMappingBuilder unmapping(); - - /** - * Maps a new getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. + * @param name the name that identifies the property for mapping. * - * @return the instance of this mapping. + * @return instance of the mapped property. */ - DiffQueryMappingBuilder mapping(String field); + DiffQueryMappingBuilder map(String name); /** - * Maps a new getter of the field for the class. + * Maps a property by name using a custom comparator. * - * @param the type of object been mapped for the field. - * @param field name of the field that will me used to find the getter method. - * @param comparator implementation that define how two objects will be check for equality. + * @param name the name that identifies the property for mapping. + * @param comparator custom comparator that checks a property for equality. * - * @return the instance of this mapping. + * @return instance of the mapped property. */ - DiffQueryMappingBuilder mapping(String field, DiffComparator comparator); + DiffQueryMappingBuilder map(String name, DiffComparator comparator); /** - * Gets the configuration instance to get the configuration generated by this instance instance. + * Constructs the final configuration object with the mapped fields. * - * @return a configuration instance instance. + * @return instance of the configuration for the mapped fields. */ - DiffConfiguration configuration(); + DiffConfig build(); } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilderImpl.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilderImpl.java deleted file mode 100644 index e4ff305..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryMappingBuilderImpl.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.github.jonpereiradev.diffobjects.builder; - - -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; - - -/** - * Responsible to map a class and fields to be able to generate diffs. - * - * @author Jonathan Pereira - * @see DiffInstanceBuilder - * @see DiffMappingBuilder - * @see DiffConfiguration - * @since 1.0.0 - */ -final class DiffQueryMappingBuilderImpl implements DiffQueryMappingBuilder { - - private final DiffMetadata metadata; - private final DiffMappingBuilderImpl diffMappingBuilder; - - DiffQueryMappingBuilderImpl(DiffMetadata metadata, DiffMappingBuilderImpl diffMappingBuilder) { - this.metadata = metadata; - this.diffMappingBuilder = diffMappingBuilder; - } - - /** - * Define a property for the last mapping. - * - * @param key the identifier of the property. - * @param value the value of the property. - * - * @return the instance of this mapping. - */ - @Override - public DiffQueryMappingBuilder property(String key, String value) { - metadata.getProperties().put(key, value); - return this; - } - - /** - * Removes the property from the mapping. - * - * @return the instance of this builder. - */ - @Override - public DiffMappingBuilder unmapping() { - diffMappingBuilder.getMetadatas().remove(metadata.getProperties().get("field")); - return diffMappingBuilder; - } - - /** - * Maps the getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * - * @return the instance of this mapping. - */ - @Override - public DiffQueryMappingBuilder mapping(String field) { - return diffMappingBuilder.mapping(field); - } - - /** - * Maps a new getter of the field for the class. - * - * @param field name of the field that will me used to find the getter method. - * @param comparator implementation that define how two objects will be check for equality. - * - * @return the instance of this mapping. - */ - @Override - public DiffQueryMappingBuilder mapping(String field, DiffComparator comparator) { - return diffMappingBuilder.mapping(field, comparator); - } - - /** - * Gets the configuration instance to get the configuration generated by this instance instance. - * - * @return a configuration instance instance. - */ - @Override - public DiffConfiguration configuration() { - return new DiffConfigurationImpl(diffMappingBuilder.getMetadatas()); - } - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffReflections.java b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffReflections.java index 90aa0ae..fccb6ba 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffReflections.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/builder/DiffReflections.java @@ -2,17 +2,11 @@ import com.github.jonpereiradev.diffobjects.DiffException; -import com.github.jonpereiradev.diffobjects.annotation.DiffIgnore; -import com.github.jonpereiradev.diffobjects.annotation.DiffMapping; -import com.github.jonpereiradev.diffobjects.annotation.DiffMappings; -import com.github.jonpereiradev.diffobjects.annotation.DiffProperty; -import com.github.jonpereiradev.diffobjects.comparator.DiffComparator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.MethodUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Collection; /** @@ -23,31 +17,11 @@ */ public final class DiffReflections { - /** - * Map the methods of the object that has the annotations for diff and stores in cache. - * - * @param diffClass class that have the diff annotations. - * - * @return the diff mappings of the class. - */ - public static DiffConfiguration mapAnnotations(Class diffClass) { - DiffBuilder builder = DiffBuilder.map(diffClass); - - if (diffClass.isAnnotationPresent(DiffMappings.class)) { - mapAllMethods(diffClass, builder); - } else { - mapAnnotationsMethods(diffClass, builder); - } - - return new DiffConfigurationImpl(builder.getMetadatas()); - } - /** * Discover the public non-args method for access a field value. * - * @param diffClass the class that has the getter method. + * @param diffClass the class that has the getter method. * @param fieldOrMethodName the name of the field for discover or the name of the getter method. - * * @return the getter method to get the value. */ public static Method discoverGetter(Class diffClass, String fieldOrMethodName) { @@ -57,7 +31,7 @@ public static Method discoverGetter(Class diffClass, String fieldOrMethodName possibleAccessMethodName = "get" + StringUtils.capitalize(fieldOrMethodName); } - Method method = MethodUtils.getMatchingAccessibleMethod(diffClass, possibleAccessMethodName, null); + Method method = MethodUtils.getMatchingAccessibleMethod(diffClass, possibleAccessMethodName); if (method == null) { throw new DiffException("Method " + possibleAccessMethodName + " not found or is not public and non-args in class " + diffClass.getName()); @@ -70,9 +44,8 @@ public static Method discoverGetter(Class diffClass, String fieldOrMethodName * Calls the method for the object and returns the value. * * @param instance the object instance that have the method. - * @param method the getter method to get the value. - * @param the type of value returned by the method. - * + * @param method the getter method to get the value. + * @param the type of value returned by the method. * @return the value returned by the getter method. */ @SuppressWarnings("unchecked") @@ -88,85 +61,15 @@ public static T invoke(Object instance, Method method) { } } - /** - * Map all methods from a class for diff. - * - * @param diffClass the class that has the methods. - * @param builder the builder that creates the metadata. - */ - private static DiffConfiguration mapAllMethods(Class diffClass, DiffBuilder builder) { - for (Method method : diffClass.getMethods()) { - if (!method.isAnnotationPresent(DiffIgnore.class)) { - builder.mapping(method.getName()); - } - } - - return new DiffConfigurationImpl(builder.getMetadatas()); - } - - /** - * Map all method annotations from a class. - * - * @param diffClass the class that has the annotations. - * @param builder the builder that creates the metadata. - */ - private static DiffConfiguration mapAnnotationsMethods(Class diffClass, DiffBuilder builder) { - for (Method method : diffClass.getMethods()) { - if (method.isAnnotationPresent(DiffMapping.class)) { - mapping(builder, method, method.getAnnotation(DiffMapping.class)); - } else if (method.isAnnotationPresent(DiffMappings.class)) { - for (DiffMapping diffMapping : method.getAnnotation(DiffMappings.class).value()) { - mapping(builder, method, diffMapping); - } - } - } - - return new DiffConfigurationImpl(builder.getMetadatas()); - } - - private static void mapping(DiffBuilder builder, Method method, DiffMapping diffMapping) { - if (Collection.class.isAssignableFrom(method.getReturnType())) { - mappingCollection(builder, method, diffMapping); - } else { - mappingField(builder, method, diffMapping); - } - } - - private static void mappingField(DiffBuilder builder, Method method, DiffMapping diffMapping) { - String field = method.getName(); - DiffComparator comparator = DiffReflections.newInstance(diffMapping.comparator()); - - if (!diffMapping.value().isEmpty()) { - field += "." + diffMapping.value(); - } - - DiffQueryMappingBuilder query = builder.mapping(field, comparator); - - for (DiffProperty diffProperty : diffMapping.properties()) { - query.property(diffProperty.key(), diffProperty.value()); - } - } - - private static void mappingCollection(DiffBuilder builder, Method method, DiffMapping diffMapping) { - DiffComparator comparator = DiffReflections.newInstance(diffMapping.comparator()); - DiffQueryMappingBuilder collectionBuilder = builder.mapping(method.getName(), comparator); - - if (!diffMapping.value().isEmpty()) { - collectionBuilder.mapping(method.getName() + "." + diffMapping.value(), comparator); - } - } - /** * Create a class instance. * * @param clazz class that will be used for create an instance. - * @param object type that will be returned by the class. - * + * @param object type that will be returned by the class. * @return created object. - * * @throws UnsupportedOperationException if no default constructor exists. */ - private static T newInstance(Class clazz) { + public static T newInstance(Class clazz) { try { return clazz.newInstance(); } catch (InstantiationException | IllegalAccessException e) { diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/comparator/DiffCollectionComparator.java b/src/main/java/com/github/jonpereiradev/diffobjects/comparator/DiffCollectionComparator.java deleted file mode 100644 index b8716de..0000000 --- a/src/main/java/com/github/jonpereiradev/diffobjects/comparator/DiffCollectionComparator.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.jonpereiradev.diffobjects.comparator; - - -/** - * Contract to compare the equality from two objects of same type. Must have a public no args constructor. - * - * @author Jonathan Pereira - * @since 1.1.0 - */ -@FunctionalInterface -public interface DiffCollectionComparator { - - /** - * Check the equality of two objects. - * - * @param expected the object with the expected state. - * @param current the object with the current state. - * - * @return {@code true} if the two objects are equals. - */ - boolean isEquals(T expected, T current); - -} diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategy.java b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategy.java index a7184d0..c509a18 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategy.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategy.java @@ -10,6 +10,7 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; /** @@ -30,19 +31,20 @@ final class DiffCollectionStrategy implements DiffStrategy { * @return the instance result between the two objects. */ @Override - @SuppressWarnings("unchecked") + @SuppressWarnings({"rawtypes", "unchecked"}) public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { DiffComparator fieldComparator = metadata.getComparator(); Collection beforeCollection = initializeCollection(expected, metadata.getMethod()); Collection afterCollection = initializeCollection(current, metadata.getMethod()); + Map properties = metadata.getProperties(); if (beforeCollection == null && afterCollection == null) { - return new DiffResult(null, null, true); + return DiffResult.forValue(null, null, true, properties); } - // if has not the same size, so they are different + // if it has not the same size, so they are different if (!isEqualsSize(beforeCollection, afterCollection)) { - return new DiffResult(beforeCollection, afterCollection, false); + return DiffResult.forValue(beforeCollection, afterCollection, false, properties); } List afterCopy = new ArrayList<>(afterCollection); @@ -53,7 +55,7 @@ public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { // check the elements that exist on beforeState and not exists on afterState if (currentAfter == null) { - return new DiffResult(beforeCollection, afterCollection, false); + return DiffResult.forValue(beforeCollection, afterCollection, false, properties); } afterCopy.remove(currentAfter); @@ -68,10 +70,10 @@ public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { ); if (!single.isEquals()) { - return new DiffResult(beforeCollection, afterCollection, false); + return DiffResult.forValue(beforeCollection, afterCollection, false, properties); } } else if (!fieldComparator.isEquals(currentBefore, currentAfter)) { - return new DiffResult(beforeCollection, afterCollection, false); + return DiffResult.forValue(beforeCollection, afterCollection, false, properties); } } @@ -82,11 +84,11 @@ public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { .noneMatch((o) -> fieldComparator.isEquals(o, currentAfter)); if (noneMatch) { - return new DiffResult(beforeCollection, afterCollection, false); + return DiffResult.forValue(beforeCollection, afterCollection, false, properties); } } - return new DiffResult(beforeCollection, afterCollection, true); + return DiffResult.forValue(beforeCollection, afterCollection, true, properties); } /** @@ -124,6 +126,7 @@ private DiffResult checkDiff( DiffComparator fieldComparator, Object currentBefore, Object currentAfter) { + String value = diffMetadata.getValue(); String currentValue = value.contains(".") ? value.substring(0, value.indexOf(".")) : value; String nextValue = value.contains(".") ? value.substring(value.indexOf(".") + 1) : ""; diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategy.java b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategy.java index b381694..a63c7da 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategy.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategy.java @@ -28,6 +28,7 @@ final class DiffNestedStrategy implements DiffStrategy { * @return the diff result between the two objects. */ @Override + @SuppressWarnings({"rawtypes", "unchecked"}) public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { DiffComparator comparator = metadata.getComparator(); Method expectedMethod = metadata.getMethod(); @@ -49,6 +50,7 @@ public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { } } - return new DiffResult(expectedObject, currentObject, comparator.isEquals(expectedObject, currentObject)); + boolean equals = comparator.isEquals(expectedObject, currentObject); + return DiffResult.forValue(expectedObject, currentObject, equals, metadata.getProperties()); } } diff --git a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategy.java b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategy.java index 1aa3f3d..f1bcc26 100644 --- a/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategy.java +++ b/src/main/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategy.java @@ -24,11 +24,13 @@ final class DiffSingleStrategy implements DiffStrategy { * @return the diff result between the two objects. */ @Override + @SuppressWarnings({"rawtypes", "unchecked"}) public DiffResult diff(Object expected, Object current, DiffMetadata metadata) { Object expectedValue = DiffReflections.invoke(expected, metadata.getMethod()); Object currentValue = DiffReflections.invoke(current, metadata.getMethod()); DiffComparator comparator = metadata.getComparator(); + boolean equals = comparator.isEquals(expectedValue, currentValue); - return new DiffResult(expectedValue, currentValue, comparator.isEquals(expectedValue, currentValue)); + return DiffResult.forValue(expectedValue, currentValue, equals, metadata.getProperties()); } } diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithAnnotationsTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithAnnotationsTest.java index 7b17d0b..c75f250 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithAnnotationsTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithAnnotationsTest.java @@ -1,6 +1,8 @@ package com.github.jonpereiradev.diffobjects; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement2; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -9,7 +11,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.List; public class DiffObjectsWithAnnotationsTest { @@ -85,13 +86,13 @@ public void testDiffObjectsCollectionWithNullAfterStateEqualsMustThrowNullPointe public void testDiffObjectsWithEqualsObjectElementMustReturnDiffWithEquals() { ObjectElement objectA = new ObjectElement("Object"); ObjectElement objectB = new ObjectElement("Object"); - List results = diffObjects.diff(objectA, objectB); + DiffResults results = diffObjects.diff(objectA, objectB); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(1, results.size()); - Assert.assertTrue(results.get(0).isEquals()); - Assert.assertEquals("Object", results.get(0).getExpected()); - Assert.assertEquals("Object", results.get(0).getCurrent()); + Assert.assertTrue(results.getResults().get(0).isEquals()); + Assert.assertEquals("Object", results.getResults().get(0).getExpected()); + Assert.assertEquals("Object", results.getResults().get(0).getCurrent()); } @Test @@ -106,25 +107,25 @@ public void testDiffObjectsCollectionWithEqualsObjectElementMustReturnDiffWithEq Collection a = Arrays.asList(objectA, objectB); Collection b = Arrays.asList(objectC, objectD); - List results = diffObjects.diff(a, b, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResults results = diffObjects.diff(a, b, (o1, o2) -> o1.getName().equals(o2.getName())); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(2, results.size()); - Assert.assertTrue(results.get(0).isEquals()); - Assert.assertTrue(results.get(1).isEquals()); + Assert.assertTrue(results.getResults().get(0).isEquals()); + Assert.assertTrue(results.getResults().get(1).isEquals()); } @Test public void testDiffObjectsWithDifferentObjectElementMustReturnDiffWithDifference() { ObjectElement objectA = new ObjectElement("Object A"); ObjectElement objectB = new ObjectElement("Object B"); - List results = diffObjects.diff(objectA, objectB); + DiffResults results = diffObjects.diff(objectA, objectB); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(1, results.size()); - Assert.assertFalse(results.get(0).isEquals()); - Assert.assertEquals("Object A", results.get(0).getExpected()); - Assert.assertEquals("Object B", results.get(0).getCurrent()); + Assert.assertFalse(results.getResults().get(0).isEquals()); + Assert.assertEquals("Object A", results.getResults().get(0).getExpected()); + Assert.assertEquals("Object B", results.getResults().get(0).getCurrent()); } @Test @@ -139,12 +140,12 @@ public void testDiffObjectsCollectionWithDifferentObjectElementMustReturnDiffWit Collection cA = Arrays.asList(objectA, objectB); Collection cB = Arrays.asList(objectC, objectD); - List results = diffObjects.diff(cA, cB, (a, b) -> a.getName().equals(b.getName())); + DiffResults results = diffObjects.diff(cA, cB, (a, b) -> a.getName().equals(b.getName())); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(2, results.size()); - Assert.assertTrue(results.get(0).isEquals()); - Assert.assertFalse(results.get(1).isEquals()); + Assert.assertTrue(results.getResults().get(0).isEquals()); + Assert.assertFalse(results.getResults().get(1).isEquals()); } @Test @@ -154,10 +155,10 @@ public void testDiffObjectsCollectionWithDifferentNameMustReturnDiffWithDifferen Collection a = Collections.singletonList(objectA); Collection b = Collections.singletonList(objectB); - List results = diffObjects.diff(a, b, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResults results = diffObjects.diff(a, b, (o1, o2) -> o1.getName().equals(o2.getName())); - Assert.assertFalse(results.get(0).isEquals()); - Assert.assertFalse(results.get(1).isEquals()); + Assert.assertFalse(results.getResults().get(0).isEquals()); + Assert.assertFalse(results.getResults().get(1).isEquals()); } @Test diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithBuilderTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithBuilderTest.java index aa6a2ff..f7225d2 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithBuilderTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/DiffObjectsWithBuilderTest.java @@ -1,8 +1,9 @@ package com.github.jonpereiradev.diffobjects; -import com.github.jonpereiradev.diffobjects.builder.DiffBuilder; -import com.github.jonpereiradev.diffobjects.builder.DiffConfiguration; +import com.github.jonpereiradev.diffobjects.builder.DiffConfigBuilder; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement2; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -10,18 +11,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.List; public class DiffObjectsWithBuilderTest { private DiffObjects diffObjects; - private DiffConfiguration configuration; + private DiffConfig configuration; @Before public void beforeTest() { diffObjects = DiffObjects.forClass(ObjectElement.class); - configuration = DiffBuilder.map(ObjectElement.class).mapping("name").configuration(); + configuration = DiffConfigBuilder.forClass(ObjectElement.class).mapping().fields().map("name").build(); } @Test(expected = NullPointerException.class) @@ -118,13 +118,16 @@ public void testDiffObjectsCollectionWithNullConfigurationEqualsStateMustThrowNu public void testDiffObjectsWithEqualsObjectElementMustReturnResultWithEquals() { ObjectElement objectA = new ObjectElement("Object"); ObjectElement objectB = new ObjectElement("Object"); - List results = diffObjects.diff(objectA, objectB, configuration); + DiffResults results = diffObjects.diff(objectA, objectB, configuration); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(1, results.size()); - Assert.assertTrue(results.get(0).isEquals()); - Assert.assertEquals("Object", results.get(0).getExpected()); - Assert.assertEquals("Object", results.get(0).getCurrent()); + + DiffResult result = results.stream().findFirst().orElseThrow(RuntimeException::new); + + Assert.assertTrue(result.isEquals()); + Assert.assertEquals("Object", result.getExpected()); + Assert.assertEquals("Object", result.getCurrent()); } @Test @@ -135,26 +138,30 @@ public void testDiffObjectsCollectionWithEqualsObjectElementMustReturnResultWith Collection b = Collections.singletonList(objectB); DiffObjects diffObjects = DiffObjects.forClass(ObjectElement.class); - DiffBuilder diffBuilder = DiffBuilder.map(ObjectElement.class); - DiffConfiguration configuration = diffBuilder.mapping("name").configuration(); + DiffConfigBuilder diffBuilder = DiffConfigBuilder.forClass(ObjectElement.class); + DiffConfig configuration = diffBuilder.mapping().fields().map("name").build(); - List results = diffObjects.diff(a, b, configuration, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResults results = diffObjects.diff(a, b, configuration, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResult result = results.stream().findFirst().orElse(null); - Assert.assertFalse(results.isEmpty()); - Assert.assertTrue(results.get(0).isEquals()); + Assert.assertNotNull(result); + Assert.assertTrue(result.isEquals()); } @Test public void testDiffObjectsWithDifferentObjectElementMustReturnResultWithDifference() { ObjectElement objectA = new ObjectElement("Object A"); ObjectElement objectB = new ObjectElement("Object B"); - List results = diffObjects.diff(objectA, objectB, configuration); + DiffResults results = diffObjects.diff(objectA, objectB, configuration); Assert.assertFalse(results.isEmpty()); Assert.assertEquals(1, results.size()); - Assert.assertFalse(results.get(0).isEquals()); - Assert.assertEquals("Object A", results.get(0).getExpected()); - Assert.assertEquals("Object B", results.get(0).getCurrent()); + + DiffResult result = results.stream().findFirst().orElseThrow(NullPointerException::new); + + Assert.assertFalse(result.isEquals()); + Assert.assertEquals("Object A", result.getExpected()); + Assert.assertEquals("Object B", result.getCurrent()); } @Test @@ -165,13 +172,14 @@ public void testDiffObjectsCollectionWithDifferentObjectElementMustReturnResultW Collection b = Collections.singletonList(objectB); DiffObjects diffObjects = DiffObjects.forClass(ObjectElement2.class); - DiffBuilder diffBuilder = DiffBuilder.map(ObjectElement2.class); - DiffConfiguration configuration = diffBuilder.mapping("name").mapping("name2").configuration(); + DiffConfigBuilder diffBuilder = DiffConfigBuilder.forClass(ObjectElement2.class); + DiffConfig configuration = diffBuilder.mapping().fields().map("name").map("name2").build(); - List results = diffObjects.diff(a, b, configuration, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResults results = diffObjects.diff(a, b, configuration, (o1, o2) -> o1.getName().equals(o2.getName())); + DiffResult result = results.stream().findFirst().orElse(null); - Assert.assertFalse(results.isEmpty()); - Assert.assertFalse(results.get(0).isEquals()); + Assert.assertNotNull(result); + Assert.assertFalse(result.isEquals()); } @Test diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImplTest.java similarity index 66% rename from src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderTest.java rename to src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImplTest.java index a6bd941..f85076a 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffBuilderTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigBuilderImplTest.java @@ -1,10 +1,10 @@ package com.github.jonpereiradev.diffobjects.builder; -import com.github.jonpereiradev.diffobjects.ComplexElement; import com.github.jonpereiradev.diffobjects.DiffException; -import com.github.jonpereiradev.diffobjects.ObjectElement; import com.github.jonpereiradev.diffobjects.comparator.EqualsComparator; +import com.github.jonpereiradev.diffobjects.model.ComplexElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType; import org.junit.Test; @@ -18,19 +18,20 @@ import static org.junit.Assert.assertTrue; -public class DiffBuilderTest { +public class DiffConfigBuilderImplTest { @Test(expected = NullPointerException.class) public void testDiffBuilderNullClassParameter() { - DiffBuilder.map(null); + DiffConfigBuilder.forClass(null); } @Test public void testDiffBuilderMappingAll() { - List metadata = DiffBuilder - .map(ObjectElement.class) - .mappingAll() - .configuration() + List metadata = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .all() + .build() .build(); assertNotNull(metadata); @@ -42,15 +43,17 @@ public void testDiffBuilderMappingAll() { @Test(expected = DiffException.class) public void testDiffBuilderMappingNotFound() { - DiffBuilder.map(ObjectElement.class).mapping("notExists"); + DiffConfigBuilder.forClass(ObjectElement.class).mapping().fields().map("notExists"); } @Test public void testDiffBuilderMappingFieldName() { - List metadata = DiffBuilder - .map(ObjectElement.class) - .mapping("name") - .configuration() + List metadata = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .fields() + .map("name") + .build() .build(); assertNotNull(metadata); @@ -61,10 +64,12 @@ public void testDiffBuilderMappingFieldName() { @Test public void testDiffBuilderMappingFieldParent() { - List metadata = DiffBuilder - .map(ObjectElement.class) - .mapping("parent") - .configuration() + List metadata = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .fields() + .map("parent") + .build() .build(); assertNotNull(metadata); @@ -75,14 +80,16 @@ public void testDiffBuilderMappingFieldParent() { @Test public void testDiffBuilderMappingWithQueryProperty() { - List metadata = DiffBuilder - .map(ObjectElement.class) - .mappingAll() - .query("name") - .unmapping() - .query("parent") + List metadata = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .all() + .query() + .find("name") + .ignore() + .find("parent") .property("query", "true") - .configuration() + .build() .build(); assertNotNull(metadata); @@ -94,11 +101,13 @@ public void testDiffBuilderMappingWithQueryProperty() { @Test public void testDiffBuilderSingleStrategyType() { - List diffMetadatas = DiffBuilder - .map(ObjectElement.class) - .mapping("name", new EqualsComparator<>()) - .mapping("parent") - .configuration() + List diffMetadatas = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .fields() + .map("name", new EqualsComparator<>()) + .map("parent") + .build() .build(); assertNotNull(diffMetadatas); @@ -112,10 +121,12 @@ public void testDiffBuilderSingleStrategyType() { @Test public void testDiffBuilderDeepStrategyType() { - List diffMetadatas = DiffBuilder - .map(ComplexElement.class) - .mapping("objectElement.name") - .configuration() + List diffMetadatas = DiffConfigBuilder + .forClass(ComplexElement.class) + .mapping() + .fields() + .map("objectElement.name") + .build() .build(); assertNotNull(diffMetadatas); @@ -127,10 +138,12 @@ public void testDiffBuilderDeepStrategyType() { @Test public void testDiffBuilderCollectionStrategyType() { - List diffMetadatas = DiffBuilder - .map(ComplexElement.class) - .mapping("objectElementList.name") - .configuration() + List diffMetadatas = DiffConfigBuilder + .forClass(ComplexElement.class) + .mapping() + .fields() + .map("objectElementList.name") + .build() .build(); assertNotNull(diffMetadatas); @@ -142,7 +155,13 @@ public void testDiffBuilderCollectionStrategyType() { @Test public void testDiffBuilderDefaultEqualsComparator() { - List diffMetadata = DiffBuilder.map(ObjectElement.class).mapping("name").configuration().build(); + List diffMetadata = DiffConfigBuilder + .forClass(ObjectElement.class) + .mapping() + .fields() + .map("name") + .build() + .build(); assertNotNull(diffMetadata); assertFalse(diffMetadata.isEmpty()); diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImplTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigImplTest.java similarity index 58% rename from src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImplTest.java rename to src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigImplTest.java index 65ec535..7419353 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigurationImplTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffConfigImplTest.java @@ -1,37 +1,39 @@ package com.github.jonpereiradev.diffobjects.builder; -import com.github.jonpereiradev.diffobjects.ObjectElement; +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.DiffConfigImpl; import com.github.jonpereiradev.diffobjects.annotation.DiffOrder; import com.github.jonpereiradev.diffobjects.comparator.EqualsComparator; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType; import org.junit.Test; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; -public class DiffConfigurationImplTest { +public class DiffConfigImplTest { @Test public void testMustBuildEmptyWithEmptyMetadatas() { - DiffConfiguration diffConfiguration = new DiffConfigurationImpl(new HashMap()); - assertTrue(diffConfiguration.build().isEmpty()); + DiffBuilderContext context = new DiffBuilderContext<>(ObjectElement.class); + DiffConfig diffConfig = new DiffConfigImpl(context); + assertTrue(diffConfig.build().isEmpty()); } @Test public void testMustBuildUnorderedMetadataWithoutOrderAnnotation() throws NoSuchMethodException { - Map map = new HashMap<>(); - DiffMetadata o2 = new DiffMetadata("parent", ObjectElement.class.getMethod("getParent"), DiffStrategyType.SINGLE, new EqualsComparator()); - DiffMetadata o1 = new DiffMetadata("name", ObjectElement.class.getMethod("getName"), DiffStrategyType.SINGLE, new EqualsComparator()); + DiffBuilderContext context = new DiffBuilderContext<>(ObjectElement.class); + DiffMetadata o2 = new DiffMetadata("parent", ObjectElement.class.getMethod("getParent"), DiffStrategyType.SINGLE, new EqualsComparator<>()); + DiffMetadata o1 = new DiffMetadata("name", ObjectElement.class.getMethod("getName"), DiffStrategyType.SINGLE, new EqualsComparator<>()); - map.put(o1.getValue(), o1); - map.put(o2.getValue(), o2); + context.put(o1.getValue(), o1); + context.put(o2.getValue(), o2); - DiffConfiguration diffConfiguration = new DiffConfigurationImpl(map); - List metadatas = diffConfiguration.build(); + DiffConfig diffConfig = new DiffConfigImpl(context); + List metadatas = diffConfig.build(); assertTrue(metadatas.contains(o1)); assertTrue(metadatas.contains(o2)); @@ -39,15 +41,15 @@ public void testMustBuildUnorderedMetadataWithoutOrderAnnotation() throws NoSuch @Test public void testMustBuildOrderedMetadataWithOrderAnnotation() throws NoSuchMethodException { - Map map = new HashMap<>(); - DiffMetadata o2 = new DiffMetadata("value1", ObjectElementOrdered.class.getMethod("getValue1"), DiffStrategyType.SINGLE, new EqualsComparator()); - DiffMetadata o1 = new DiffMetadata("value2", ObjectElementOrdered.class.getMethod("getValue2"), DiffStrategyType.SINGLE, new EqualsComparator()); + DiffBuilderContext context = new DiffBuilderContext<>(ObjectElementOrdered.class); + DiffMetadata o2 = new DiffMetadata("value1", ObjectElementOrdered.class.getMethod("getValue1"), DiffStrategyType.SINGLE, new EqualsComparator<>()); + DiffMetadata o1 = new DiffMetadata("value2", ObjectElementOrdered.class.getMethod("getValue2"), DiffStrategyType.SINGLE, new EqualsComparator<>()); - map.put(o1.getValue(), o1); - map.put(o2.getValue(), o2); + context.put(o1.getValue(), o1); + context.put(o2.getValue(), o2); - DiffConfiguration diffConfiguration = new DiffConfigurationImpl(map); - List metadatas = diffConfiguration.build(); + DiffConfig diffConfig = new DiffConfigImpl(context); + List metadatas = diffConfig.build(); assertEquals("value2", metadatas.get(0).getValue()); assertEquals("value1", metadatas.get(1).getValue()); diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImplTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImplTest.java index d2219cd..f941673 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImplTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffMappingBuilderImplTest.java @@ -1,14 +1,12 @@ package com.github.jonpereiradev.diffobjects.builder; -import com.github.jonpereiradev.diffobjects.ComplexElement; import com.github.jonpereiradev.diffobjects.DiffException; import com.github.jonpereiradev.diffobjects.comparator.EqualsComparator; +import com.github.jonpereiradev.diffobjects.model.ComplexElement; import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; import com.github.jonpereiradev.diffobjects.strategy.DiffStrategyType; import org.junit.Test; -import java.util.HashMap; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; @@ -16,12 +14,12 @@ public class DiffMappingBuilderImplTest { @Test public void testMustMapFieldWithSingleStrategy() { - HashMap metadatas = new HashMap<>(); - DiffMappingBuilder diffMappingBuilder = new DiffMappingBuilderImpl<>(ComplexElement.class, metadatas); + DiffBuilderContext context = new DiffBuilderContext<>(ComplexElement.class); + DiffManualMappingBuilder diffMappingBuilder = new DiffMappingFieldBuilderImpl<>(context); - diffMappingBuilder.mapping("parent"); + diffMappingBuilder.map("parent"); - DiffMetadata diffMetadata = diffMappingBuilder.configuration().build().get(0); + DiffMetadata diffMetadata = diffMappingBuilder.build().build().get(0); assertSame(DiffStrategyType.SINGLE.getStrategy(), diffMetadata.getStrategy()); assertEquals(EqualsComparator.class, diffMetadata.getComparator().getClass()); @@ -30,12 +28,12 @@ public void testMustMapFieldWithSingleStrategy() { @Test public void testMustMapFieldWithDeepStrategy() { - HashMap metadatas = new HashMap<>(); - DiffMappingBuilder diffMappingBuilder = new DiffMappingBuilderImpl<>(ComplexElement.class, metadatas); + DiffBuilderContext context = new DiffBuilderContext<>(ComplexElement.class); + DiffManualMappingBuilder diffMappingBuilder = new DiffMappingFieldBuilderImpl<>(context); - diffMappingBuilder.mapping("objectElement.name"); + diffMappingBuilder.map("objectElement.name"); - DiffMetadata diffMetadata = diffMappingBuilder.configuration().build().get(0); + DiffMetadata diffMetadata = diffMappingBuilder.build().build().get(0); assertSame(DiffStrategyType.NESTED.getStrategy(), diffMetadata.getStrategy()); assertEquals(EqualsComparator.class, diffMetadata.getComparator().getClass()); @@ -44,12 +42,12 @@ public void testMustMapFieldWithDeepStrategy() { @Test public void testMustMapFieldWithCollectionStrategy() { - HashMap metadatas = new HashMap<>(); - DiffMappingBuilder diffMappingBuilder = new DiffMappingBuilderImpl<>(ComplexElement.class, metadatas); + DiffBuilderContext context = new DiffBuilderContext<>(ComplexElement.class); + DiffManualMappingBuilder diffMappingBuilder = new DiffMappingFieldBuilderImpl<>(context); - diffMappingBuilder.mapping("objectElementList.name"); + diffMappingBuilder.map("objectElementList.name"); - DiffMetadata diffMetadata = diffMappingBuilder.configuration().build().get(0); + DiffMetadata diffMetadata = diffMappingBuilder.build().build().get(0); assertSame(DiffStrategyType.COLLECTION.getStrategy(), diffMetadata.getStrategy()); assertEquals(EqualsComparator.class, diffMetadata.getComparator().getClass()); @@ -58,14 +56,16 @@ public void testMustMapFieldWithCollectionStrategy() { @Test(expected = DiffException.class) public void testMustThrowExceptionWhenMethodNotPublic() { - DiffMappingBuilder diffMappingBuilder = new DiffMappingBuilderImpl<>(ComplexElement.class, new HashMap<>()); - diffMappingBuilder.mapping("notAccessible"); + DiffBuilderContext context = new DiffBuilderContext<>(ComplexElement.class); + DiffManualMappingBuilder diffMappingBuilder = new DiffMappingFieldBuilderImpl<>(context); + diffMappingBuilder.map("notAccessible"); } @Test(expected = DiffException.class) public void testMustThrowExceptionWhenMethodNotNoArgs() { - DiffMappingBuilder diffMappingBuilder = new DiffMappingBuilderImpl<>(ComplexElement.class, new HashMap<>()); - diffMappingBuilder.mapping("withArgs"); + DiffBuilderContext context = new DiffBuilderContext<>(ComplexElement.class); + DiffManualMappingBuilder diffMappingBuilder = new DiffMappingFieldBuilderImpl<>(context); + diffMappingBuilder.map("withArgs"); } } \ No newline at end of file diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImplTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImplTest.java index 5e063ec..00a175c 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImplTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/builder/DiffQueryBuilderImplTest.java @@ -1,16 +1,15 @@ package com.github.jonpereiradev.diffobjects.builder; import com.github.jonpereiradev.diffobjects.DiffException; -import com.github.jonpereiradev.diffobjects.strategy.DiffMetadata; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import org.junit.Test; -import java.util.HashMap; - public class DiffQueryBuilderImplTest { @Test(expected = DiffException.class) public void testMustThrowExceptionWhenFieldNotFound() { - new DiffQueryBuilderImpl("notexists", new HashMap(), null); + DiffBuilderContext context = new DiffBuilderContext<>(ObjectElement.class); + new DiffQueryBuilderImpl<>(context).find("not_exists"); } } \ No newline at end of file diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/ComplexElement.java b/src/test/java/com/github/jonpereiradev/diffobjects/model/ComplexElement.java similarity index 96% rename from src/test/java/com/github/jonpereiradev/diffobjects/ComplexElement.java rename to src/test/java/com/github/jonpereiradev/diffobjects/model/ComplexElement.java index f6591db..48369fb 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/ComplexElement.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/model/ComplexElement.java @@ -1,4 +1,4 @@ -package com.github.jonpereiradev.diffobjects; +package com.github.jonpereiradev.diffobjects.model; import com.github.jonpereiradev.diffobjects.annotation.DiffMapping; diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement.java b/src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement.java similarity index 94% rename from src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement.java rename to src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement.java index db9b0ac..e8e6904 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement.java @@ -1,11 +1,10 @@ -package com.github.jonpereiradev.diffobjects; +package com.github.jonpereiradev.diffobjects.model; import com.github.jonpereiradev.diffobjects.annotation.DiffMapping; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; - public class ObjectElement extends ParentObjectElement { private final String name; diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement2.java b/src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement2.java similarity index 95% rename from src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement2.java rename to src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement2.java index d6f28dc..0a510a8 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/ObjectElement2.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/model/ObjectElement2.java @@ -1,4 +1,4 @@ -package com.github.jonpereiradev.diffobjects; +package com.github.jonpereiradev.diffobjects.model; import com.github.jonpereiradev.diffobjects.annotation.DiffMapping; diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/ParentObjectElement.java b/src/test/java/com/github/jonpereiradev/diffobjects/model/ParentObjectElement.java similarity index 80% rename from src/test/java/com/github/jonpereiradev/diffobjects/ParentObjectElement.java rename to src/test/java/com/github/jonpereiradev/diffobjects/model/ParentObjectElement.java index 7b7a6b7..299a5c4 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/ParentObjectElement.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/model/ParentObjectElement.java @@ -1,4 +1,4 @@ -package com.github.jonpereiradev.diffobjects; +package com.github.jonpereiradev.diffobjects.model; public abstract class ParentObjectElement { diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/BaseStrategyTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/BaseStrategyTest.java index 931d1c6..cfde4a2 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/BaseStrategyTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/BaseStrategyTest.java @@ -1,12 +1,18 @@ package com.github.jonpereiradev.diffobjects.strategy; -import com.github.jonpereiradev.diffobjects.builder.DiffReflections; +import com.github.jonpereiradev.diffobjects.DiffConfig; +import com.github.jonpereiradev.diffobjects.builder.DiffConfigBuilder; + +import java.util.List; public abstract class BaseStrategyTest { protected DiffMetadata discoverByName(Class classMap, String name) { - for (DiffMetadata metadata : DiffReflections.mapAnnotations(classMap).build()) { + DiffConfig config = DiffConfigBuilder.forClass(classMap).mapping().annotations().build(); + List metadataList = config.build(); + + for (DiffMetadata metadata : metadataList) { if (metadata.getMethod().getName().equals(name)) { return metadata; } diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategyTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategyTest.java index d723c02..c6d27f3 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategyTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffCollectionStrategyTest.java @@ -1,9 +1,9 @@ package com.github.jonpereiradev.diffobjects.strategy; -import com.github.jonpereiradev.diffobjects.ComplexElement; import com.github.jonpereiradev.diffobjects.DiffResult; -import com.github.jonpereiradev.diffobjects.ObjectElement; +import com.github.jonpereiradev.diffobjects.model.ComplexElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import org.junit.Assert; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategyTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategyTest.java index 8ac2920..84acfa2 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategyTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffNestedStrategyTest.java @@ -1,9 +1,9 @@ package com.github.jonpereiradev.diffobjects.strategy; -import com.github.jonpereiradev.diffobjects.ComplexElement; import com.github.jonpereiradev.diffobjects.DiffResult; -import com.github.jonpereiradev.diffobjects.ObjectElement; +import com.github.jonpereiradev.diffobjects.model.ComplexElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import org.junit.Assert; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategyTest.java b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategyTest.java index ecfb7d3..a652edb 100644 --- a/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategyTest.java +++ b/src/test/java/com/github/jonpereiradev/diffobjects/strategy/DiffSingleStrategyTest.java @@ -2,7 +2,7 @@ import com.github.jonpereiradev.diffobjects.DiffResult; -import com.github.jonpereiradev.diffobjects.ObjectElement; +import com.github.jonpereiradev.diffobjects.model.ObjectElement; import org.junit.Assert; import org.junit.Before; import org.junit.Test;