]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.ui/src/org/simantics/document/ui/graphfile/DocumentVersionUtils.java
82372f1264a568c21a06927a59c147f7583b6f24
[simantics/platform.git] / bundles / org.simantics.document.ui / src / org / simantics / document / ui / graphfile / DocumentVersionUtils.java
1 package org.simantics.document.ui.graphfile;
2
3 import org.simantics.db.ReadGraph;
4 import org.simantics.db.Resource;
5 import org.simantics.db.WriteGraph;
6 import org.simantics.db.common.utils.NameUtils;
7 import org.simantics.db.exception.DatabaseException;
8 import org.simantics.document.DocumentResource;
9 import org.simantics.layer0.Layer0;
10 /**
11  * Util class for managing document versions
12  * 
13  * Document version history mode  is searched with relations:
14  * 1. l0.PartOf
15  * 2. l0.IsOwnedBy
16  * 3. l0.IsDependencyOf 
17  * 
18  * If library is not found, history mode is assumed to be flat.
19  * 
20  * In order to have working tree history, the library must contain proper configuration for relations:
21  *  doc.HasLibraryRelation
22  *  doc.HasVersionType
23  *  
24  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
25  *
26  */
27 public class DocumentVersionUtils {
28
29         public enum VersionMode{FLAT,TREE};
30         
31         
32         /**
33          * Adds a new document version.
34          * 
35          * Expects that newDocument is not part of document version chain, and oldDocument does not have newer version.
36          * 
37          * @param graph
38          * @param oldDocument
39          * @param newDocument
40          * @param relation
41          * @throws DatabaseException
42          */
43         public static void createNewVersion(WriteGraph graph, Resource oldDocument, Resource newDocument, Resource relation) throws DatabaseException{
44                 DocumentResource doc = DocumentResource.getInstance(graph);
45                 if (graph.hasStatement(oldDocument, doc.HasNewerVersion))
46                         throw new DatabaseException("Document " + NameUtils.getSafeName(graph, oldDocument) +" has already new version");
47                 
48                 Resource inverse = graph.getInverse(relation);
49                 Resource lib = graph.getSingleObject(oldDocument, inverse);
50                 String modeString = graph.getPossibleRelatedValue(lib, doc.HasVersionType);
51                 VersionMode mode = VersionMode.FLAT;
52                 if (modeString != null)
53                         mode = VersionMode.valueOf(modeString);
54                 
55                 graph.claim(oldDocument, doc.HasNewerVersion, newDocument);
56                 graph.claim(lib, relation, newDocument);
57                 
58                 if (mode == VersionMode.TREE) {
59                         graph.deny(lib,relation,oldDocument);
60                         graph.claim(newDocument,relation,oldDocument);
61                 }
62                 FileDocumentUtil.createUniqueName(graph, newDocument);
63         }
64         
65         /**
66          * Sets document version relationship between two documents. 
67          * 
68          * If the documents are already part of the same version chain this method does nothing.
69          * 
70          * If documents are already set to some version chain with given relation, this method replaces the exiting links.
71          * 
72          * @param graph
73          * @param document1
74          * @param document2
75          * @param versionRel
76          * @throws DatabaseException
77          */
78         public static void setVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException {
79                 DocumentResource doc = DocumentResource.getInstance(graph);
80                 // document type must match
81                 if (!graph.getSingleType(document2, doc.Document).equals(graph.getSingleType(document1, doc.Document)))
82                         return;
83                 if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion)))
84                         throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel));
85                 
86                 Resource versionRelInv = graph.getInverse(versionRel);
87                 // toSet must not be part of the document's version history
88                 Resource r = document1;
89                 while (r != null) {
90                         if (r.equals(document2))
91                                 return;
92                         r = graph.getPossibleObject(r, versionRel);
93                 }
94                 
95                 r = document2;
96                 while (r != null) {
97                         if (r.equals(document1))
98                                 return;
99                         r = graph.getPossibleObject(r, versionRel);
100                 }
101                 // At the moment document revision history is linear (no branching).
102                 Resource document1Ver = graph.getPossibleObject(document1, versionRel);
103                 if (document1Ver != null)
104                         unsetVersion(graph, document1, document1Ver, versionRel);
105                 Resource document2Ver = graph.getPossibleObject(document2, versionRelInv);
106                 if (document2Ver != null)
107                         unsetVersion(graph, document2, document2Ver, versionRelInv);
108                 
109                 graph.claim(document1, versionRel, document2);
110                 
111                 Resource lib = getLib(graph, document1);
112                 if (lib != null) {
113                         Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation);
114                         String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType);
115                         if ("TREE".equals(type) && relation != null) {
116                                 if (versionRel.equals(doc.HasOlderVersion)) {
117                                         graph.deny(document2, graph.getInverse(relation));
118                                         graph.claim(document1,relation,document2);
119                                 } else {
120                                         graph.deny(document1, graph.getInverse(relation));
121                                         graph.claim(document2,relation,document1);
122                                 }
123                         }
124                         
125                 }
126         }
127         
128         /**
129          * Unlinks document version relationship between two documents. 
130          * @param graph
131          * @param document1
132          * @param document2
133          * @param versionRel
134          * @throws DatabaseException
135          */
136         public static void unsetVersion(WriteGraph graph, Resource document1, Resource document2, Resource versionRel) throws DatabaseException {
137                 DocumentResource doc = DocumentResource.getInstance(graph);
138                 if (!versionRel.equals(doc.HasNewerVersion) && !(versionRel.equals(doc.HasOlderVersion)))
139                         throw new IllegalArgumentException("Unknow version relation + " + graph.getPossibleURI(versionRel));
140                 
141                 graph.deny(document1, versionRel,document2);
142                 Resource lib = getLib(graph, document1);
143                 if (lib != null) {
144                         Resource relation = graph.getPossibleObject(lib, doc.HasLibraryRelation);
145                         String type= graph.getPossibleRelatedValue(lib, doc.HasVersionType);
146                         if ("TREE".equals(type) && relation != null) {
147                                 if (versionRel.equals(doc.HasOlderVersion)) {
148                                         graph.deny(document1, relation);
149                                         graph.claim(lib,relation,document2);
150                                         FileDocumentUtil.createUniqueName(graph, document2);
151                                 } else {
152                                         graph.deny(document1, graph.getInverse(relation));
153                                         graph.claim(lib,relation,document1);
154                                         FileDocumentUtil.createUniqueName(graph, document1);
155                                 }
156                         }
157                         
158                 }
159         }
160         
161         private static Resource getLib(ReadGraph graph, Resource document) throws DatabaseException {
162                 Layer0 l0 = Layer0.getInstance(graph);
163                 DocumentResource doc = DocumentResource.getInstance(graph);
164                 Resource r = document;
165                 while (true) {
166                         Resource lib = graph.getPossibleObject(r, l0.PartOf);
167                         if (lib == null)
168                                 lib = graph.getPossibleObject(r, l0.IsOwnedBy);
169                         if (lib == null)
170                                 lib =  graph.getPossibleObject(r, l0.IsDependencyOf);
171                         if (lib == null)
172                                 return null;
173                         if (!graph.isInstanceOf(lib, doc.Document))
174                                 return lib;
175                         r = lib;
176                 }
177         }
178 }