package org.javers.core.metamodel.object; import org.javers.common.validation.Validate; import org.javers.core.commit.CommitId; import org.javers.core.commit.CommitMetadata; import org.javers.core.metamodel.property.Property; import org.javers.core.metamodel.type.ManagedType; import java.util.List; import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.BiFunction; import static java.util.Collections.unmodifiableList; import static org.javers.common.validation.Validate.argumentIsNotNull; import static org.javers.core.metamodel.object.SnapshotType.INITIAL; import static org.javers.core.metamodel.object.SnapshotType.TERMINAL; /** * Historical state of a domain object captured as the property->value Map. * Values and primitives are stored 'by value'. * Referenced Entities and ValueObjects are stored 'by reference' using {@link GlobalId} * * @author bartosz walacik */ public final class CdoSnapshot extends Cdo { private CommitMetadata commitMetadata; private final CdoSnapshotState state; private final SnapshotType type; private final List<String> changed; private final long version; /** * should be assembled by {@link CdoSnapshotBuilder} */ CdoSnapshot(GlobalId globalId, CommitMetadata commitMetadata, CdoSnapshotState state, SnapshotType type, List<String> changed, ManagedType managedType, long version) { super(globalId, managedType); Validate.argumentsAreNotNull(state, commitMetadata, type, managedType); this.state = state; this.commitMetadata = commitMetadata; this.type = type; this.changed = changed; this.version = version; } /** * @return {@link Optional#EMPTY} */ @Override public Optional<Object> getWrappedCdo() { return Optional.empty(); } public int size() { return state.size(); } @Override public Object getPropertyValue(String propertyName) { return state.getPropertyValue(propertyName); } /** * returns default values for null primitives */ @Override public Object getPropertyValue(Property property) { return state.getPropertyValue(property); } /** * List of propertyNames changed with this snapshot * (comparing to latest from repository). * <br/> * For initial snapshot, returns all properties. */ public List<String> getChanged() { return unmodifiableList(changed); } public boolean hasChangeAt(String propertyName) { argumentIsNotNull(propertyName); return changed.contains(propertyName); } @Override public boolean isNull(Property property) { Validate.argumentIsNotNull(property); return state.isNull(property.getName()); } public CommitId getCommitId() { return commitMetadata.getId(); } public CommitMetadata getCommitMetadata() { return commitMetadata; } public boolean stateEquals(Object o) { if (o == null || getClass() != o.getClass()) { return false; } CdoSnapshot other = (CdoSnapshot) o; return this.state.equals(other.state); } public CdoSnapshotState getState() { return state; } <R> List<R> mapProperties(BiFunction<String, Object, R> mapper) { return getState().mapProperties(mapper); } void forEachProperty(BiConsumer<String, Object> consumer) { getState().forEachProperty(consumer); } public boolean isInitial() { return type == INITIAL; } public boolean isTerminal() { return type == TERMINAL; } public SnapshotType getType() { return type; } /** * Object version number.<br/> * Initial snapshot of given object has version 1, next has version 2. * <br/><br/> * * <b>Warning!</b> Version field was added in JaVers v. 1.4.4. * All snapshots persisted in JaversRepository before this release * have version 0. * <br/> * If it isn't OK for you, run manual DB update. * See <a href="http://javers.org/documentation/features/#release-notes">release-notes</a> * for v. 1.4.4 * * @since 1.4.4 */ public long getVersion() { return version; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder .append("Snapshot{commit:").append(getCommitMetadata().getId()).append(", ") .append("id:").append(getGlobalId()).append(", ") .append("version:").append(getVersion()).append(", ") .append(getState()+"}"); return stringBuilder.toString(); } }