]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java
Separate DB and non-DB code to different structural sync bundles
[simantics/platform.git] / bundles / org.simantics.structural.synchronization.client / src / org / simantics / structural / synchronization / Synchronizer.java
diff --git a/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java b/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/Synchronizer.java
deleted file mode 100644 (file)
index 9c74284..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-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;
-    }
-
-    
-}