All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.javers.repository.api.JaversExtendedRepository Maven / Gradle / Ivy

There is a newer version: 7.6.1
Show newest version
package org.javers.repository.api;

import org.javers.common.collections.Lists;
import org.javers.common.string.ToStringBuilder;
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.JaversType;
import org.javers.core.metamodel.type.ManagedType;
import org.javers.core.snapshot.SnapshotDiffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

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(queryParams.newObjectChanges() ? snapshots : skipInitial(snapshots));

        return filterByPropertyName(changes, queryParams);
    }

    public List getChangeHistory(Set givenClasses, QueryParams queryParams) {
        argumentsAreNotNull(givenClasses, queryParams);

        List snapshots = getStateHistory(givenClasses, queryParams);
        List changes = getChangesIntroducedBySnapshots(queryParams.newObjectChanges() ? snapshots : skipInitial(snapshots));
        return filterByPropertyName(changes, queryParams);
    }

    public List getValueObjectChangeHistory(EntityType ownerEntity, String path, QueryParams queryParams) {
        argumentsAreNotNull(ownerEntity, path, queryParams);

        List snapshots = getValueObjectStateHistory(ownerEntity, path, queryParams);
        return getChangesIntroducedBySnapshots(queryParams.newObjectChanges() ? snapshots : skipInitial(snapshots));
    }

    public List getChanges(boolean newObjects, QueryParams queryParams) {
        argumentsAreNotNull(queryParams);

        List snapshots = getSnapshots(queryParams);
        return getChangesIntroducedBySnapshots(newObjects ? snapshots : skipInitial(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);
    }

    /**
     * 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();
    }

    @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 filterByPropertyName(List changes, final QueryParams queryParams) {
        if (!queryParams.changedProperty().isPresent()){
            return changes;
        }

        return Lists.positiveFilter(changes, input -> input instanceof PropertyChange &&
                ((PropertyChange) input).getPropertyName().equals(queryParams.changedProperty().get()));
    }

    private List skipInitial(List snapshots) {
        return Lists.negativeFilter(snapshots, snapshot -> snapshot.isInitial());
    }

    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.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);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy