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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.layer0.changeset;
\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
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
32 public class MetadataUtils {
\r
34 public static final boolean DEBUG = false;
\r
35 public static final boolean DEBUG_IDS = false;
\r
37 public static Map<Long, Map<String,byte[]>> getMetadatas(ReadGraph graph, ManagementSupport support, long fromRevisionId, long toRevisionId) throws DatabaseException {
\r
39 TreeMap<Long, Map<String,byte[]>> result = new TreeMap<Long, Map<String,byte[]>>();
\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
47 Map<String,byte[]> metadata = csi.getMetadata();
\r
48 if(metadata != null) result.put(csi.getId(), metadata);
\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
64 public static Map<Resource, Collection<Change>> getDependencyChangesFrom(ReadGraph graph, long revisionId) throws DatabaseException {
\r
65 ManagementSupport support = graph.getService(ManagementSupport.class);
\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
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
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
83 list = new ArrayList<Change>();
\r
84 result.put(entry.getKey(), list);
\r
86 for(Change c : entry.getValue()) {
\r
87 if(DEBUG) System.err.println("-" + c);
\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
105 * Finds all changes made to the given {@code model} from the given revision and calls
\r
106 * the {@code visitor} for them.
\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
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
119 Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, fromRevision, toRevision);
\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
124 for(Map.Entry<Long, Map<String,byte[]>> e : metadatas.entrySet()) {
\r
126 Map<String,byte[]> metadata = e.getValue();
\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
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