package org.javersion.object;
import static com.google.common.collect.ImmutableSet.of;
import static java.util.Arrays.asList;
import static org.javersion.core.Version.DEFAULT_BRANCH;
import java.util.Collection;
import java.util.Set;
import javax.annotation.concurrent.NotThreadSafe;
import org.javersion.core.*;
import org.javersion.object.types.ValueType;
import org.javersion.path.PropertyPath;
import org.javersion.path.Schema;
@NotThreadSafe
public class ObjectVersionManager<O, M> {
protected VersionGraph<PropertyPath, Object, M> versionGraph;
protected Set<Revision> heads;
protected final ObjectSerializer<O> serializer;
final boolean useSchemaFilter;
public ObjectVersionManager(Class<O> clazz) {
this(new ObjectSerializer<>(clazz), false);
}
public ObjectVersionManager(ObjectSerializer<O> serializer, boolean useSchemaFilter) {
this.serializer = serializer;
this.useSchemaFilter = useSchemaFilter;
}
public ObjectVersionManager<O, M> init() {
this.versionGraph = ObjectVersionGraph.init();
return this;
}
public ObjectVersionManager<O, M> init(Iterable<ObjectVersion<M>> versions) {
return init(ObjectVersionGraph.init(versions));
}
public ObjectVersionManager<O, M> init(VersionGraph<PropertyPath, Object, M> versionGraph) {
this.versionGraph = versionGraph;
heads = null;
return this;
}
public ManagedObjectVersionBuilder<M> versionBuilder(O object) {
ManagedObjectVersionBuilder<M> builder = new ManagedObjectVersionBuilder<M>(this, serializer.toPropertyMap(object));
builder.parents(heads);
return builder;
}
public MergeObject<O, M> mergeBranches(String... branches) {
return mergeBranches(asList(branches));
}
public MergeObject<O, M> mergeBranches(Collection<String> branches) {
if (branches.isEmpty()) {
return mergeObject(versionGraph.mergeBranches(DEFAULT_BRANCH));
}
return mergeObject(versionGraph.mergeBranches(branches));
}
public MergeObject<O, M> mergeRevisions(Collection<Revision> revisions) {
return mergeObject(versionGraph.mergeRevisions(revisions));
}
private MergeObject<O, M> mergeObject(Merge<PropertyPath, Object, M> merge) {
MergeObject<O, M> mergeObject = new MergeObject<>(toObject(merge), merge);
heads = merge.getMergeHeads();
return mergeObject;
}
private O toObject(Merge<PropertyPath, Object, M> merge) {
return serializer.fromPropertyMap(merge.getProperties());
}
public VersionNode<PropertyPath, Object, M> commit(Version<PropertyPath, Object, M> version) {
versionGraph = versionGraph.commit(version);
heads = of(version.revision);
return versionGraph.getTip();
}
public VersionGraph<PropertyPath, Object, M> getVersionGraph() {
return versionGraph;
}
public Set<Revision> getHeads() {
return heads;
}
public VersionNode<PropertyPath, Object, M> getVersionNode(Revision revision) {
return versionGraph.getVersionNode(revision);
}
public Set<String> getBranches() {
return versionGraph.getBranches();
}
public Schema<ValueType> getSchema() {
return serializer.schemaRoot;
}
public boolean isEmpty() {
return versionGraph.isEmpty();
}
}