org.javers.core.Changes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javers-core Show documentation
Show all versions of javers-core Show documentation
JaVers - object auditing and diff framework for Java
package org.javers.core;
import org.javers.common.string.PrettyValuePrinter;
import org.javers.common.validation.Validate;
import org.javers.core.commit.CommitMetadata;
import org.javers.core.diff.Change;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.repository.jql.JqlQuery;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
import static org.javers.common.validation.Validate.argumentIsNotNull;
/**
* Convenient wrapper for the list of Changes returned by {@link Javers#findChanges(JqlQuery)}.
*
*
* Allows traversing over the list of Changes grouped by commits
* and grouped by entities, see:
* {@link #groupByCommit()}, {@link #groupByObject()}.
*
*
* {@link #prettyPrint()} prints Changes to the the nicely formatted String.
*
* @since 3.9
*/
public class Changes extends AbstractList implements Serializable {
private final List changes;
private final transient PrettyValuePrinter valuePrinter;
public Changes(List changes, PrettyValuePrinter valuePrinter) {
Validate.argumentsAreNotNull(changes, valuePrinter);
this.changes = Collections.unmodifiableList(changes);
this.valuePrinter = valuePrinter;
}
/**
* Changes grouped by commits.
*
*
* When formatting a changelog,
* usually you need to group changes by commits and then by objects.
*
*
* For example, this changelog:
*
* commit 2.0
* changes on Employee/Frodo :
* - ValueChange{ 'salary' changed from '10000' to '11000' }
* - ListChange{ 'subordinates' collection changes :
* 0. 'Employee/Sam' added }
* changes on Employee/Sam :
* - ValueChange{ 'name' changed from '' to 'Sam' }
* - ValueChange{ 'salary' changed from '0' to '2000' }
* - ReferenceChange{ 'boss' changed from '' to 'Employee/Frodo' }
* - NewObject{ new object: Employee/Sam }
* commit 1.0
* changes on Employee/Frodo :
* - ValueChange{ 'name' changed from '' to 'Frodo' }
* - ValueChange{ 'salary' changed from '0' to '10000' }
* - NewObject{ new object: Employee/Frodo }
*
*
* is printed by this code:
*
* Changes changes = javers.findChanges(QueryBuilder.byClass(Employee.class)
* .withNewObjectChanges().build());
*
* changes.groupByCommit().forEach(byCommit -> {
* System.out.println("commit " + byCommit.getCommit().getId());
* byCommit.groupByObject().forEach(byObject -> {
* System.out.println(" changes on " + byObject.getGlobalId().value() + " : ");
* byObject.get().forEach(change -> {
* System.out.println(" - " + change);
* });
* });
* });
*
*
* @see http://javers.org/documentation/repository-examples/#change-log
* @since 3.9
*/
public List groupByCommit() {
Map> changesByCommit = changes.stream().collect(
groupingBy(c -> c.getCommitMetadata().orElseThrow( () -> new IllegalStateException("No CommitMetadata in this Change")),
() -> new LinkedHashMap<>(), toList()));
List result = new ArrayList<>();
changesByCommit.forEach((k,v) -> {
result.add(new ChangesByCommit(k, v, valuePrinter));
});
return unmodifiableList(result);
}
/**
* Changes grouped by entities.
*
*
* See example in {@link #groupByCommit()}
*
*
* @since 3.9
*/
public List groupByObject() {
Map> changesByObject = changes.stream().collect(
groupingBy(c -> c.getAffectedGlobalId().masterObjectId()));
List result = new ArrayList<>();
changesByObject.forEach((k, v) -> {
result.add(new ChangesByObject(k, v, valuePrinter));
});
return unmodifiableList(result);
}
@Override
public Change get(int index) {
return changes.get(index);
}
@Override
public int size() {
return changes.size();
}
public List getChangesByType(final Class type) {
argumentIsNotNull(type);
return (List) unmodifiableList(
changes.stream().filter(input -> type.isAssignableFrom(input.getClass())).collect(Collectors.toList()));
}
/**
* Prints the nicely formatted list of Changes.
* Alias to {@link #toString()}.
*/
public final String prettyPrint() {
return toString();
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("Changes:\n");
for (ChangesByCommit c : groupByCommit()){
b.append(c.prettyPrint());
}
return b.toString();
}
}