Skip to content

Commit

Permalink
https://github.com/javers/javers/issues/71
Browse files Browse the repository at this point in the history
tracking Removed objects
  • Loading branch information
bartoszwalacik committed Jan 11, 2015
1 parent bc7152b commit 88eddff
Show file tree
Hide file tree
Showing 29 changed files with 328 additions and 185 deletions.
Expand Up @@ -5,7 +5,7 @@
*
* @author Pawel Cierpiatka <pawel.cierpiatka@gmail.com>
*/
public enum JaversExceptionCode {
public enum JaversExceptionCode {

CLASS_EXTRACTION_ERROR(JaversException.BOOTSTRAP_ERROR + "Don't know how to extract Class from type '%s'.") ,

Expand Down Expand Up @@ -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<ValueObjectType>, 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")

;

Expand Down
41 changes: 0 additions & 41 deletions javers-core/src/main/java/org/javers/core/GraphFactory.java

This file was deleted.

40 changes: 26 additions & 14 deletions 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;

Expand Down Expand Up @@ -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;
}

/**
* <p>
* 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.
* </p>
* 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;
}

Expand Down Expand Up @@ -175,7 +187,7 @@ public Optional<CdoSnapshot> getLatestSnapshot(GlobalIdDTO globalId){
* @return empty List, if object is not versioned or was committed only once
*/
public List<Change> getChangeHistory(GlobalIdDTO globalId, int limit) {
return snapshotDiffer.getChangeHistory(globalId, limit);
return graphSnapshotFacade.getChangeHistory(globalId, limit);
}

JaversType getForClass(Class<?> clazz) {
Expand Down
2 changes: 2 additions & 0 deletions javers-core/src/main/java/org/javers/core/JaversBuilder.java
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -37,7 +36,7 @@ public static void traverse(List<Change> changes, ChangeProcessor renderer) {
}

if (!change.getAffectedGlobalId().equals(lastGlobalId) &&
!(change instanceof NewObject)) {
!(change instanceof NewObject || change instanceof ObjectRemoved)) {
renderer.onAffectedObject(change.getAffectedGlobalId());
}

Expand Down
Expand Up @@ -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()));
}

Expand Down
59 changes: 44 additions & 15 deletions 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;

Expand All @@ -19,41 +25,64 @@
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<CdoSnapshot> snapshots =
graphFactory.createGraphSnapshot(currentGraph, latestShadowGraph, commitMetadata);
graphSnapshotFacade.createGraphSnapshot(currentGraph, latestShadowGraph, commitMetadata);

//do diff
Diff diff = diffFactory.create(latestShadowGraph, currentGraph, Optional.of(commitMetadata));

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

}
35 changes: 23 additions & 12 deletions javers-core/src/main/java/org/javers/core/diff/DiffFactory.java
Expand Up @@ -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;
Expand All @@ -29,24 +33,17 @@ public class DiffFactory {
private final TypeMapper typeMapper;
private final List<NodeChangeAppender> nodeChangeAppenders;
private final List<PropertyChangeAppender> propertyChangeAppender;
private final GraphFactory graphFactory;
private final LiveGraphFactory graphFactory;
private final JaversCoreConfiguration javersCoreConfiguration;

public DiffFactory(JaversCoreConfiguration javersCoreConfiguration, TypeMapper typeMapper, List<NodeChangeAppender> nodeChangeAppenders, List<PropertyChangeAppender> propertyChangeAppender, GraphFactory graphFactory) {
public DiffFactory(TypeMapper typeMapper, List<NodeChangeAppender> nodeChangeAppenders, List<PropertyChangeAppender> propertyChangeAppender, LiveGraphFactory graphFactory, JaversCoreConfiguration javersCoreConfiguration) {
this.typeMapper = typeMapper;
this.nodeChangeAppenders = nodeChangeAppenders;
this.propertyChangeAppender = propertyChangeAppender;
this.graphFactory = graphFactory;
this.javersCoreConfiguration = javersCoreConfiguration;
}

/**
* @see Javers#initial(Object)
*/
public Diff initial(Object newDomainObject) {
return createInitial(buildGraph(newDomainObject));
}

/**
* @see Javers#compare(Object, Object)
*/
Expand All @@ -61,8 +58,22 @@ public Diff create(ObjectGraph leftGraph, ObjectGraph rightGraph, Optional<Commi
return createAndAppendChanges(graphPair, commitMetadata);
}

public Diff createInitial(ObjectGraph currentGraph) {
Validate.argumentIsNotNull(currentGraph);
public Diff singleTerminal(Cdo removedCdo, CommitMetadata commitMetadata){
Validate.argumentIsNotNull(removedCdo);

DiffBuilder diff = diff();
diff.addChange(new ObjectRemoved(removedCdo.getGlobalId(), removedCdo.getWrappedCdo(), commitMetadata));

return diff.build();
}

/**
* @param newDomainObject object or handle to objects graph
*/
public Diff initial(Object newDomainObject) {
Validate.argumentIsNotNull(newDomainObject);

ObjectGraph currentGraph = buildGraph(newDomainObject);

GraphPair graphPair = new GraphPair(currentGraph);
return createAndAppendChanges(graphPair, Optional.<CommitMetadata>empty());
Expand Down
@@ -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;

Expand All @@ -14,4 +15,9 @@ public NewObject(GlobalId newId, Optional<Object> newCdo) {
super(newId);
setAffectedCdo(newCdo);
}

public NewObject(GlobalId newId, Optional<Object> newCdo, CommitMetadata commitMetadata) {
this(newId, newCdo);
bindToCommit(commitMetadata);
}
}

0 comments on commit 88eddff

Please sign in to comment.