From 88eddffbca821e792026fc1367bd146901f06c0a Mon Sep 17 00:00:00 2001 From: "bartosz.walacik" Date: Sun, 11 Jan 2015 01:26:21 +0100 Subject: [PATCH] https://github.com/javers/javers/issues/71 tracking Removed objects --- .../common/exception/JaversExceptionCode.java | 11 ++-- .../java/org/javers/core/GraphFactory.java | 41 ------------- .../src/main/java/org/javers/core/Javers.java | 40 ++++++++----- .../java/org/javers/core/JaversBuilder.java | 2 + .../core/changelog/ChangeListTraverser.java | 3 +- .../core/changelog/SimpleTextChangeLog.java | 2 +- .../org/javers/core/commit/CommitFactory.java | 59 ++++++++++++++----- .../org/javers/core/diff/DiffFactory.java | 35 +++++++---- .../core/diff/changetype/NewObject.java | 6 ++ .../core/diff/changetype/ObjectRemoved.java | 6 ++ .../javers/core/graph/LiveGraphFactory.java | 5 ++ .../commit/CommitIdTypeAdapter.java | 2 +- .../metamodel/object/SnapshotFactory.java | 17 ++++-- .../core/metamodel/type/TypeMapper.java | 2 +- .../javers/core/pico/CoreJaversModule.java | 12 +--- .../core/snapshot/GraphShadowFactory.java | 9 ++- .../core/snapshot/GraphSnapshotFacade.java | 37 ++++++++++++ .../core/snapshot/GraphSnapshotFactory.java | 19 +++--- .../core/snapshot/GraphSnapshotModule.java | 26 ++++++++ .../javers/core/snapshot/SnapshotDiffer.java | 36 +++++++---- .../javers/core/JaversCommitE2ETest.groovy | 26 ++++++-- .../core/JaversRepositoryE2ETest.groovy | 23 ++------ .../org/javers/core/JaversTestBuilder.groovy | 19 +++--- .../javers/core/commit/CommitAssert.groovy | 4 +- .../org/javers/core/diff/DiffAssert.groovy | 6 +- .../core/prettyprint/ChangeLogDemo.groovy | 8 ++- .../snapshot/GraphShadowFactoryTest.groovy | 7 ++- .../snapshot/GraphSnapshotFactoryTest.groovy | 25 ++++---- .../SnapshotDifferIntegrationTest.groovy | 25 +++++++- 29 files changed, 328 insertions(+), 185 deletions(-) delete mode 100644 javers-core/src/main/java/org/javers/core/GraphFactory.java create mode 100644 javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFacade.java create mode 100644 javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotModule.java diff --git a/javers-core/src/main/java/org/javers/common/exception/JaversExceptionCode.java b/javers-core/src/main/java/org/javers/common/exception/JaversExceptionCode.java index 30e8483c9..e9510e43d 100644 --- a/javers-core/src/main/java/org/javers/common/exception/JaversExceptionCode.java +++ b/javers-core/src/main/java/org/javers/common/exception/JaversExceptionCode.java @@ -5,7 +5,7 @@ * * @author Pawel Cierpiatka */ -public enum JaversExceptionCode { +public enum JaversExceptionCode { CLASS_EXTRACTION_ERROR(JaversException.BOOTSTRAP_ERROR + "Don't know how to extract Class from type '%s'.") , @@ -54,11 +54,14 @@ public enum JaversExceptionCode { CLASS_NOT_FOUND(JaversException.RUNTIME_ERROR+"class not found - '%s'") , - CANNOT_EXTRACT_CHILD_VALUE_OBJECT (JaversException.RUNTIME_ERROR+"error while extracting child ValueObject from '%s'" + + CANT_EXTRACT_CHILD_VALUE_OBJECT(JaversException.RUNTIME_ERROR+"error while extracting child ValueObject from '%s'" + ", invalid property type, expected ValueObjectType or ContainerType, got '%s'"), - CANNOT_PARSE_COMMIT_ID(JaversException.RUNTIME_ERROR+"cannot parse given value {'$s'} to CommitId. " + - "CommitId should consists of two parts : majorId.minorId e.g. 1.0") + CANT_PARSE_COMMIT_ID(JaversException.RUNTIME_ERROR+"can't parse given value {'%s'} to CommitId. " + + "CommitId should consists of two parts : majorId.minorId e.g. 1.0"), + + CANT_DELETE_OBJECT_NOT_FOUND(JaversException.RUNTIME_ERROR+"failed to delete object {'%s'}, "+ + "it doesn't exists in JaversRepository") ; diff --git a/javers-core/src/main/java/org/javers/core/GraphFactory.java b/javers-core/src/main/java/org/javers/core/GraphFactory.java deleted file mode 100644 index efbd5fc51..000000000 --- a/javers-core/src/main/java/org/javers/core/GraphFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.javers.core; - -import org.javers.core.commit.CommitMetadata; -import org.javers.core.graph.LiveGraph; -import org.javers.core.graph.LiveGraphFactory; -import org.javers.core.metamodel.object.CdoSnapshot; -import org.javers.core.snapshot.GraphShadowFactory; -import org.javers.core.snapshot.GraphSnapshotFactory; -import org.javers.core.snapshot.ShadowGraph; - -import java.util.List; - -/** - * Facade to all graph factories - * - * @author bartosz walacik - */ -public class GraphFactory { - private final GraphSnapshotFactory graphSnapshotFactory; - private final GraphShadowFactory graphShadowFactory; - private final LiveGraphFactory liveGraphFactory; - - public GraphFactory(GraphSnapshotFactory graphSnapshotFactory, GraphShadowFactory graphShadowFactory, LiveGraphFactory liveGraphFactory) { - this.graphSnapshotFactory = graphSnapshotFactory; - this.graphShadowFactory = graphShadowFactory; - this.liveGraphFactory = liveGraphFactory; - } - - public LiveGraph createLiveGraph(Object currentVersion) { - return liveGraphFactory.createLiveGraph(currentVersion); - } - - public ShadowGraph createLatestShadow(LiveGraph liveGraph){ - return graphShadowFactory.createLatestShadow(liveGraph); - } - - //capture current state - public List createGraphSnapshot(LiveGraph currentVersion, ShadowGraph latestShadowGraph, CommitMetadata commitMetadata){ - return graphSnapshotFactory.create(currentVersion, latestShadowGraph, commitMetadata); - } -} diff --git a/javers-core/src/main/java/org/javers/core/Javers.java b/javers-core/src/main/java/org/javers/core/Javers.java index c6d09affc..ea72a1541 100644 --- a/javers-core/src/main/java/org/javers/core/Javers.java +++ b/javers-core/src/main/java/org/javers/core/Javers.java @@ -1,26 +1,26 @@ package org.javers.core; import org.javers.common.collections.Optional; -import org.javers.core.changelog.ChangeProcessor; import org.javers.core.changelog.ChangeListTraverser; -import org.javers.core.commit.CommitMetadata; +import org.javers.core.changelog.ChangeProcessor; import org.javers.core.commit.Commit; import org.javers.core.commit.CommitFactory; +import org.javers.core.commit.CommitMetadata; import org.javers.core.diff.Change; import org.javers.core.diff.Diff; import org.javers.core.diff.DiffFactory; 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.GlobalIdDTO; import org.javers.core.metamodel.object.GlobalIdFactory; import org.javers.core.metamodel.type.JaversType; import org.javers.core.metamodel.type.TypeMapper; -import org.javers.core.snapshot.SnapshotDiffer; +import org.javers.core.snapshot.GraphSnapshotFacade; import org.javers.repository.api.JaversExtendedRepository; import org.javers.repository.api.JaversRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.javers.core.metamodel.object.GlobalId; import java.util.List; @@ -48,36 +48,48 @@ public class Javers { private final JsonConverter jsonConverter; private final CommitFactory commitFactory; private final JaversExtendedRepository repository; - private final SnapshotDiffer snapshotDiffer; + private final GraphSnapshotFacade graphSnapshotFacade; /** * JaVers instance should be constructed by {@link JaversBuilder} */ - public Javers(DiffFactory diffFactory, TypeMapper typeMapper, JsonConverter jsonConverter, CommitFactory commitFactory, JaversExtendedRepository repository, SnapshotDiffer snapshotDiffer) { + public Javers(DiffFactory diffFactory, TypeMapper typeMapper, JsonConverter jsonConverter, CommitFactory commitFactory, JaversExtendedRepository repository, GraphSnapshotFacade graphSnapshotFacade) { this.diffFactory = diffFactory; this.typeMapper = typeMapper; this.jsonConverter = jsonConverter; this.commitFactory = commitFactory; this.repository = repository; - this.snapshotDiffer = snapshotDiffer; + this.graphSnapshotFacade = graphSnapshotFacade; } /** - *

- * Persists current version of given domain object in JaVers repository. + * Persists current version of a given domain object in JaVers repository. * JaVers applies commit() to given object and all objects navigable from it. - * You can capture state of arbitrary complex objects graph with single commit() call. - *

+ * You can capture a state of an arbitrary complex objects graph with a single commit() call. * - * @param currentVersion Standalone object or handle to objects graph + * @param currentVersion Standalone object or handle to an objects graph */ public Commit commit(String author, Object currentVersion) { Commit commit = commitFactory.create(author, currentVersion); repository.persist(commit); - logger.info(commit.toString()); + return commit; + } + /** + * Marks given object as deleted. + * + * This method doesn't delete anything from JaVers repository. + * It just persists 'terminal snapshot' of given object. + * + * @param deleted object to be marked as deleted + */ + public Commit commitDelete(String author, Object deleted) { + Commit commit = commitFactory.createTerminal(author, deleted); + + repository.persist(commit); + logger.info(commit.toString()); return commit; } @@ -175,7 +187,7 @@ public Optional getLatestSnapshot(GlobalIdDTO globalId){ * @return empty List, if object is not versioned or was committed only once */ public List getChangeHistory(GlobalIdDTO globalId, int limit) { - return snapshotDiffer.getChangeHistory(globalId, limit); + return graphSnapshotFacade.getChangeHistory(globalId, limit); } JaversType getForClass(Class clazz) { diff --git a/javers-core/src/main/java/org/javers/core/JaversBuilder.java b/javers-core/src/main/java/org/javers/core/JaversBuilder.java index f3ee43924..f06998c0c 100644 --- a/javers-core/src/main/java/org/javers/core/JaversBuilder.java +++ b/javers-core/src/main/java/org/javers/core/JaversBuilder.java @@ -15,6 +15,7 @@ import org.javers.core.metamodel.type.ValueType; import org.javers.core.pico.CoreJaversModule; import org.javers.core.pico.JaversModule; +import org.javers.core.snapshot.GraphSnapshotModule; import org.javers.repository.api.InMemoryRepository; import org.javers.repository.api.JaversRepository; import org.picocontainer.PicoContainer; @@ -50,6 +51,7 @@ private JaversBuilder() { bootContainer(new CoreJaversModule()); addModule(new DiffAppendersModule(getContainer())); addModule(new CommitFactoryModule(getContainer())); + addModule(new GraphSnapshotModule(getContainer())); } public static JaversBuilder javers() { diff --git a/javers-core/src/main/java/org/javers/core/changelog/ChangeListTraverser.java b/javers-core/src/main/java/org/javers/core/changelog/ChangeListTraverser.java index a893f3374..d4fa8c631 100644 --- a/javers-core/src/main/java/org/javers/core/changelog/ChangeListTraverser.java +++ b/javers-core/src/main/java/org/javers/core/changelog/ChangeListTraverser.java @@ -3,7 +3,6 @@ import org.javers.common.collections.Optional; import org.javers.core.commit.CommitMetadata; import org.javers.core.diff.Change; -import org.javers.core.diff.Diff; import org.javers.core.diff.changetype.*; import org.javers.core.diff.changetype.container.ArrayChange; import org.javers.core.diff.changetype.container.ContainerChange; @@ -37,7 +36,7 @@ public static void traverse(List changes, ChangeProcessor renderer) { } if (!change.getAffectedGlobalId().equals(lastGlobalId) && - !(change instanceof NewObject)) { + !(change instanceof NewObject || change instanceof ObjectRemoved)) { renderer.onAffectedObject(change.getAffectedGlobalId()); } diff --git a/javers-core/src/main/java/org/javers/core/changelog/SimpleTextChangeLog.java b/javers-core/src/main/java/org/javers/core/changelog/SimpleTextChangeLog.java index 8aa2396a7..1beb57654 100644 --- a/javers-core/src/main/java/org/javers/core/changelog/SimpleTextChangeLog.java +++ b/javers-core/src/main/java/org/javers/core/changelog/SimpleTextChangeLog.java @@ -44,7 +44,7 @@ public SimpleTextChangeLog(DateTimeFormatter dateTimeFormatter) { @Override public void onCommit(CommitMetadata commitMetadata) { - appendln("commit " + commitMetadata.getId() + ", author:" + commitMetadata.getAuthor() + + appendln("commit " + commitMetadata.getId() + ", author: " + commitMetadata.getAuthor() + ", " + DEFAULT_DATE_FORMATTER.print(commitMetadata.getCommitDate())); } diff --git a/javers-core/src/main/java/org/javers/core/commit/CommitFactory.java b/javers-core/src/main/java/org/javers/core/commit/CommitFactory.java index 9de3833de..c2206cc6a 100644 --- a/javers-core/src/main/java/org/javers/core/commit/CommitFactory.java +++ b/javers-core/src/main/java/org/javers/core/commit/CommitFactory.java @@ -1,13 +1,19 @@ package org.javers.core.commit; +import org.javers.common.collections.Lists; import org.javers.common.collections.Optional; import org.javers.common.date.DateProvider; +import org.javers.common.exception.JaversException; +import org.javers.common.exception.JaversExceptionCode; import org.javers.common.validation.Validate; -import org.javers.core.GraphFactory; import org.javers.core.diff.Diff; import org.javers.core.diff.DiffFactory; import org.javers.core.graph.LiveGraph; +import org.javers.core.graph.LiveGraphFactory; +import org.javers.core.metamodel.object.Cdo; import org.javers.core.metamodel.object.CdoSnapshot; +import org.javers.core.metamodel.object.SnapshotFactory; +import org.javers.core.snapshot.GraphSnapshotFacade; import org.javers.core.snapshot.ShadowGraph; import org.javers.repository.api.JaversExtendedRepository; @@ -19,36 +25,52 @@ public class CommitFactory { private final DiffFactory diffFactory; private final JaversExtendedRepository javersRepository; - private final GraphFactory graphFactory; private final CommitSeqGenerator commitSeqGenerator; private final DateProvider dateProvider; + private final GraphSnapshotFacade graphSnapshotFacade; + private final LiveGraphFactory liveGraphFactory; + private final SnapshotFactory snapshotFactory; - public CommitFactory(DiffFactory diffFactory, - JaversExtendedRepository javersRepository, - GraphFactory graphFactory, - CommitSeqGenerator commitSeqGenerator, - DateProvider dateProvider) { + public CommitFactory(DiffFactory diffFactory, JaversExtendedRepository javersRepository, CommitSeqGenerator commitSeqGenerator, DateProvider dateProvider, GraphSnapshotFacade graphSnapshotFacade, LiveGraphFactory liveGraphFactory, SnapshotFactory snapshotFactory) { this.diffFactory = diffFactory; this.javersRepository = javersRepository; - this.graphFactory = graphFactory; this.commitSeqGenerator = commitSeqGenerator; this.dateProvider = dateProvider; + this.graphSnapshotFacade = graphSnapshotFacade; + this.liveGraphFactory = liveGraphFactory; + this.snapshotFactory = snapshotFactory; + } + + public Commit createTerminal(String author, Object removed){ + Validate.argumentsAreNotNull(author, removed); + + Cdo removedCdo = liveGraphFactory.createCdo(removed); + + if (javersRepository.getLatest(removedCdo.getGlobalId()).isEmpty()){ + throw new JaversException(JaversExceptionCode.CANT_DELETE_OBJECT_NOT_FOUND, removedCdo.getGlobalId().value()); + } + + CommitMetadata commitMetadata = nextCommit(author); + + CdoSnapshot terminalSnapshot = + snapshotFactory.createTerminal(removedCdo.getGlobalId(), commitMetadata); + + Diff diff = diffFactory.singleTerminal(removedCdo, commitMetadata); + + return new Commit(commitMetadata, Lists.asList(terminalSnapshot), diff); } public Commit create(String author, Object currentVersion){ Validate.argumentsAreNotNull(author, currentVersion); - CommitId head = javersRepository.getHeadId(); - CommitId newId = commitSeqGenerator.nextId(head); + CommitMetadata commitMetadata = nextCommit(author); - LiveGraph currentGraph = graphFactory.createLiveGraph(currentVersion); - ShadowGraph latestShadowGraph = graphFactory.createLatestShadow(currentGraph); - - CommitMetadata commitMetadata = new CommitMetadata(author, dateProvider.now(), newId); + LiveGraph currentGraph = liveGraphFactory.createLiveGraph(currentVersion); + ShadowGraph latestShadowGraph = graphSnapshotFacade.createLatestShadow(currentGraph); //capture current state List snapshots = - graphFactory.createGraphSnapshot(currentGraph, latestShadowGraph, commitMetadata); + graphSnapshotFacade.createGraphSnapshot(currentGraph, latestShadowGraph, commitMetadata); //do diff Diff diff = diffFactory.create(latestShadowGraph, currentGraph, Optional.of(commitMetadata)); @@ -56,4 +78,11 @@ public Commit create(String author, Object currentVersion){ return new Commit(commitMetadata, snapshots, diff); } + private CommitMetadata nextCommit(String author){ + CommitId head = javersRepository.getHeadId(); + CommitId newId = commitSeqGenerator.nextId(head); + + return new CommitMetadata(author, dateProvider.now(), newId); + } + } diff --git a/javers-core/src/main/java/org/javers/core/diff/DiffFactory.java b/javers-core/src/main/java/org/javers/core/diff/DiffFactory.java index 3c7c35d87..e353e68f8 100644 --- a/javers-core/src/main/java/org/javers/core/diff/DiffFactory.java +++ b/javers-core/src/main/java/org/javers/core/diff/DiffFactory.java @@ -3,14 +3,18 @@ import org.javers.common.collections.Consumer; import org.javers.common.collections.Optional; import org.javers.common.validation.Validate; -import org.javers.core.GraphFactory; import org.javers.core.Javers; import org.javers.core.JaversCoreConfiguration; import org.javers.core.commit.CommitMetadata; import org.javers.core.diff.appenders.NodeChangeAppender; import org.javers.core.diff.appenders.PropertyChangeAppender; +import org.javers.core.diff.changetype.NewObject; +import org.javers.core.diff.changetype.ObjectRemoved; import org.javers.core.graph.LiveGraph; +import org.javers.core.graph.LiveGraphFactory; import org.javers.core.graph.ObjectNode; +import org.javers.core.metamodel.object.Cdo; +import org.javers.core.metamodel.object.CdoSnapshot; import org.javers.core.metamodel.property.Property; import org.javers.core.metamodel.type.JaversType; import org.javers.core.metamodel.type.TypeMapper; @@ -29,10 +33,10 @@ public class DiffFactory { private final TypeMapper typeMapper; private final List nodeChangeAppenders; private final List propertyChangeAppender; - private final GraphFactory graphFactory; + private final LiveGraphFactory graphFactory; private final JaversCoreConfiguration javersCoreConfiguration; - public DiffFactory(JaversCoreConfiguration javersCoreConfiguration, TypeMapper typeMapper, List nodeChangeAppenders, List propertyChangeAppender, GraphFactory graphFactory) { + public DiffFactory(TypeMapper typeMapper, List nodeChangeAppenders, List propertyChangeAppender, LiveGraphFactory graphFactory, JaversCoreConfiguration javersCoreConfiguration) { this.typeMapper = typeMapper; this.nodeChangeAppenders = nodeChangeAppenders; this.propertyChangeAppender = propertyChangeAppender; @@ -40,13 +44,6 @@ public DiffFactory(JaversCoreConfiguration javersCoreConfiguration, TypeMapper t this.javersCoreConfiguration = javersCoreConfiguration; } - /** - * @see Javers#initial(Object) - */ - public Diff initial(Object newDomainObject) { - return createInitial(buildGraph(newDomainObject)); - } - /** * @see Javers#compare(Object, Object) */ @@ -61,8 +58,22 @@ public Diff create(ObjectGraph leftGraph, ObjectGraph rightGraph, Optionalempty()); diff --git a/javers-core/src/main/java/org/javers/core/diff/changetype/NewObject.java b/javers-core/src/main/java/org/javers/core/diff/changetype/NewObject.java index e6ccdbc7d..afc0abe39 100644 --- a/javers-core/src/main/java/org/javers/core/diff/changetype/NewObject.java +++ b/javers-core/src/main/java/org/javers/core/diff/changetype/NewObject.java @@ -1,6 +1,7 @@ package org.javers.core.diff.changetype; import org.javers.common.collections.Optional; +import org.javers.core.commit.CommitMetadata; import org.javers.core.diff.Change; import org.javers.core.metamodel.object.GlobalId; @@ -14,4 +15,9 @@ public NewObject(GlobalId newId, Optional newCdo) { super(newId); setAffectedCdo(newCdo); } + + public NewObject(GlobalId newId, Optional newCdo, CommitMetadata commitMetadata) { + this(newId, newCdo); + bindToCommit(commitMetadata); + } } diff --git a/javers-core/src/main/java/org/javers/core/diff/changetype/ObjectRemoved.java b/javers-core/src/main/java/org/javers/core/diff/changetype/ObjectRemoved.java index 7145c14f2..1d9e2ef26 100644 --- a/javers-core/src/main/java/org/javers/core/diff/changetype/ObjectRemoved.java +++ b/javers-core/src/main/java/org/javers/core/diff/changetype/ObjectRemoved.java @@ -1,6 +1,7 @@ package org.javers.core.diff.changetype; import org.javers.common.collections.Optional; +import org.javers.core.commit.CommitMetadata; import org.javers.core.diff.Change; import org.javers.core.metamodel.object.GlobalId; @@ -14,4 +15,9 @@ public ObjectRemoved(GlobalId removed, Optional removedCdo) { super(removed); setAffectedCdo(removedCdo); } + + public ObjectRemoved(GlobalId removed, Optional removedCdo, CommitMetadata commitMetadata) { + this(removed, removedCdo); + bindToCommit(commitMetadata); + } } diff --git a/javers-core/src/main/java/org/javers/core/graph/LiveGraphFactory.java b/javers-core/src/main/java/org/javers/core/graph/LiveGraphFactory.java index 68c06d60f..3e5d7deb0 100644 --- a/javers-core/src/main/java/org/javers/core/graph/LiveGraphFactory.java +++ b/javers-core/src/main/java/org/javers/core/graph/LiveGraphFactory.java @@ -1,5 +1,6 @@ package org.javers.core.graph; +import org.javers.core.metamodel.object.Cdo; import org.javers.core.metamodel.type.TypeMapper; import java.util.List; @@ -27,6 +28,10 @@ public LiveGraph createLiveGraph(Object handle) { return new ObjectGraphBuilder(typeMapper, liveCdoFactory).buildGraph(wrappedHandle); } + public Cdo createCdo(Object cdo){ + return liveCdoFactory.create(cdo, null); + } + private Object wrapTopLevelContainer(Object handle){ if (handle instanceof Map){ return new MapWrapper((Map)handle); diff --git a/javers-core/src/main/java/org/javers/core/json/typeadapter/commit/CommitIdTypeAdapter.java b/javers-core/src/main/java/org/javers/core/json/typeadapter/commit/CommitIdTypeAdapter.java index 7741780fc..ee862a88f 100644 --- a/javers-core/src/main/java/org/javers/core/json/typeadapter/commit/CommitIdTypeAdapter.java +++ b/javers-core/src/main/java/org/javers/core/json/typeadapter/commit/CommitIdTypeAdapter.java @@ -23,7 +23,7 @@ public CommitId fromJson(JsonElement json, JsonDeserializationContext jsonDeseri String[] strings = majorDotMinor.split("\\."); if (strings.length != 2) { - throw new JaversException(JaversExceptionCode.CANNOT_PARSE_COMMIT_ID, majorDotMinor); + throw new JaversException(JaversExceptionCode.CANT_PARSE_COMMIT_ID, majorDotMinor); } long major = Long.parseLong(strings[0]); diff --git a/javers-core/src/main/java/org/javers/core/metamodel/object/SnapshotFactory.java b/javers-core/src/main/java/org/javers/core/metamodel/object/SnapshotFactory.java index 76b8affc2..be3e8f6ab 100644 --- a/javers-core/src/main/java/org/javers/core/metamodel/object/SnapshotFactory.java +++ b/javers-core/src/main/java/org/javers/core/metamodel/object/SnapshotFactory.java @@ -6,12 +6,13 @@ import org.javers.common.exception.JaversException; import org.javers.core.commit.CommitMetadata; import org.javers.core.graph.ObjectNode; -import org.javers.core.metamodel.object.*; import org.javers.core.metamodel.property.Property; import org.javers.core.metamodel.type.*; + import static org.javers.common.exception.JaversExceptionCode.GENERIC_TYPE_NOT_PARAMETRIZED; import static org.javers.common.exception.JaversExceptionCode.NOT_IMPLEMENTED; import static org.javers.core.metamodel.object.CdoSnapshotBuilder.cdoSnapshot; +import static org.javers.core.metamodel.object.SnapshotType.*; /** * @author bartosz walacik @@ -26,7 +27,7 @@ public SnapshotFactory(TypeMapper typeMapper, GlobalIdFactory globalIdFactory) { } CdoSnapshot create(Object liveCdo, GlobalId id, CommitMetadata commitMetadata) { - return create(liveCdo, id, commitMetadata, SnapshotType.UPDATE); + return create(liveCdo, id, commitMetadata, UPDATE); } /** @@ -58,8 +59,16 @@ CdoSnapshot create(Object liveCdo, GlobalId id, CommitMetadata commitMetadata, S return snapshot.build(); } - public CdoSnapshot create(ObjectNode objectNode, CommitMetadata commitMetadata, SnapshotType type) { - return create(objectNode.wrappedCdo().get(), objectNode.getGlobalId(), commitMetadata, type); + public CdoSnapshot createTerminal(GlobalId globalId, CommitMetadata commitMetadata) { + return cdoSnapshot(globalId, commitMetadata).withType(TERMINAL).build(); + } + + public CdoSnapshot createInitial(ObjectNode objectNode, CommitMetadata commitMetadata) { + return create(objectNode.wrappedCdo().get(), objectNode.getGlobalId(), commitMetadata, INITIAL); + } + + public CdoSnapshot create(ObjectNode objectNode, CommitMetadata commitMetadata) { + return create(objectNode.wrappedCdo().get(), objectNode.getGlobalId(), commitMetadata, UPDATE); } private Object extractAndDehydrateEnumerable(Object propertyVal, EnumerableType propertyType, OwnerContext owner) { diff --git a/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapper.java b/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapper.java index 77f4cb100..cf0de5b04 100644 --- a/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapper.java +++ b/javers-core/src/main/java/org/javers/core/metamodel/type/TypeMapper.java @@ -209,7 +209,7 @@ public ValueObject getChildValueObject(Entity owner, String voPropertyName) { } } - throw new JaversException(JaversExceptionCode.CANNOT_EXTRACT_CHILD_VALUE_OBJECT, + throw new JaversException(JaversExceptionCode.CANT_EXTRACT_CHILD_VALUE_OBJECT, owner.getName()+"."+voPropertyName, javersType); diff --git a/javers-core/src/main/java/org/javers/core/pico/CoreJaversModule.java b/javers-core/src/main/java/org/javers/core/pico/CoreJaversModule.java index fffdf410f..9536972e1 100644 --- a/javers-core/src/main/java/org/javers/core/pico/CoreJaversModule.java +++ b/javers-core/src/main/java/org/javers/core/pico/CoreJaversModule.java @@ -1,7 +1,6 @@ package org.javers.core.pico; import org.javers.common.date.DefaultDateProvider; -import org.javers.core.GraphFactory; import org.javers.core.Javers; import org.javers.core.JaversCoreConfiguration; import org.javers.core.diff.DiffFactory; @@ -10,12 +9,9 @@ import org.javers.core.graph.ObjectGraphBuilder; import org.javers.core.json.JsonConverterBuilder; import org.javers.core.metamodel.object.GlobalIdFactory; +import org.javers.core.metamodel.object.SnapshotFactory; import org.javers.core.metamodel.type.TypeFactory; import org.javers.core.metamodel.type.TypeMapper; -import org.javers.core.snapshot.GraphShadowFactory; -import org.javers.core.snapshot.GraphSnapshotFactory; -import org.javers.core.snapshot.SnapshotDiffer; -import org.javers.core.metamodel.object.SnapshotFactory; import org.javers.repository.api.JaversExtendedRepository; import java.util.Arrays; @@ -35,15 +31,11 @@ public class CoreJaversModule implements JaversModule { TypeFactory.class, JaversCoreConfiguration.class, SnapshotFactory.class, - GraphSnapshotFactory.class, - GraphShadowFactory.class, JaversExtendedRepository.class, LiveCdoFactory.class, LiveGraphFactory.class, GlobalIdFactory.class, - GraphFactory.class, - DefaultDateProvider.class, - SnapshotDiffer.class + DefaultDateProvider.class }; @Override diff --git a/javers-core/src/main/java/org/javers/core/snapshot/GraphShadowFactory.java b/javers-core/src/main/java/org/javers/core/snapshot/GraphShadowFactory.java index 40d8698a3..4c9648378 100644 --- a/javers-core/src/main/java/org/javers/core/snapshot/GraphShadowFactory.java +++ b/javers-core/src/main/java/org/javers/core/snapshot/GraphShadowFactory.java @@ -17,17 +17,16 @@ * * @author bartosz walacik */ -public class GraphShadowFactory { +class GraphShadowFactory { private final JaversExtendedRepository javersRepository; - public GraphShadowFactory(JaversExtendedRepository javersRepository) { + GraphShadowFactory(JaversExtendedRepository javersRepository) { this.javersRepository = javersRepository; } - public ShadowGraph createLatestShadow(LiveGraph liveGraph){ + ShadowGraph createLatestShadow(LiveGraph liveGraph){ Validate.argumentIsNotNull(liveGraph); - Set snapshotNodes = new HashSet<>(); for (ObjectNode liveNode : liveGraph.nodes()){ Optional snapshot = javersRepository.getLatest(liveNode.getGlobalId()); @@ -42,7 +41,7 @@ public ShadowGraph createLatestShadow(LiveGraph liveGraph){ return new ShadowGraph(snapshotNodes); } - public ShadowGraph createFromSnapshot(CdoSnapshot cdoSnapshot){ + ShadowGraph createFromSnapshot(CdoSnapshot cdoSnapshot){ return new ShadowGraph(Sets.asSet(new ObjectNode(cdoSnapshot))); } } diff --git a/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFacade.java b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFacade.java new file mode 100644 index 000000000..72fc414b3 --- /dev/null +++ b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFacade.java @@ -0,0 +1,37 @@ +package org.javers.core.snapshot; + +import org.javers.core.commit.CommitMetadata; +import org.javers.core.diff.Change; +import org.javers.core.graph.LiveGraph; +import org.javers.core.metamodel.object.CdoSnapshot; +import org.javers.core.metamodel.object.GlobalIdDTO; + +import java.util.List; + +/** + * @author bartosz walacik + */ +public class GraphSnapshotFacade { + private final SnapshotDiffer snapshotDiffer; + private final GraphSnapshotFactory graphSnapshotFactory; + private final GraphShadowFactory graphShadowFactory; + + public GraphSnapshotFacade(SnapshotDiffer snapshotDiffer, GraphSnapshotFactory graphSnapshotFactory, GraphShadowFactory graphShadowFactory) { + this.snapshotDiffer = snapshotDiffer; + this.graphSnapshotFactory = graphSnapshotFactory; + this.graphShadowFactory = graphShadowFactory; + } + + public List getChangeHistory(GlobalIdDTO globalId, int limit) { + return snapshotDiffer.getChangeHistory(globalId, limit); + } + + + public ShadowGraph createLatestShadow(LiveGraph currentGraph) { + return graphShadowFactory.createLatestShadow(currentGraph); + } + + public List createGraphSnapshot(LiveGraph currentGraph, ShadowGraph latestShadowGraph, CommitMetadata commitMetadata) { + return graphSnapshotFactory.create(currentGraph, latestShadowGraph, commitMetadata); + } +} diff --git a/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFactory.java b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFactory.java index 1a11a054d..9c177626d 100644 --- a/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFactory.java +++ b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotFactory.java @@ -20,12 +20,12 @@ * * @author bartosz walacik */ -public class GraphSnapshotFactory { +class GraphSnapshotFactory { private final SnapshotFactory snapshotFactory; private final JaversExtendedRepository javersRepository; - public GraphSnapshotFactory(SnapshotFactory snapshotFactory, JaversExtendedRepository javersRepository) { + GraphSnapshotFactory(SnapshotFactory snapshotFactory, JaversExtendedRepository javersRepository) { this.snapshotFactory = snapshotFactory; this.javersRepository = javersRepository; } @@ -33,14 +33,21 @@ public GraphSnapshotFactory(SnapshotFactory snapshotFactory, JaversExtendedRepos /** * @param currentVersion outcome from {@link ObjectGraphBuilder#buildGraph(Object)} */ - public List create(LiveGraph currentVersion, ShadowGraph latestShadowGraph, CommitMetadata commitMetadata){ + List create(LiveGraph currentVersion, ShadowGraph latestShadowGraph, CommitMetadata commitMetadata){ Validate.argumentsAreNotNull(currentVersion, commitMetadata, latestShadowGraph); List reused = new ArrayList<>(); for (ObjectNode node : currentVersion.nodes()) { boolean initial = isInitial(node, latestShadowGraph); - CdoSnapshot fresh = snapshotFactory.create(node, commitMetadata, toType(initial)); + + CdoSnapshot fresh; + if (initial){ + fresh = snapshotFactory.createInitial(node, commitMetadata); + } + else{ + fresh = snapshotFactory.create(node, commitMetadata); + } Optional existing = javersRepository.getLatest(fresh.getGlobalId()); if (existing.isEmpty()) { @@ -60,10 +67,6 @@ List create(LiveGraph currentVersion, CommitMetadata commitMetadata return create(currentVersion, ShadowGraph.EMPTY, commitMetadata); } - private SnapshotType toType(boolean initial){ - return initial ? SnapshotType.INITIAL : SnapshotType.UPDATE; - } - private boolean isInitial(ObjectNode node, ShadowGraph latestShadowGraph){ return !latestShadowGraph.nodes().contains(node); } diff --git a/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotModule.java b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotModule.java new file mode 100644 index 000000000..1415be24f --- /dev/null +++ b/javers-core/src/main/java/org/javers/core/snapshot/GraphSnapshotModule.java @@ -0,0 +1,26 @@ +package org.javers.core.snapshot; + +import org.javers.common.collections.Lists; +import org.javers.core.pico.InstantiatingModule; +import org.picocontainer.MutablePicoContainer; + +import java.util.Collection; + +/** + * @author bartosz walacik + */ +public class GraphSnapshotModule extends InstantiatingModule { + public GraphSnapshotModule(MutablePicoContainer container) { + super(container); + } + + @Override + protected Collection getImplementations() { + return (Collection) Lists.asList( + GraphSnapshotFacade.class, + GraphSnapshotFactory.class, + SnapshotDiffer.class, + GraphShadowFactory.class + ); + } +} diff --git a/javers-core/src/main/java/org/javers/core/snapshot/SnapshotDiffer.java b/javers-core/src/main/java/org/javers/core/snapshot/SnapshotDiffer.java index 83575d88b..84074ed29 100644 --- a/javers-core/src/main/java/org/javers/core/snapshot/SnapshotDiffer.java +++ b/javers-core/src/main/java/org/javers/core/snapshot/SnapshotDiffer.java @@ -8,11 +8,13 @@ import org.javers.core.diff.Diff; import org.javers.core.diff.DiffFactory; import org.javers.core.diff.changetype.NewObject; -import org.javers.core.metamodel.object.*; +import org.javers.core.diff.changetype.ObjectRemoved; +import org.javers.core.metamodel.object.CdoSnapshot; +import org.javers.core.metamodel.object.GlobalIdDTO; +import org.javers.core.metamodel.object.InstanceIdDTO; import org.javers.repository.api.JaversExtendedRepository; import java.util.ArrayList; -import java.util.Collections; import java.util.List; /** @@ -21,13 +23,13 @@ * * @author bartosz walacik */ -public class SnapshotDiffer { +class SnapshotDiffer { private final JaversExtendedRepository javersExtendedRepository; private final GraphShadowFactory graphShadowFactory; private final DiffFactory diffFactory; - public SnapshotDiffer(JaversExtendedRepository javersExtendedRepository, GraphShadowFactory graphShadowFactory, DiffFactory diffFactory) { + SnapshotDiffer(JaversExtendedRepository javersExtendedRepository, GraphShadowFactory graphShadowFactory, DiffFactory diffFactory) { this.javersExtendedRepository = javersExtendedRepository; this.graphShadowFactory = graphShadowFactory; this.diffFactory = diffFactory; @@ -38,24 +40,32 @@ public SnapshotDiffer(JaversExtendedRepository javersExtendedRepository, GraphSh * * @throws JaversException ENTITY_EXPECTED if given javaClass is NOT mapped to Entity */ - public List getChangeHistory(Object localId, Class entityClass, int limit){ + List getChangeHistory(Object localId, Class entityClass, int limit){ return getChangeHistory(InstanceIdDTO.instanceId(localId,entityClass),limit); } /** * Changes (diff sequence) of given managed class instance, in reverse chronological order */ - public List getChangeHistory(GlobalIdDTO globalCdoId, int limit) { + List getChangeHistory(GlobalIdDTO globalCdoId, int limit) { Validate.argumentsAreNotNull(globalCdoId); - List snapshots = javersExtendedRepository.getStateHistory(globalCdoId, limit); + List snapshots = javersExtendedRepository.getStateHistory(globalCdoId, limit); List result = new ArrayList<>(); + addObjectRemovedIfTerminal(result, snapshots.get(0)); + //compare pair-by-pair if (snapshots.size() > 1){ for (int i = 0; i getChangeHistory(GlobalIdDTO globalCdoId, int limit) { return result; } + private void addObjectRemovedIfTerminal(List changes, CdoSnapshot last) { + if (last.isTerminal()){ + changes.add(new ObjectRemoved(last.getGlobalId(), Optional.empty(), last.getCommitMetadata())); + } + } + private void addNewObjectIfInitial(List changes, CdoSnapshot first) { if (first.isInitial()){ - Diff diff = diffFactory.create(ShadowGraph.EMPTY, - fromSnapshot(first), Optional.of(first.getCommitMetadata())); - changes.add(diff.getChangesByType(NewObject.class).get(0)); + changes.add(new NewObject(first.getGlobalId(), Optional.empty(), first.getCommitMetadata())); } } diff --git a/javers-core/src/test/groovy/org/javers/core/JaversCommitE2ETest.groovy b/javers-core/src/test/groovy/org/javers/core/JaversCommitE2ETest.groovy index 36b5445cd..31ddca8c0 100644 --- a/javers-core/src/test/groovy/org/javers/core/JaversCommitE2ETest.groovy +++ b/javers-core/src/test/groovy/org/javers/core/JaversCommitE2ETest.groovy @@ -1,7 +1,8 @@ package org.javers.core +import org.javers.common.exception.JaversException +import org.javers.common.exception.JaversExceptionCode import org.javers.core.commit.CommitAssert -import org.javers.core.diff.changetype.ObjectRemoved import org.javers.core.model.DummyAddress import org.javers.core.model.DummyUser import org.javers.core.model.DummyUserDetails @@ -22,16 +23,31 @@ class JaversCommitE2ETest extends Specification { given: def javers = javers().build() def anEntity = new SnapshotEntity(id:1, entityRef: new SnapshotEntity(id:2)) - javers.commit(anEntity) + javers.commit("some.login", anEntity) when: - def commit = javers.commitDelete(anEntity) + def commit = javers.commitDelete("some.login", anEntity) then: CommitAssert.assertThat(commit) - .hasChanges(2, ObjectRemoved) + .hasId("2.0") + .hasChanges(1) + .hasObjectRemoved(instanceId(1,SnapshotEntity), anEntity) + .hasSnapshots(1) .hasTerminalSnapshot(instanceId(1,SnapshotEntity)) - .hasTerminalSnapshot(instanceId(2,SnapshotEntity)) + } + + def "should fail when deleting non existing object"() { + given: + def javers = javers().build() + def anEntity = new SnapshotEntity(id:1) + + when: + javers.commitDelete("some.login", anEntity) + + then: + JaversException exception = thrown() + exception.code == JaversExceptionCode.CANT_DELETE_OBJECT_NOT_FOUND } def "should create initial commit for new objects"() { diff --git a/javers-core/src/test/groovy/org/javers/core/JaversRepositoryE2ETest.groovy b/javers-core/src/test/groovy/org/javers/core/JaversRepositoryE2ETest.groovy index 0e49babc5..21b26abf1 100644 --- a/javers-core/src/test/groovy/org/javers/core/JaversRepositoryE2ETest.groovy +++ b/javers-core/src/test/groovy/org/javers/core/JaversRepositoryE2ETest.groovy @@ -1,7 +1,6 @@ package org.javers.core import org.javers.core.diff.changetype.NewObject -import org.javers.core.diff.changetype.ObjectRemoved import org.javers.core.diff.changetype.ValueChange import org.javers.core.model.DummyAddress import org.javers.core.model.DummyUser @@ -24,33 +23,21 @@ class JaversRepositoryE2ETest extends Specification { javers = javers().build() } - def "should fetch terminal snapshots and changed from the repository"() { + def "should fetch terminal snapshots from the repository"() { given: def anEntity = new SnapshotEntity(id:1, entityRef: new SnapshotEntity(id:2)) - javers.commit(anEntity) - javers.commitDelete(anEntity) + javers.commit("author", anEntity) + javers.commitDelete("author", anEntity) when: - def topSnapshots = javers.getStateHistory(instanceId(1, SnapshotEntity), 10) - def bottomSnapshots = javers.getStateHistory(instanceId(2, SnapshotEntity), 10) + def snapshots = javers.getStateHistory(instanceId(1, SnapshotEntity), 10) then: - SnapshotsAssert.assertThat(topSnapshots) + SnapshotsAssert.assertThat(snapshots) .hasSize(2) .hasOrdinarySnapshot(instanceId(1,SnapshotEntity)) .hasTerminalSnapshot(instanceId(1,SnapshotEntity), "2.0") - SnapshotsAssert.assertThat(bottomSnapshots) - .hasSize(2) - .hasOrdinarySnapshot(instanceId(2,SnapshotEntity)) - .hasTerminalSnapshot(instanceId(2,SnapshotEntity), "2.0") - when: - def topChanges = javers.getChangeHistory(instanceId(1, SnapshotEntity), 10) - - then: - topChanges.size() == 2 - topChanges[0] instanceof ObjectRemoved - topChanges[0] instanceof NewObject } def "should store state history of Entity instance in JaversRepository and fetch snapshots in reverse order"() { diff --git a/javers-core/src/test/groovy/org/javers/core/JaversTestBuilder.groovy b/javers-core/src/test/groovy/org/javers/core/JaversTestBuilder.groovy index 1725959e5..52250e645 100644 --- a/javers-core/src/test/groovy/org/javers/core/JaversTestBuilder.groovy +++ b/javers-core/src/test/groovy/org/javers/core/JaversTestBuilder.groovy @@ -7,15 +7,14 @@ import org.javers.core.graph.LiveGraph import org.javers.core.graph.ObjectGraphBuilder import org.javers.core.json.JsonConverter import org.javers.core.metamodel.clazz.ClassAnnotationsScanner +import org.javers.core.metamodel.clazz.ManagedClassFactory import org.javers.core.metamodel.object.GlobalIdFactory import org.javers.core.metamodel.object.InstanceId -import org.javers.core.metamodel.clazz.ManagedClassFactory +import org.javers.core.metamodel.object.SnapshotFactory import org.javers.core.metamodel.property.PropertyScanner import org.javers.core.metamodel.type.TypeFactory import org.javers.core.metamodel.type.TypeMapper -import org.javers.core.snapshot.GraphShadowFactory -import org.javers.core.snapshot.GraphSnapshotFactory -import org.javers.core.metamodel.object.SnapshotFactory +import org.javers.core.snapshot.GraphSnapshotFacade import org.javers.repository.api.JaversExtendedRepository import org.javers.repository.api.JaversRepository @@ -95,12 +94,8 @@ class JaversTestBuilder { javersBuilder.getContainerComponent(SnapshotFactory) } - GraphSnapshotFactory getGraphSnapshotFactory() { - javersBuilder.getContainerComponent(GraphSnapshotFactory) - } - - GraphShadowFactory getGraphShadowFactory() { - javersBuilder.getContainerComponent(GraphShadowFactory) + GraphSnapshotFacade getGraphSnapshotFacade() { + javersBuilder.getContainerComponent(GraphSnapshotFacade) } TypeFactory getTypeSpawningFactory() { @@ -131,6 +126,10 @@ class JaversTestBuilder { javersBuilder.getContainerComponent(JsonConverter) } + def getContainerComponent(Class type) { + javersBuilder.getContainerComponent(type) + } + ObjectGraphBuilder createObjectGraphBuilder() { new ObjectGraphBuilder(getTypeMapper(), getLiveCdoFactory()) } diff --git a/javers-core/src/test/groovy/org/javers/core/commit/CommitAssert.groovy b/javers-core/src/test/groovy/org/javers/core/commit/CommitAssert.groovy index 7d8603145..b1594c692 100644 --- a/javers-core/src/test/groovy/org/javers/core/commit/CommitAssert.groovy +++ b/javers-core/src/test/groovy/org/javers/core/commit/CommitAssert.groovy @@ -54,8 +54,8 @@ class CommitAssert { this } - CommitAssert hasObjectRemoved(def expectedId){ - diffAssert.hasObjectRemoved(expectedId) + CommitAssert hasObjectRemoved(def expectedId, def expectedObject){ + diffAssert.hasObjectRemoved(expectedId, expectedObject) this } diff --git a/javers-core/src/test/groovy/org/javers/core/diff/DiffAssert.groovy b/javers-core/src/test/groovy/org/javers/core/diff/DiffAssert.groovy index 60a094332..fb34142d2 100644 --- a/javers-core/src/test/groovy/org/javers/core/diff/DiffAssert.groovy +++ b/javers-core/src/test/groovy/org/javers/core/diff/DiffAssert.groovy @@ -100,8 +100,10 @@ class DiffAssert { this } - DiffAssert hasObjectRemoved(def globalId){ - assert actual.changes.find{it instanceof ObjectRemoved && it.globalId == globalId}, "no ObjectRemoved change with expected globalId: "+globalId + DiffAssert hasObjectRemoved(def globalId, def expectedObject){ + def change = actual.changes.find{it instanceof ObjectRemoved && it.affectedGlobalId == globalId} + assert change, "no ObjectRemoved change with expected globalId: "+globalId + assert change.affectedCdo == expectedObject this } } diff --git a/javers-core/src/test/groovy/org/javers/core/prettyprint/ChangeLogDemo.groovy b/javers-core/src/test/groovy/org/javers/core/prettyprint/ChangeLogDemo.groovy index cc28c39db..a1549837d 100644 --- a/javers-core/src/test/groovy/org/javers/core/prettyprint/ChangeLogDemo.groovy +++ b/javers-core/src/test/groovy/org/javers/core/prettyprint/ChangeLogDemo.groovy @@ -17,17 +17,19 @@ class ChangeLogDemo extends Specification { def user = new DummyUser('bob', 'Dijk') user.setStringSet(['groovy'] as Set) - javers.commit("some author",user) + javers.commit("some author", user) user.setAge(18) user.setSurname('van Dijk') user.setSupervisor(new DummyUser('New Supervisor')) - javers.commit('some author',user) + javers.commit('some author', user) user.setIntegerList([22,23]) user.setSex(DummyUser.Sex.FEMALE) user.setStringSet(['java','scala'] as Set) - javers.commit('another author',user) + javers.commit('another author', user) + + javers.commitDelete('another author', user) when: diff --git a/javers-core/src/test/groovy/org/javers/core/snapshot/GraphShadowFactoryTest.groovy b/javers-core/src/test/groovy/org/javers/core/snapshot/GraphShadowFactoryTest.groovy index 75864f382..9e48df329 100644 --- a/javers-core/src/test/groovy/org/javers/core/snapshot/GraphShadowFactoryTest.groovy +++ b/javers-core/src/test/groovy/org/javers/core/snapshot/GraphShadowFactoryTest.groovy @@ -14,12 +14,13 @@ import static org.javers.core.metamodel.object.InstanceIdDTO.instanceId class GraphShadowFactoryTest extends Specification { @Shared JaversTestBuilder javers + @Shared GraphShadowFactory graphShadowFactory def setup(){ javers = JaversTestBuilder.javersTestAssembly() + graphShadowFactory = javers.getContainerComponent(GraphShadowFactory) } - def "should create ShadowGraph with snapshots of committed objects "() { given: def oldRef = new SnapshotEntity(id: 2, intProperty:2) @@ -28,11 +29,11 @@ class GraphShadowFactoryTest extends Specification { def liveGraph = javers.createLiveGraph(cdo) when: - def shadow = javers.graphShadowFactory.createLatestShadow(liveGraph) + def shadow = graphShadowFactory.createLatestShadow(liveGraph) then: shadow.nodes().size() == 1 NodeAssert.assertThat(shadow.nodes()[0]).hasGlobalId(instanceId(2,SnapshotEntity)) - .isSnapshot() + .isSnapshot() } } diff --git a/javers-core/src/test/groovy/org/javers/core/snapshot/GraphSnapshotFactoryTest.groovy b/javers-core/src/test/groovy/org/javers/core/snapshot/GraphSnapshotFactoryTest.groovy index 935070b11..1b54c5184 100644 --- a/javers-core/src/test/groovy/org/javers/core/snapshot/GraphSnapshotFactoryTest.groovy +++ b/javers-core/src/test/groovy/org/javers/core/snapshot/GraphSnapshotFactoryTest.groovy @@ -20,9 +20,12 @@ import static org.javers.core.snapshot.SnapshotsAssert.getAssertThat class GraphSnapshotFactoryTest extends Specification { @Shared JaversTestBuilder javers + @Shared GraphSnapshotFactory graphSnapshotFactory def setup(){ javers = JaversTestBuilder.javersTestAssembly() + graphSnapshotFactory = javers.getContainerComponent(GraphSnapshotFactory) + } CommitMetadata someCommitMetadata(){ @@ -38,7 +41,7 @@ class GraphSnapshotFactoryTest extends Specification { when: def snapshots = - javers.graphSnapshotFactory.create(node, latestShadowGraph, someCommitMetadata()) + graphSnapshotFactory.create(node, latestShadowGraph, someCommitMetadata()) then: assertThat(snapshots).hasSize(2) @@ -52,7 +55,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(2) @@ -69,7 +72,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(3) @@ -84,7 +87,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(2) @@ -98,7 +101,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(3) @@ -114,7 +117,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(3) @@ -142,7 +145,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(3) @@ -164,7 +167,7 @@ class GraphSnapshotFactoryTest extends Specification { def node = javers.createLiveGraph(cdo) when: - def snapshots = javers.graphSnapshotFactory.create(node, someCommitMetadata()) + def snapshots = graphSnapshotFactory.create(node, someCommitMetadata()) then: assertThat(snapshots).hasSize(3) @@ -193,7 +196,7 @@ class GraphSnapshotFactoryTest extends Specification { javers.javersRepository.persist(firstCommit) when: - def secondSnapshots = javers.graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) + def secondSnapshots = graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) then: firstCommit.snapshots.size() == 3 @@ -209,7 +212,7 @@ class GraphSnapshotFactoryTest extends Specification { when: cdo.listOfEntities.get(0).intProperty = 1 cdo.listOfEntities.get(1).intProperty = 1 - def secondSnapshots = javers.graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) + def secondSnapshots = graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) then: assertThat(secondSnapshots).hasSize(2) @@ -225,7 +228,7 @@ class GraphSnapshotFactoryTest extends Specification { when: cdo.intProperty = 1 - def secondSnapshots = javers.graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) + def secondSnapshots = graphSnapshotFactory.create(javers.createLiveGraph(cdo), someCommitMetadata()) then: assertThat(secondSnapshots).hasSize(1) diff --git a/javers-core/src/test/groovy/org/javers/core/snapshot/SnapshotDifferIntegrationTest.groovy b/javers-core/src/test/groovy/org/javers/core/snapshot/SnapshotDifferIntegrationTest.groovy index 0734e9182..ed4e86129 100644 --- a/javers-core/src/test/groovy/org/javers/core/snapshot/SnapshotDifferIntegrationTest.groovy +++ b/javers-core/src/test/groovy/org/javers/core/snapshot/SnapshotDifferIntegrationTest.groovy @@ -1,6 +1,7 @@ package org.javers.core.snapshot import org.javers.core.diff.changetype.NewObject +import org.javers.core.diff.changetype.ObjectRemoved import org.javers.core.diff.changetype.ReferenceChange import org.javers.core.diff.changetype.ValueChange import org.javers.core.model.DummyUser @@ -19,7 +20,7 @@ import static org.javers.test.builder.DummyUserBuilder.dummyUser */ class SnapshotDifferIntegrationTest extends Specification { - def "should not include NewObject in change history for ordinary commit"() { + def "shouldn't add NewObject to change history for ordinary commit"() { given: def javers = javers().build() def user = new DummyUser("kaz") @@ -40,7 +41,7 @@ class SnapshotDifferIntegrationTest extends Specification { } } - def "should include NewObject in change history for initial commit"() { + def "should add NewObject to change history for initial commit"() { given: def javers = javers().build() def user = new DummyUser("kaz") @@ -62,6 +63,26 @@ class SnapshotDifferIntegrationTest extends Specification { changes.size() == 2 changes[0] instanceof ValueChange changes[1] instanceof NewObject + changes[1].affectedGlobalId == instanceId("kaz",DummyUser) + changes[1].commitMetadata.get().id.majorId == 1 + } + + def "should add ObjectRemoved to change history for terminal commit"() { + given: + def javers = javers().build() + def user = new DummyUser("kaz") + javers.commit("some.login", user) + javers.commitDelete("some.login", user) + + when: + def changes = javers.getChangeHistory(instanceId("kaz",DummyUser),5) + + then: + changes.size() == 2 + changes[0] instanceof ObjectRemoved + changes[0].affectedGlobalId == instanceId("kaz",DummyUser) + changes[0].commitMetadata.get().id.majorId == 2 + changes[1] instanceof NewObject } @Unroll