1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.layer0.changeset;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
18 import java.util.TreeMap;
20 import org.simantics.db.ChangeSetIdentifier;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.WriteGraph;
24 import org.simantics.db.common.UndoMetadata;
25 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
26 import org.simantics.db.exception.DatabaseException;
27 import org.simantics.db.layer0.genericrelation.DependencyChanges;
28 import org.simantics.db.layer0.genericrelation.DependencyChanges.Change;
29 import org.simantics.db.layer0.request.IsLinkedTo;
30 import org.simantics.db.service.ManagementSupport;
32 public class MetadataUtils {
34 public static final boolean DEBUG = false;
35 public static final boolean DEBUG_IDS = false;
37 public static Map<Long, Map<String,byte[]>> getMetadatas(ReadGraph graph, ManagementSupport support, long fromRevisionId, long toRevisionId) throws DatabaseException {
39 TreeMap<Long, Map<String,byte[]>> result = new TreeMap<Long, Map<String,byte[]>>();
41 Collection<ChangeSetIdentifier> csis = support.getChangeSetIdentifiers(fromRevisionId, toRevisionId);
42 for(ChangeSetIdentifier csi : csis) {
43 if(csi.getId() < fromRevisionId) {
44 System.err.println("ManagementSupport.getChangeSetIdentifiers returned identifiers outside of the requested range.");
47 Map<String,byte[]> metadata = csi.getMetadata();
48 if(metadata != null) result.put(csi.getId(), metadata);
50 long toBeRevision = support.getHeadRevisionId()+1;
51 if(toBeRevision >= fromRevisionId && toBeRevision <= toRevisionId) {
52 if(graph instanceof WriteGraph) {
53 WriteGraph writeGraph = (WriteGraph)graph;
54 Map<String,byte[]> metadata = writeGraph.getMetadata();
56 result.put(toBeRevision, metadata);
64 public static Map<Resource, Collection<Change>> getDependencyChangesFrom(ReadGraph graph, long revisionId) throws DatabaseException {
65 ManagementSupport support = graph.getService(ManagementSupport.class);
67 Map<Resource, Collection<Change>> result = new HashMap<Resource, Collection<Change>>();
68 Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE);
70 for(Map.Entry<Long, Map<String,byte[]>> e : metadatas.entrySet()) {
71 long csid = e.getKey();
72 Map<String,byte[]> metadata = e.getValue();
73 if(metadata != null) {
74 byte[] changesData = metadata.get(DependencyChanges.class.getName());
75 if(changesData != null && changesData.length > 0) {
76 DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData);
79 if(DEBUG_IDS) System.err.println("-DependencyChanges[" + csid + "]");
80 for(Map.Entry<Resource, Change[]> entry : changes.modelChanges.entrySet()) {
81 Collection<Change> list = result.get(entry.getKey());
83 list = new ArrayList<Change>();
84 result.put(entry.getKey(), list);
86 for(Change c : entry.getValue()) {
87 if(DEBUG) System.err.println("-" + c);
97 public static void visitDependencyChangesFrom2(ReadGraph graph,
98 Resource model, Change[] changes, ChangeVisitor changeVisitor) throws DatabaseException {
99 for(Change change : changes) {
100 changeVisitor.visit(graph, change, false);
105 * Finds all changes made to the given {@code model} from the given revision and calls
106 * the {@code visitor} for them.
108 public static void visitDependencyChangesFrom(ReadGraph graph, Resource model, long fromRevision,
109 ChangeVisitor visitor) throws DatabaseException {
110 visitDependencyChangesBetween(graph, model, fromRevision, Long.MAX_VALUE, visitor, false);
113 private static void visitDependencyChangesBetween(ReadGraph graph, Resource model, long fromRevision, long toRevision,
114 ChangeVisitor visitor, boolean inverted) throws DatabaseException {
115 ManagementSupport support = graph.getService(ManagementSupport.class);
116 // System.err.println("visitDependencyChangesBetween " + fromRevision + " " + toRevision);
117 // Collection<ChangeSetIdentifier> csis = support.getChangeSetIdentifiers(fromRevision, toRevision);
119 Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, fromRevision, toRevision);
121 // Map<Resource, Collection<Change>> result = new HashMap<Resource, Collection<Change>>();
122 // Map<Long, Map<String,byte[]>> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE);
124 for(Map.Entry<Long, Map<String,byte[]>> e : metadatas.entrySet()) {
126 Map<String,byte[]> metadata = e.getValue();
129 byte[] changesData = metadata.get(DependencyChanges.class.getName());
130 if(changesData == null || changesData.length == 0)
132 DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData);
135 for(Map.Entry<Resource, Change[]> entry : changes.modelChanges.entrySet())
136 if(graph.syncRequest(new IsLinkedTo(model, entry.getKey()),
137 TransientCacheListener.<Boolean>instance()))
138 for(Change change : entry.getValue())
139 visitor.visit(graph, change, inverted);
142 byte[] undoMetadata = metadata.get(UndoMetadata.class.getName());
143 if(undoMetadata != null && undoMetadata.length != 0) {
144 UndoMetadata undo = UndoMetadata.deserialise(graph.getSession(), undoMetadata);
145 visitDependencyChangesBetween(graph, model, undo.getBeginCSId(), undo.getEndCSId(), visitor,
146 undo.isRedo() ? inverted : !inverted);