/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.db.layer0.changeset; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import org.simantics.db.ChangeSetIdentifier; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.UndoMetadata; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.genericrelation.DependencyChanges; import org.simantics.db.layer0.genericrelation.DependencyChanges.Change; import org.simantics.db.layer0.request.IsLinkedTo; import org.simantics.db.service.ManagementSupport; public class MetadataUtils { public static final boolean DEBUG = false; public static final boolean DEBUG_IDS = false; public static Map> getMetadatas(ReadGraph graph, ManagementSupport support, long fromRevisionId, long toRevisionId) throws DatabaseException { TreeMap> result = new TreeMap>(); Collection csis = support.getChangeSetIdentifiers(fromRevisionId, toRevisionId); for(ChangeSetIdentifier csi : csis) { if(csi.getId() < fromRevisionId) { System.err.println("ManagementSupport.getChangeSetIdentifiers returned identifiers outside of the requested range."); continue; } Map metadata = csi.getMetadata(); if(metadata != null) result.put(csi.getId(), metadata); } long toBeRevision = support.getHeadRevisionId()+1; if(toBeRevision >= fromRevisionId && toBeRevision <= toRevisionId) { if(graph instanceof WriteGraph) { WriteGraph writeGraph = (WriteGraph)graph; Map metadata = writeGraph.getMetadata(); if(metadata != null) result.put(toBeRevision, metadata); } } return result; } public static Map> getDependencyChangesFrom(ReadGraph graph, long revisionId) throws DatabaseException { ManagementSupport support = graph.getService(ManagementSupport.class); Map> result = new HashMap>(); Map> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE); for(Map.Entry> e : metadatas.entrySet()) { long csid = e.getKey(); Map metadata = e.getValue(); if(metadata != null) { byte[] changesData = metadata.get(DependencyChanges.class.getName()); if(changesData != null && changesData.length > 0) { DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData); if (changes == null) continue; if(DEBUG_IDS) System.err.println("-DependencyChanges[" + csid + "]"); for(Map.Entry entry : changes.modelChanges.entrySet()) { Collection list = result.get(entry.getKey()); if(list == null) { list = new ArrayList(); result.put(entry.getKey(), list); } for(Change c : entry.getValue()) { if(DEBUG) System.err.println("-" + c); list.add(c); } } } } } return result; } public static void visitDependencyChangesFrom2(ReadGraph graph, Resource model, Change[] changes, ChangeVisitor changeVisitor) throws DatabaseException { for(Change change : changes) { changeVisitor.visit(graph, change, false); } } /** * Finds all changes made to the given {@code model} from the given revision and calls * the {@code visitor} for them. */ public static void visitDependencyChangesFrom(ReadGraph graph, Resource model, long fromRevision, ChangeVisitor visitor) throws DatabaseException { visitDependencyChangesBetween(graph, model, fromRevision, Long.MAX_VALUE, visitor, false); } private static void visitDependencyChangesBetween(ReadGraph graph, Resource model, long fromRevision, long toRevision, ChangeVisitor visitor, boolean inverted) throws DatabaseException { ManagementSupport support = graph.getService(ManagementSupport.class); // System.err.println("visitDependencyChangesBetween " + fromRevision + " " + toRevision); // Collection csis = support.getChangeSetIdentifiers(fromRevision, toRevision); Map> metadatas = getMetadatas(graph, support, fromRevision, toRevision); // Map> result = new HashMap>(); // Map> metadatas = getMetadatas(graph, support, revisionId, Long.MAX_VALUE); for(Map.Entry> e : metadatas.entrySet()) { Map metadata = e.getValue(); browseChanges: { byte[] changesData = metadata.get(DependencyChanges.class.getName()); if(changesData == null || changesData.length == 0) break browseChanges; DependencyChanges changes = DependencyChanges.deserialise(graph.getSession(), changesData); if (changes == null) break browseChanges; for(Map.Entry entry : changes.modelChanges.entrySet()) if(graph.syncRequest(new IsLinkedTo(model, entry.getKey()), TransientCacheListener.instance())) for(Change change : entry.getValue()) visitor.visit(graph, change, inverted); } byte[] undoMetadata = metadata.get(UndoMetadata.class.getName()); if(undoMetadata != null && undoMetadata.length != 0) { UndoMetadata undo = UndoMetadata.deserialise(graph.getSession(), undoMetadata); visitDependencyChangesBetween(graph, model, undo.getBeginCSId(), undo.getEndCSId(), visitor, undo.isRedo() ? inverted : !inverted); } } } }