org.javers.repository.api.JaversExtendedRepository 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.repository.api;
import org.javers.common.collections.Lists;
import org.javers.core.commit.Commit;
import org.javers.core.commit.CommitId;
import org.javers.core.diff.Change;
import org.javers.core.diff.changetype.PropertyChange;
import org.javers.core.json.JsonConverter;
import org.javers.core.metamodel.object.CdoSnapshot;
import org.javers.core.metamodel.object.GlobalId;
import org.javers.core.metamodel.object.InstanceId;
import org.javers.core.metamodel.type.EntityType;
import org.javers.core.metamodel.type.ManagedType;
import org.javers.core.snapshot.SnapshotDiffer;
import java.time.LocalDateTime;
import java.util.*;
import static org.javers.common.validation.Validate.argumentIsNotNull;
import static org.javers.common.validation.Validate.argumentsAreNotNull;
/**
* @author bartosz walacik
*/
public class JaversExtendedRepository implements JaversRepository {
private final JaversRepository delegate;
private final SnapshotDiffer snapshotDiffer;
private final PreviousSnapshotsCalculator previousSnapshotsCalculator;
public JaversExtendedRepository(JaversRepository delegate, SnapshotDiffer snapshotDiffer) {
this.delegate = delegate;
this.snapshotDiffer = snapshotDiffer;
previousSnapshotsCalculator = new PreviousSnapshotsCalculator(input -> getSnapshots(input));
}
public List getChangeHistory(GlobalId globalId, QueryParams queryParams) {
argumentsAreNotNull(globalId, queryParams);
List snapshots = getStateHistory(globalId, queryParams);
List changes = getChangesIntroducedBySnapshots(snapshots);
return filterChangesByPropertyNames(changes, queryParams);
}
public List getChangeHistory(Set givenClasses, QueryParams queryParams) {
argumentsAreNotNull(givenClasses, queryParams);
List snapshots = getStateHistory(givenClasses, queryParams);
List changes = getChangesIntroducedBySnapshots(snapshots);
return filterChangesByPropertyNames(changes, queryParams);
}
public List getValueObjectChangeHistory(EntityType ownerEntity, String path, QueryParams queryParams) {
argumentsAreNotNull(ownerEntity, path, queryParams);
List snapshots = getValueObjectStateHistory(ownerEntity, path, queryParams);
return getChangesIntroducedBySnapshots(snapshots);
}
public List getChanges(QueryParams queryParams) {
argumentsAreNotNull(queryParams);
List snapshots = getSnapshots(queryParams);
return getChangesIntroducedBySnapshots(snapshots);
}
@Override
public List getStateHistory(GlobalId globalId, QueryParams queryParams) {
argumentsAreNotNull(globalId, queryParams);
List snapshots = delegate.getStateHistory(globalId, queryParams);
if (globalId instanceof InstanceId && queryParams.isAggregate()) {
return loadMasterEntitySnapshotIfNecessary((InstanceId) globalId, snapshots);
} else {
return snapshots;
}
}
@Override
public List getValueObjectStateHistory(EntityType ownerEntity, String path, QueryParams queryParams) {
argumentsAreNotNull(ownerEntity, path, queryParams);
return delegate.getValueObjectStateHistory(ownerEntity, path, queryParams);
}
@Override
public Optional getLatest(GlobalId globalId) {
argumentIsNotNull(globalId);
return delegate.getLatest(globalId);
}
@Override
public List getLatest(Collection globalIds) {
argumentIsNotNull(globalIds);
return delegate.getLatest(globalIds);
}
/**
* last snapshot with commitId <= given timePoint
*/
public List getHistoricals(GlobalId globalId, CommitId timePoint, boolean withChildValueObjects, int limit) {
argumentsAreNotNull(globalId, timePoint);
return delegate.getStateHistory(globalId, QueryParamsBuilder
.withLimit(limit)
.withChildValueObjects(withChildValueObjects)
.toCommitId(timePoint).build());
}
/**
* last snapshot with commitId <= given date
*/
public Optional getHistorical(GlobalId globalId, LocalDateTime timePoint) {
argumentsAreNotNull(globalId, timePoint);
return delegate.getStateHistory(globalId, QueryParamsBuilder.withLimit(1).to(timePoint).build())
.stream().findFirst();
}
public List getHistoricals(GlobalId globalId, LocalDateTime timePoint, boolean withChildValueObjects, int limit) {
argumentsAreNotNull(globalId, timePoint);
return delegate.getStateHistory(globalId, QueryParamsBuilder
.withLimit(limit)
.withChildValueObjects(withChildValueObjects)
.to(timePoint).build());
}
@Override
public List getSnapshots(QueryParams queryParams) {
argumentsAreNotNull(queryParams);
return delegate.getSnapshots(queryParams);
}
@Override
public List getSnapshots(Collection snapshotIdentifiers) {
argumentIsNotNull(snapshotIdentifiers);
return delegate.getSnapshots(snapshotIdentifiers);
}
@Override
public List getStateHistory(Set givenClasses, QueryParams queryParams) {
return delegate.getStateHistory(givenClasses, queryParams);
}
@Override
public void persist(Commit commit) {
delegate.persist(commit);
}
@Override
public CommitId getHeadId() {
return delegate.getHeadId();
}
@Override
public void setJsonConverter(JsonConverter jsonConverter) {
}
@Override
public void ensureSchema() {
delegate.ensureSchema();
}
private List filterChangesByPropertyNames(List changes, final QueryParams queryParams) {
if (queryParams.changedProperties().size() == 0){
return changes;
}
return Lists.positiveFilter(changes, input -> input instanceof PropertyChange &&
queryParams.changedProperties().contains(((PropertyChange) input).getPropertyName()));
}
private List getChangesIntroducedBySnapshots(List snapshots) {
return snapshotDiffer.calculateDiffs(snapshots, previousSnapshotsCalculator.calculate(snapshots));
}
//required for the corner case, when valueObject snapshots consume all the limit
private List loadMasterEntitySnapshotIfNecessary(InstanceId instanceId, List alreadyLoaded) {
if (alreadyLoaded.isEmpty()) {
return alreadyLoaded;
}
if (alreadyLoaded.stream().filter(s -> s.getGlobalId().equals(instanceId)).findFirst().isPresent()) {
return alreadyLoaded;
}
return getLatest(instanceId).map(it -> {
List enhanced = new ArrayList(alreadyLoaded);
enhanced.add(it);
return java.util.Collections.unmodifiableList(enhanced);
}).orElse(alreadyLoaded);
}
}