X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.document.ui%2Fsrc%2Forg%2Fsimantics%2Fdocument%2Fui%2Fgraphfile%2FDocumentVersionUtils.java;fp=bundles%2Forg.simantics.document.ui%2Fsrc%2Forg%2Fsimantics%2Fdocument%2Fui%2Fgraphfile%2FDocumentVersionUtils.java;h=41d62e28d8033d158f503ae3ebdaf14ef810308a;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/DocumentVersionUtils.java b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/DocumentVersionUtils.java new file mode 100644 index 000000000..41d62e28d --- /dev/null +++ b/bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/DocumentVersionUtils.java @@ -0,0 +1,178 @@ +package org.simantics.document.ui.graphfile; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.document.DocumentResource; +import org.simantics.layer0.Layer0; +/** + * Util class for managing document versions + * + * Document version history mode is searched with relations: + * 1. l0.PartOf + * 2. l0.IsOwnedBy + * 3. l0.IsDependencyOf + * + * If library is not found, history mode is assumed to be flat. + * + * In order to have working tree history, the library must contain proper configuration for relations: + * doc.HasLibraryRelation + * doc.HasVersionType + * + * @author Marko Luukkainen + * + */ +public class DocumentVersionUtils { + + public enum VersionMode{FLAT,TREE}; + + + /** + * Adds a new document version. + * + * Expects that newDocument is not part of document version chain, and oldDocument does not have newer version. + * + * @param graph + * @param oldDocument + * @param newDocument + * @param relation + * @throws DatabaseException + */ + public static void createNewVersion(WriteGraph graph, Resource oldDocument, Resource newDocument, Resource relation) throws DatabaseException{ + DocumentResource doc = DocumentResource.getInstance(graph); + if (graph.hasStatement(oldDocument, doc.HasNewerVersion)) + throw new DatabaseException("Document " + NameUtils.getSafeName(graph, oldDocument) +" has already new version"); + + Resource inverse = graph.getInverse(relation); + Resource lib = graph.getSingleObject(oldDocument, inverse); + String modeString = graph.getPossibleRelatedValue(lib, doc.HasVersionType); + VersionMode mode = VersionMode.FLAT; + if (modeString != null) + mode = VersionMode.valueOf(modeString); + + graph.claim(oldDocument, doc.HasNewerVersion, newDocument); + graph.claim(lib, relation, newDocument); + + if (mode == VersionMode.TREE) { + graph.deny(lib,relation,oldDocument); + graph.claim(newDocument,relation,oldDocument); + } + FileDocumentUtil.createUniqueName(graph, newDocument); + } + + /** + * Sets document version relationship between two documents. + * + * If the documents are already part of the same version chain this method does nothing. + * + * If documents are already set to some version chain with given relation, this method replaces the exiting links. + * + * @param graph + * @param document1 + * @param document2 + * @param versionRel + * @throws DatabaseException + */ + public static void setVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException { + DocumentResource doc = DocumentResource.getInstance(graph); + // document type must match + if (!graph.getSingleType(document2, doc.Document).equals(graph.getSingleType(document1, doc.Document))) + return; + if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion))) + throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel)); + + Resource versionRelInv = graph.getInverse(versionRel); + // toSet must not be part of the document's version history + Resource r = document1; + while (r != null) { + if (r.equals(document2)) + return; + r = graph.getPossibleObject(r, versionRel); + } + + r = document2; + while (r != null) { + if (r.equals(document1)) + return; + r = graph.getPossibleObject(r, versionRel); + } + // At the moment document revision history is linear (no branching). + Resource document1Ver = graph.getPossibleObject(document1, versionRel); + if (document1Ver != null) + unsetVersion(graph, document1, document1Ver, versionRel); + Resource document2Ver = graph.getPossibleObject(document2, versionRelInv); + if (document2Ver != null) + unsetVersion(graph, document2, document2Ver, versionRelInv); + + graph.claim(document1, versionRel, document2); + + Resource lib = getLib(graph, document1); + if (lib != null) { + Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation); + String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType); + if ("TREE".equals(type) && relation != null) { + if (versionRel.equals(doc.HasOlderVersion)) { + graph.deny(document2, graph.getInverse(relation)); + graph.claim(document1,relation,document2); + } else { + graph.deny(document1, graph.getInverse(relation)); + graph.claim(document2,relation,document1); + } + } + + } + } + + /** + * Unlinks document version relationship between two documents. + * @param graph + * @param document1 + * @param document2 + * @param versionRel + * @throws DatabaseException + */ + public static void unsetVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException { + DocumentResource doc = DocumentResource.getInstance(graph); + if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion))) + throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel)); + + graph.deny(document1, versionRel,document2); + Resource lib = getLib(graph, document1); + if (lib != null) { + Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation); + String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType); + if ("TREE".equals(type) && relation != null) { + if (versionRel.equals(doc.HasOlderVersion)) { + graph.deny(document1, relation); + graph.claim(lib,relation,document2); + FileDocumentUtil.createUniqueName(graph, document2); + } else { + graph.deny(document1, graph.getInverse(relation)); + graph.claim(lib,relation,document1); + FileDocumentUtil.createUniqueName(graph, document1); + } + } + + } + } + + private static Resource getLib(ReadGraph graph, Resource document) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + DocumentResource doc = DocumentResource.getInstance(graph); + Resource r = document; + while (true) { + Resource lib = graph.getPossibleObject(r, l0.PartOf); + if (lib == null) + lib = graph.getPossibleObject(r, l0.IsOwnedBy); + if (lib == null) + lib = graph.getPossibleObject(r, l0.IsDependencyOf); + if (lib == null) + return null; + if (!graph.isInstanceOf(lib, doc.Document)) + return lib; + r = lib; + } + } +}