]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/changeset/MetadataUtils.java
Sync git svn branch with SVN repository r33249.
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / changeset / MetadataUtils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.layer0.changeset;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collection;\r
16 import java.util.HashMap;\r
17 import java.util.Map;\r
18 import java.util.TreeMap;\r
19 \r
20 import org.simantics.db.ChangeSetIdentifier;\r
21 import org.simantics.db.ReadGraph;\r
22 import org.simantics.db.Resource;\r
23 import org.simantics.db.WriteGraph;\r
24 import org.simantics.db.common.UndoMetadata;\r
25 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
26 import org.simantics.db.exception.DatabaseException;\r
27 import org.simantics.db.layer0.genericrelation.DependencyChanges;\r
28 import org.simantics.db.layer0.genericrelation.DependencyChanges.Change;\r
29 import org.simantics.db.layer0.request.IsLinkedTo;\r
30 import org.simantics.db.service.ManagementSupport;\r
31 \r
32 public class MetadataUtils {\r
33         \r
34         public static final boolean DEBUG = false;\r
35         public static final boolean DEBUG_IDS = false;\r
36 \r
37         public static Map<Long, Map<String,byte[]>> getMetadatas(ReadGraph graph, ManagementSupport support, long fromRevisionId, long toRevisionId) throws DatabaseException {\r
38 \r
39             TreeMap<Long, Map<String,byte[]>> result = new TreeMap<Long, Map<String,byte[]>>(); \r
40                     \r
41             Collection<ChangeSetIdentifier> csis = support.getChangeSetIdentifiers(fromRevisionId, toRevisionId);\r
42         for(ChangeSetIdentifier csi : csis) {\r
43             if(csi.getId() < fromRevisionId) {\r
44                 System.err.println("ManagementSupport.getChangeSetIdentifiers returned identifiers outside of the requested range.");\r
45                 continue;\r
46             }\r
47             Map<String,byte[]> metadata = csi.getMetadata();\r
48             if(metadata != null) result.put(csi.getId(), metadata);\r
49         }\r
50         long toBeRevision = support.getHeadRevisionId()+1;\r
51         if(toBeRevision >= fromRevisionId && toBeRevision <= toRevisionId) {\r
52             if(graph instanceof WriteGraph) {\r
53                 WriteGraph writeGraph = (WriteGraph)graph;\r
54                 Map<String,byte[]> metadata = writeGraph.getMetadata();\r
55                 if(metadata != null)\r
56                     result.put(toBeRevision, metadata);\r
57             }\r
58         }\r
59         \r
60         return result;\r
61             \r
62         }\r
63         \r
64         public static Map<Resource, Collection<Change>> getDependencyChangesFrom(ReadGraph graph, long revisionId) throws DatabaseException {\r
65                 ManagementSupport support = graph.getService(ManagementSupport.class);\r
66                 \r
67         Map<Resource, Collection<Change>> result = new HashMap<Resource, Collection<Change>>();\r
68                 Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE);\r
69                 \r
70                 for(Map.Entry<Long, Map<String,byte[]>> e : metadatas.entrySet()) {\r
71                     long csid = e.getKey();\r
72                         Map<String,byte[]> metadata = e.getValue();\r
73                         if(metadata != null) {\r
74                                 byte[] changesData = metadata.get(DependencyChanges.class.getName());\r
75                                 if(changesData != null && changesData.length > 0) {\r
76                                         DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData);\r
77                                         if (changes == null)\r
78                                                 continue;\r
79                                         if(DEBUG_IDS) System.err.println("-DependencyChanges[" + csid + "]");\r
80                                         for(Map.Entry<Resource, Change[]> entry : changes.modelChanges.entrySet()) {\r
81                                                 Collection<Change> list = result.get(entry.getKey());\r
82                                                 if(list == null) {\r
83                                                         list = new ArrayList<Change>();\r
84                                                         result.put(entry.getKey(), list);\r
85                                                 }\r
86                                                 for(Change c : entry.getValue()) {\r
87                                                         if(DEBUG) System.err.println("-" + c);\r
88                                                         list.add(c);\r
89                                                 }\r
90                                         }\r
91                                 }\r
92                         }\r
93                 }\r
94                 return result;\r
95         }\r
96     \r
97         public static void visitDependencyChangesFrom2(ReadGraph graph,\r
98                         Resource model, Change[] changes, ChangeVisitor changeVisitor) throws DatabaseException {\r
99         for(Change change : changes) {\r
100                 changeVisitor.visit(graph, change, false);\r
101         }\r
102         }\r
103 \r
104     /**\r
105      * Finds all changes made to the given {@code model} from the given revision and calls \r
106      * the {@code visitor} for them.\r
107      */\r
108     public static void visitDependencyChangesFrom(ReadGraph graph, Resource model, long fromRevision,\r
109             ChangeVisitor visitor) throws DatabaseException {\r
110         visitDependencyChangesBetween(graph, model, fromRevision, Long.MAX_VALUE, visitor, false);\r
111     }\r
112 \r
113     private static void visitDependencyChangesBetween(ReadGraph graph, Resource model, long fromRevision, long toRevision,\r
114             ChangeVisitor visitor, boolean inverted) throws DatabaseException {\r
115         ManagementSupport support = graph.getService(ManagementSupport.class);\r
116 //        System.err.println("visitDependencyChangesBetween " + fromRevision + " " + toRevision);\r
117 //        Collection<ChangeSetIdentifier> csis = support.getChangeSetIdentifiers(fromRevision, toRevision);\r
118         \r
119         Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, fromRevision, toRevision);\r
120 \r
121 //        Map<Resource, Collection<Change>> result = new HashMap<Resource, Collection<Change>>();\r
122 //        Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE);\r
123         \r
124         for(Map.Entry<Long, Map<String,byte[]>> e : metadatas.entrySet()) {\r
125 \r
126             Map<String,byte[]> metadata = e.getValue();\r
127 \r
128             browseChanges: {\r
129                 byte[] changesData = metadata.get(DependencyChanges.class.getName());\r
130                 if(changesData == null || changesData.length == 0) \r
131                     break browseChanges;\r
132                 DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData);\r
133                 if (changes == null)\r
134                     break browseChanges;\r
135                 for(Map.Entry<Resource, Change[]> entry : changes.modelChanges.entrySet())\r
136                     if(graph.syncRequest(new IsLinkedTo(model, entry.getKey()),\r
137                             TransientCacheListener.<Boolean>instance()))\r
138                         for(Change change : entry.getValue())\r
139                             visitor.visit(graph, change, inverted);\r
140             }\r
141             \r
142             byte[] undoMetadata = metadata.get(UndoMetadata.class.getName());\r
143             if(undoMetadata != null && undoMetadata.length != 0) { \r
144                 UndoMetadata undo = UndoMetadata.deserialise(graph.getSession(), undoMetadata);\r
145                 visitDependencyChangesBetween(graph, model, undo.getBeginCSId(), undo.getEndCSId(), visitor, \r
146                         undo.isRedo() ? inverted : !inverted);\r
147             }\r
148         }\r
149     }\r
150 \r
151 }\r