package org.javers.repository.api; import org.javers.core.metamodel.object.CdoSnapshot; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import static org.javers.common.collections.Lists.toImmutableList; class PreviousSnapshotsCalculator { private final Function<Collection<SnapshotIdentifier>, List<CdoSnapshot>> snapshotProvider; PreviousSnapshotsCalculator(Function<Collection<SnapshotIdentifier>, List<CdoSnapshot>> snapshotProvider) { this.snapshotProvider = snapshotProvider; } /** * Returns a Map from snapshot.id to snapshot with this id. * The Map contains entries for all previous snapshots. * I.e, for each snapshot S from a given list, there is a map entry for S.id.previous() */ Map<SnapshotIdentifier, CdoSnapshot> calculate(List<CdoSnapshot> snapshots) { Map<SnapshotIdentifier, CdoSnapshot> previousSnapshots = new HashMap<>(); populatePreviousSnapshotsWithSnapshots(previousSnapshots, snapshots); List<CdoSnapshot> missingPreviousSnapshots = getMissingPreviousSnapshots(snapshots, previousSnapshots); populatePreviousSnapshotsWithSnapshots(previousSnapshots, missingPreviousSnapshots); return previousSnapshots; } private List<CdoSnapshot> getSnapshots(Collection<SnapshotIdentifier> identifiers) { return snapshotProvider.apply(identifiers); } private void populatePreviousSnapshotsWithSnapshots(Map<SnapshotIdentifier, CdoSnapshot> previousSnapshots, List<CdoSnapshot> snapshots) { for (CdoSnapshot snapshot : snapshots) { previousSnapshots.put(SnapshotIdentifier.from(snapshot), snapshot); } } private List<CdoSnapshot> getMissingPreviousSnapshots(List<CdoSnapshot> snapshots, Map<SnapshotIdentifier, CdoSnapshot> previousSnapshots) { List<SnapshotIdentifier> missingPreviousSnapshotIdentifiers = determineMissingPreviousSnapshotIdentifiers(previousSnapshots, snapshots); return getSnapshots(missingPreviousSnapshotIdentifiers); } private List<SnapshotIdentifier> determineMissingPreviousSnapshotIdentifiers(Map<SnapshotIdentifier, CdoSnapshot> previousSnapshots, List<CdoSnapshot> snapshots) { List<SnapshotIdentifier> missingPreviousSnapshotIdentifiers = snapshots.stream() .filter(snapshot -> !(snapshot.isInitial() || snapshot.isTerminal())) .map(snapshot -> SnapshotIdentifier.from(snapshot).previous()) .filter(previousSnapshotIdentifier -> !previousSnapshots.containsKey(previousSnapshotIdentifier)) .collect(toImmutableList()); return missingPreviousSnapshotIdentifiers; } }