-package org.simantics.structural.synchronization;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
-import org.simantics.db.exception.CancelTransactionException;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.exception.MissingVariableValueException;\r
-import org.simantics.db.layer0.request.ResourceToPossibleVariable;\r
-import org.simantics.db.layer0.variable.RVI;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.service.ManagementSupport;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.scl.runtime.SCLContext;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.structural.synchronization.protocol.ChildInfo;\r
-import org.simantics.structural.synchronization.protocol.Connection;\r
-import org.simantics.structural.synchronization.protocol.SerializedVariable;\r
-import org.simantics.structural.synchronization.protocol.SynchronizationEventHandler;\r
-import org.simantics.structural.synchronization.protocol.SynchronizationException;\r
-import org.simantics.structural2.variables.VariableConnectionPointDescriptor;\r
-\r
-public class Synchronizer {\r
- \r
- public static boolean TRACE = false;\r
- \r
- ReadGraph graph;\r
- Layer0 L0;\r
- StructuralResource2 STR;\r
- THashSet<String> visitedTypes = new THashSet<String>();\r
- IProgressMonitor monitor;\r
- \r
- double workDone = 0.0;\r
- int workDoneInteger;\r
- int maxWork;\r
- \r
- public Synchronizer(ReadGraph graph) {\r
- this.graph = graph;\r
- L0 = Layer0.getInstance(graph);\r
- STR = StructuralResource2.getInstance(graph);\r
- }\r
- \r
- public void setMonitor(IProgressMonitor monitor, int maxWork) {\r
- this.monitor = monitor;\r
- this.maxWork = maxWork;\r
- this.workDoneInteger = 0;\r
- }\r
- \r
- private void didWork(double amount) {\r
- workDone += amount;\r
- //System.out.println(workDone);\r
- if(monitor != null) {\r
- int t = (int)(workDone * maxWork);\r
- if(t > workDoneInteger) {\r
- monitor.worked(t-workDoneInteger);\r
- workDoneInteger = t;\r
- }\r
- }\r
- }\r
-\r
- ChildInfo mapChild(Variable child) throws DatabaseException {\r
- String name = child.getName(graph);\r
- RVI rvi = child.getRVI(graph);\r
- return new ChildInfo(name, rvi.toString());\r
- }\r
-\r
- Collection<ChildInfo> mapChildren(SynchronizationEventHandler handler, Collection<Variable> children) throws DatabaseException {\r
- ArrayList<ChildInfo> result = new ArrayList<ChildInfo>(children.size());\r
- for(Variable child : children) {\r
- if(child.getPossibleType(graph, STR.Component) != null)\r
- try {\r
- result.add(mapChild(child));\r
- } catch(Exception e) {\r
- handler.reportProblem("Failed to get ChildInfo for " + child + ".", e);\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- Collection<Connection> mapConnections(SynchronizationEventHandler handler, Variable child) throws DatabaseException {\r
- ArrayList<Connection> result = new ArrayList<Connection>();\r
- for(Variable conn : child.getProperties(graph, StructuralResource2.URIs.SynchronizedConnectionRelation)) {\r
- String name = conn.getName(graph);\r
- org.simantics.structural2.variables.Connection vc = conn.getValue(graph);\r
- Collection<VariableConnectionPointDescriptor> connectionPoints = vc.getConnectionPointDescriptors(graph, null);\r
- List<String> cps = new ArrayList<String>(connectionPoints.size());\r
- for(VariableConnectionPointDescriptor desc : connectionPoints) {\r
- if(desc.isFlattenedFrom(graph, conn)) continue;\r
- if(!desc.hasClassification(graph, StructuralResource2.URIs.ProvidingConnectionRelation)) continue;\r
- String cpRef = desc.getRelativeRVI(graph, child);\r
- cps.add(cpRef);\r
- }\r
- \r
- result.add(new Connection(name, cps));\r
- \r
- }\r
- \r
- return result;\r
- \r
- }\r
- \r
- private SerializedVariable serialize(SynchronizationEventHandler handler, Variable var, String name) throws DatabaseException {\r
- try {\r
- SerializedVariable result = new SerializedVariable(name, var.getVariantValue(graph));\r
- for(Variable prop : var.getProperties(graph, StructuralResource2.URIs.SynchronizedRelation)) {\r
- String pName = prop.getName(graph);\r
- SerializedVariable v = serialize(handler, prop, pName);\r
- if(v != null) result.addProperty(pName, v);\r
- }\r
- return result;\r
- } catch (MissingVariableValueException e) {\r
- handler.reportProblem("Failed to read " + name + ". " + e.getMessage());\r
- \r
- Throwable cur = e;\r
- while((cur = cur.getCause()) != null) {\r
- if(!(cur instanceof MissingVariableValueException)) {\r
- handler.reportProblem(cur.getMessage());\r
- break;\r
- }\r
- }\r
- } catch (Exception e) {\r
- handler.reportProblem("Failed to serialize " + name + ": " + e.getMessage(), e);\r
- }\r
- \r
- return null;\r
- \r
- }\r
-\r
- Collection<SerializedVariable> mapProperties(SynchronizationEventHandler handler, Variable child) throws DatabaseException {\r
- ArrayList<SerializedVariable> result = new ArrayList<SerializedVariable>();\r
- for(Variable prop : child.getProperties(graph, StructuralResource2.URIs.SynchronizedRelation)) {\r
- SerializedVariable serialized = serialize(handler, prop, prop.getName(graph));\r
- if(serialized != null) result.add(serialized);\r
- }\r
- return result;\r
- }\r
-\r
- /**\r
- * Assumes that the variable points to a composite.\r
- */\r
- public void fullSynchronization(Variable variable, SynchronizationEventHandler handler) throws DatabaseException {\r
- long duration = 0;\r
- if(TRACE) {\r
- System.out.println("fullSynchronization " + variable.getURI(graph));\r
- duration -= System.nanoTime();\r
- }\r
- SCLContext context = SCLContext.getCurrent();\r
- Object oldGraph = context.put("graph", graph);\r
- try {\r
- handler.beginSynchronization();\r
- synchronizationRec(variable, handler, null, 1.0);\r
- handler.endSynchronization();\r
- } finally {\r
- context.put("graph", oldGraph);\r
- }\r
- if(TRACE) {\r
- duration += System.nanoTime();\r
- System.out.println("full sync in " + 1e-9*duration + "s.");\r
- }\r
- }\r
- \r
- /**\r
- * Recursive implementation of partial and full synchronization. If {@code changeFlags}\r
- * is null, this is full synchronization, otherwise partial synchronization.\r
- */\r
- private void synchronizationRec(Variable variable, SynchronizationEventHandler handler,\r
- TObjectIntHashMap<Variable> changeFlags,\r
- double proportionOfWork) throws DatabaseException {\r
- String name = variable.getName(graph);\r
- Resource type = variable.getPossibleType(graph, STR.Component);\r
- if(type == null) {\r
- // This same filtering is done separately in mapChildren when beginComponent has been called for the parent.\r
- return;\r
- }\r
- Collection<Variable> children = variable.getChildren(graph);\r
- if(graph.isInheritedFrom(type, STR.Composite) || graph.isInheritedFrom(type, STR.AbstractDefinedComponentType)) {\r
- String typeId = graph.getPossibleURI(type);\r
- if(typeId == null)\r
- throw new SynchronizationException("User component " + type + " does not have an URI.");\r
- if(visitedTypes.add(typeId))\r
- visitType(typeId, type, handler);\r
- boolean endComponentNeeded = false;\r
- try {\r
- Collection<SerializedVariable> propertyMap = mapProperties(handler, variable);\r
- Collection<ChildInfo> childMap = mapChildren(handler, children);\r
- endComponentNeeded = true;\r
- handler.beginComponent(name, typeId, \r
- propertyMap,\r
- Collections.<Connection>emptyList(), \r
- childMap);\r
- } catch(Exception e) {\r
- handler.reportProblem("Failed to synchronize " + name + ": " + e.getMessage(), e);\r
- if (endComponentNeeded)\r
- handler.endComponent();\r
- return;\r
- }\r
- } else {\r
- String typeId = graph.getPossibleURI(type);\r
- if(typeId == null)\r
- throw new SynchronizationException("User component " + type + " does not have an URI.");\r
- if(visitedTypes.add(typeId))\r
- visitType(typeId, type, handler);\r
- boolean endComponentNeeded = false;\r
- try {\r
- Collection<SerializedVariable> propertyMap = mapProperties(handler, variable);\r
- Collection<Connection> connectionMap = mapConnections(handler, variable);\r
- Collection<ChildInfo> childMap = mapChildren(handler, children);\r
- endComponentNeeded = true;\r
- handler.beginComponent(name, \r
- typeId,\r
- propertyMap,\r
- connectionMap,\r
- childMap);\r
- } catch(Exception e) {\r
- handler.reportProblem("Failed to synchronize " + name + ": " + e.getMessage(), e);\r
- if (endComponentNeeded)\r
- handler.endComponent();\r
- return;\r
- }\r
- }\r
- \r
- if(changeFlags == null) {\r
- // Full synchronization, synchronize all children\r
- if(children.size() > 0) {\r
- double proportionOfWorkForChildren = proportionOfWork / children.size();\r
- for(Variable child : children)\r
- synchronizationRec(child, handler, null, proportionOfWorkForChildren);\r
- }\r
- else {\r
- didWork(proportionOfWork);\r
- // Full synchronization is cancelable\r
- if(monitor != null && monitor.isCanceled())\r
- throw new CancelTransactionException();\r
- }\r
- }\r
- else {\r
- // Partial synchronization, synchronize only children with positive changeFlag\r
- int relevantChildCount = 0;\r
- for(final Variable child : children) {\r
- int changeStatus = changeFlags.get(child);\r
- if(changeStatus != 0)\r
- ++relevantChildCount;\r
- }\r
- if(relevantChildCount > 0) {\r
- double proportionOfWorkForChildren = proportionOfWork / relevantChildCount;\r
- for(final Variable child : children) {\r
- int changeStatus = changeFlags.get(child);\r
- if(changeStatus == 0)\r
- continue;\r
- synchronizationRec(child, handler,\r
- // Apply full synchronization for subtree if changeStatus > 1\r
- changeStatus==1 ? changeFlags : null,\r
- proportionOfWorkForChildren\r
- );\r
- }\r
- }\r
- else {\r
- didWork(proportionOfWork);\r
- }\r
- }\r
- handler.endComponent();\r
- }\r
- \r
- public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, TObjectIntHashMap<Variable> changeFlags) throws DatabaseException {\r
- long duration = 0;\r
- if(TRACE) {\r
- System.out.println("partialSynchronization " + variable.getURI(graph));\r
- duration -= System.nanoTime();\r
- }\r
- int changeStatus = changeFlags.get(variable);\r
- if(changeStatus == 0) return;\r
- SCLContext context = SCLContext.getCurrent();\r
- Object oldGraph = context.put("graph", graph);\r
- try {\r
- handler.beginSynchronization();\r
- synchronizationRec(variable, handler, changeStatus == 1 ? changeFlags : null, 1.0);\r
- handler.endSynchronization();\r
- } finally {\r
- context.put("graph", oldGraph);\r
- } \r
- if(TRACE) {\r
- duration += System.nanoTime();\r
- System.out.println("partial sync in " + 1e-9*duration + "s.");\r
- }\r
- }\r
- \r
- public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, long fromRevision) throws DatabaseException {\r
- TObjectIntHashMap<Variable> modifiedComponents = StructuralChangeFlattener.getModifiedComponents(graph, variable, fromRevision);\r
- /*System.out.println("----------------");\r
- modifiedComponents.forEachEntry(\r
- new TObjectIntProcedure<Variable>() {\r
- @Override\r
- public boolean execute(Variable a, int b) {\r
- try {\r
- System.out.println("Changed: " + a.getURI(graph) + " " + b);\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- }\r
- return true;\r
- }\r
- });*/\r
- partialSynchronization(variable, handler, modifiedComponents);\r
- }\r
- \r
- void visitType(String typeId, Resource typeResource, SynchronizationEventHandler handler) throws DatabaseException {\r
- Variable typeVariable = graph.syncRequest(new ResourceToPossibleVariable(typeResource), TransientCacheAsyncListener.<Variable>instance());\r
- handler.beginType(typeId, mapProperties(handler, typeVariable));\r
- handler.endType();\r
- }\r
-\r
- public long getHeadRevisionId() throws DatabaseException {\r
- return graph.getService(ManagementSupport.class).getHeadRevisionId()+1;\r
- }\r
-\r
- \r
-}\r
+package org.simantics.structural.synchronization;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.exception.CancelTransactionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.exception.MissingVariableValueException;
+import org.simantics.db.layer0.request.ResourceToPossibleVariable;
+import org.simantics.db.layer0.variable.RVI;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.service.ManagementSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural.synchronization.protocol.ChildInfo;
+import org.simantics.structural.synchronization.protocol.Connection;
+import org.simantics.structural.synchronization.protocol.SerializedVariable;
+import org.simantics.structural.synchronization.protocol.SynchronizationEventHandler;
+import org.simantics.structural.synchronization.protocol.SynchronizationException;
+import org.simantics.structural2.variables.VariableConnectionPointDescriptor;
+
+public class Synchronizer {
+
+ public static boolean TRACE = false;
+
+ ReadGraph graph;
+ Layer0 L0;
+ StructuralResource2 STR;
+ THashSet<String> visitedTypes = new THashSet<String>();
+ IProgressMonitor monitor;
+
+ double workDone = 0.0;
+ int workDoneInteger;
+ int maxWork;
+
+ public Synchronizer(ReadGraph graph) {
+ this.graph = graph;
+ L0 = Layer0.getInstance(graph);
+ STR = StructuralResource2.getInstance(graph);
+ }
+
+ public void setMonitor(IProgressMonitor monitor, int maxWork) {
+ this.monitor = monitor;
+ this.maxWork = maxWork;
+ this.workDoneInteger = 0;
+ }
+
+ private void didWork(double amount) {
+ workDone += amount;
+ //System.out.println(workDone);
+ if(monitor != null) {
+ int t = (int)(workDone * maxWork);
+ if(t > workDoneInteger) {
+ monitor.worked(t-workDoneInteger);
+ workDoneInteger = t;
+ }
+ }
+ }
+
+ ChildInfo mapChild(Variable child) throws DatabaseException {
+ String name = child.getName(graph);
+ RVI rvi = child.getRVI(graph);
+ return new ChildInfo(name, rvi.toString());
+ }
+
+ Collection<ChildInfo> mapChildren(SynchronizationEventHandler handler, Collection<Variable> children) throws DatabaseException {
+ ArrayList<ChildInfo> result = new ArrayList<ChildInfo>(children.size());
+ for(Variable child : children) {
+ if(child.getPossibleType(graph, STR.Component) != null)
+ try {
+ result.add(mapChild(child));
+ } catch(Exception e) {
+ handler.reportProblem("Failed to get ChildInfo for " + child + ".", e);
+ }
+ }
+ return result;
+ }
+
+ Collection<Connection> mapConnections(SynchronizationEventHandler handler, Variable child) throws DatabaseException {
+ ArrayList<Connection> result = new ArrayList<Connection>();
+ for(Variable conn : child.getProperties(graph, StructuralResource2.URIs.SynchronizedConnectionRelation)) {
+ String name = conn.getName(graph);
+ org.simantics.structural2.variables.Connection vc = conn.getValue(graph);
+ Collection<VariableConnectionPointDescriptor> connectionPoints = vc.getConnectionPointDescriptors(graph, null);
+ List<String> cps = new ArrayList<String>(connectionPoints.size());
+ for(VariableConnectionPointDescriptor desc : connectionPoints) {
+ if(desc.isFlattenedFrom(graph, conn)) continue;
+ if(!desc.hasClassification(graph, StructuralResource2.URIs.ProvidingConnectionRelation)) continue;
+ String cpRef = desc.getRelativeRVI(graph, child);
+ cps.add(cpRef);
+ }
+
+ result.add(new Connection(name, cps));
+
+ }
+
+ return result;
+
+ }
+
+ private SerializedVariable serialize(SynchronizationEventHandler handler, Variable var, String name) throws DatabaseException {
+ try {
+ SerializedVariable result = new SerializedVariable(name, var.getVariantValue(graph));
+ for(Variable prop : var.getProperties(graph, StructuralResource2.URIs.SynchronizedRelation)) {
+ String pName = prop.getName(graph);
+ SerializedVariable v = serialize(handler, prop, pName);
+ if(v != null) result.addProperty(pName, v);
+ }
+ return result;
+ } catch (MissingVariableValueException e) {
+ handler.reportProblem("Failed to read " + name + ". " + e.getMessage());
+
+ Throwable cur = e;
+ while((cur = cur.getCause()) != null) {
+ if(!(cur instanceof MissingVariableValueException)) {
+ handler.reportProblem(cur.getMessage());
+ break;
+ }
+ }
+ } catch (Exception e) {
+ handler.reportProblem("Failed to serialize " + name + ": " + e.getMessage(), e);
+ }
+
+ return null;
+
+ }
+
+ Collection<SerializedVariable> mapProperties(SynchronizationEventHandler handler, Variable child) throws DatabaseException {
+ ArrayList<SerializedVariable> result = new ArrayList<SerializedVariable>();
+ for(Variable prop : child.getProperties(graph, StructuralResource2.URIs.SynchronizedRelation)) {
+ SerializedVariable serialized = serialize(handler, prop, prop.getName(graph));
+ if(serialized != null) result.add(serialized);
+ }
+ return result;
+ }
+
+ /**
+ * Assumes that the variable points to a composite.
+ */
+ public void fullSynchronization(Variable variable, SynchronizationEventHandler handler) throws DatabaseException {
+ long duration = 0;
+ if(TRACE) {
+ System.out.println("fullSynchronization " + variable.getURI(graph));
+ duration -= System.nanoTime();
+ }
+ SCLContext context = SCLContext.getCurrent();
+ Object oldGraph = context.put("graph", graph);
+ try {
+ handler.beginSynchronization();
+ synchronizationRec(variable, handler, null, 1.0);
+ handler.endSynchronization();
+ } finally {
+ context.put("graph", oldGraph);
+ }
+ if(TRACE) {
+ duration += System.nanoTime();
+ System.out.println("full sync in " + 1e-9*duration + "s.");
+ }
+ }
+
+ /**
+ * Recursive implementation of partial and full synchronization. If {@code changeFlags}
+ * is null, this is full synchronization, otherwise partial synchronization.
+ */
+ private void synchronizationRec(Variable variable, SynchronizationEventHandler handler,
+ TObjectIntHashMap<Variable> changeFlags,
+ double proportionOfWork) throws DatabaseException {
+ String name = variable.getName(graph);
+ Resource type = variable.getPossibleType(graph, STR.Component);
+ if(type == null) {
+ // This same filtering is done separately in mapChildren when beginComponent has been called for the parent.
+ return;
+ }
+ Collection<Variable> children = variable.getChildren(graph);
+ if(graph.isInheritedFrom(type, STR.Composite) || graph.isInheritedFrom(type, STR.AbstractDefinedComponentType)) {
+ String typeId = graph.getPossibleURI(type);
+ if(typeId == null)
+ throw new SynchronizationException("User component " + type + " does not have an URI.");
+ if(visitedTypes.add(typeId))
+ visitType(typeId, type, handler);
+ boolean endComponentNeeded = false;
+ try {
+ Collection<SerializedVariable> propertyMap = mapProperties(handler, variable);
+ Collection<ChildInfo> childMap = mapChildren(handler, children);
+ endComponentNeeded = true;
+ handler.beginComponent(name, typeId,
+ propertyMap,
+ Collections.<Connection>emptyList(),
+ childMap);
+ } catch(Exception e) {
+ handler.reportProblem("Failed to synchronize " + name + ": " + e.getMessage(), e);
+ if (endComponentNeeded)
+ handler.endComponent();
+ return;
+ }
+ } else {
+ String typeId = graph.getPossibleURI(type);
+ if(typeId == null)
+ throw new SynchronizationException("User component " + type + " does not have an URI.");
+ if(visitedTypes.add(typeId))
+ visitType(typeId, type, handler);
+ boolean endComponentNeeded = false;
+ try {
+ Collection<SerializedVariable> propertyMap = mapProperties(handler, variable);
+ Collection<Connection> connectionMap = mapConnections(handler, variable);
+ Collection<ChildInfo> childMap = mapChildren(handler, children);
+ endComponentNeeded = true;
+ handler.beginComponent(name,
+ typeId,
+ propertyMap,
+ connectionMap,
+ childMap);
+ } catch(Exception e) {
+ handler.reportProblem("Failed to synchronize " + name + ": " + e.getMessage(), e);
+ if (endComponentNeeded)
+ handler.endComponent();
+ return;
+ }
+ }
+
+ if(changeFlags == null) {
+ // Full synchronization, synchronize all children
+ if(children.size() > 0) {
+ double proportionOfWorkForChildren = proportionOfWork / children.size();
+ for(Variable child : children)
+ synchronizationRec(child, handler, null, proportionOfWorkForChildren);
+ }
+ else {
+ didWork(proportionOfWork);
+ // Full synchronization is cancelable
+ if(monitor != null && monitor.isCanceled())
+ throw new CancelTransactionException();
+ }
+ }
+ else {
+ // Partial synchronization, synchronize only children with positive changeFlag
+ int relevantChildCount = 0;
+ for(final Variable child : children) {
+ int changeStatus = changeFlags.get(child);
+ if(changeStatus != 0)
+ ++relevantChildCount;
+ }
+ if(relevantChildCount > 0) {
+ double proportionOfWorkForChildren = proportionOfWork / relevantChildCount;
+ for(final Variable child : children) {
+ int changeStatus = changeFlags.get(child);
+ if(changeStatus == 0)
+ continue;
+ synchronizationRec(child, handler,
+ // Apply full synchronization for subtree if changeStatus > 1
+ changeStatus==1 ? changeFlags : null,
+ proportionOfWorkForChildren
+ );
+ }
+ }
+ else {
+ didWork(proportionOfWork);
+ }
+ }
+ handler.endComponent();
+ }
+
+ public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, TObjectIntHashMap<Variable> changeFlags) throws DatabaseException {
+ long duration = 0;
+ if(TRACE) {
+ System.out.println("partialSynchronization " + variable.getURI(graph));
+ duration -= System.nanoTime();
+ }
+ int changeStatus = changeFlags.get(variable);
+ if(changeStatus == 0) return;
+ SCLContext context = SCLContext.getCurrent();
+ Object oldGraph = context.put("graph", graph);
+ try {
+ handler.beginSynchronization();
+ synchronizationRec(variable, handler, changeStatus == 1 ? changeFlags : null, 1.0);
+ handler.endSynchronization();
+ } finally {
+ context.put("graph", oldGraph);
+ }
+ if(TRACE) {
+ duration += System.nanoTime();
+ System.out.println("partial sync in " + 1e-9*duration + "s.");
+ }
+ }
+
+ public void partialSynchronization(Variable variable, SynchronizationEventHandler handler, long fromRevision) throws DatabaseException {
+ TObjectIntHashMap<Variable> modifiedComponents = StructuralChangeFlattener.getModifiedComponents(graph, variable, fromRevision);
+ /*System.out.println("----------------");
+ modifiedComponents.forEachEntry(
+ new TObjectIntProcedure<Variable>() {
+ @Override
+ public boolean execute(Variable a, int b) {
+ try {
+ System.out.println("Changed: " + a.getURI(graph) + " " + b);
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+ });*/
+ partialSynchronization(variable, handler, modifiedComponents);
+ }
+
+ void visitType(String typeId, Resource typeResource, SynchronizationEventHandler handler) throws DatabaseException {
+ Variable typeVariable = graph.syncRequest(new ResourceToPossibleVariable(typeResource), TransientCacheAsyncListener.<Variable>instance());
+ handler.beginType(typeId, mapProperties(handler, typeVariable));
+ handler.endType();
+ }
+
+ public long getHeadRevisionId() throws DatabaseException {
+ return graph.getService(ManagementSupport.class).getHeadRevisionId()+1;
+ }
+
+
+}