X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.structural.synchronization.client%2Fsrc%2Forg%2Fsimantics%2Fstructural%2Fsynchronization%2Fbase%2FSynchronizationEventHandlerBase.java;fp=bundles%2Forg.simantics.structural.synchronization.client%2Fsrc%2Forg%2Fsimantics%2Fstructural%2Fsynchronization%2Fbase%2FSynchronizationEventHandlerBase.java;h=0000000000000000000000000000000000000000;hb=e4007b17057ff4acc2e900c5c811743b74f71f41;hp=7be353a0222bac45db628c3655d0faded28078c7;hpb=3fe6778c21d6437e90d08987de6dae7bca89bc6d;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java b/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java deleted file mode 100644 index 7be353a02..000000000 --- a/bundles/org.simantics.structural.synchronization.client/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java +++ /dev/null @@ -1,430 +0,0 @@ -package org.simantics.structural.synchronization.base; - -import java.util.ArrayDeque; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Queue; - -import org.simantics.databoard.Bindings; -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.db.exception.DatabaseException; -import org.simantics.structural.synchronization.internal.Policy; -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.structural.synchronization.utils.ComponentBase; -import org.simantics.structural.synchronization.utils.ComponentFactory; -import org.simantics.structural.synchronization.utils.MappingBase; -import org.simantics.structural.synchronization.utils.Solver; -import org.slf4j.Logger; - -import gnu.trove.map.hash.THashMap; -import gnu.trove.set.hash.THashSet; - -/** - * Handles synchronization events by updating the simulator designated by the - * provided {@link Solver} instance. - * - * @author Hannu Niemistö - */ -public abstract class SynchronizationEventHandlerBase> implements SynchronizationEventHandler { - - public static final boolean TRACE_EVENTS = false; - - public final Solver solver; - protected final SolverNameUtil nameUtil; - protected final MappingBase mapping; - final ModuleUpdaterFactoryBase moduleUpdaterFactory; - final ComponentFactory componentFactory; - public final ReferenceResolverBase resolver; - private boolean didChanges = false; - - protected T component; // Current active component - THashMap> moduleUpdaters = new THashMap<>(); - Queue postSynchronizationActions = new ArrayDeque<>(); - protected THashMap> solverComponentNameToComponent = new THashMap<>(); - - /** - * This is a set of components satisfying the following conditions - *
    - *
  • beginComponent is called for their parents - *
  • endComponent is not yet called for their parents - *
  • beginComponent is not yet called for them - *
- */ - THashSet potentiallyUpdatedComponents = new THashSet<>(); - - public SynchronizationEventHandlerBase(Solver solver, ReferenceResolverBase resolver, SolverNameUtil nameUtil, - ComponentFactory componentFactory, ModuleUpdaterFactoryBase moduleUpdaterFactory, MappingBase mapping) { - this.solver = solver; - this.nameUtil = nameUtil; - this.mapping = mapping; - this.componentFactory = componentFactory; - this.moduleUpdaterFactory = moduleUpdaterFactory; - this.resolver = resolver; - } - - @Override - public void beginSynchronization() { - if(TRACE_EVENTS) { - System.out.println("beginSynchronization()"); - //mapping.printUidMap(); - } - component = null; - } - - @Override - public void endSynchronization() { - try { - if(TRACE_EVENTS) - System.out.println("endSynchronization()"); - if(component != null) - throw new SynchronizationException("beginComponent/endComponent calls do not match."); - - resolver.resolvePendingSelfReferences(); - resolver.printPending(); - - // Do removals - mapping.removePending(solver); - - // Post synchronization actions - Runnable action; - while((action = postSynchronizationActions.poll()) != null) - action.run(); - - // Rename modules to suggested names where possible. - nameUtil.applySuggestedNames((creationName, newName) -> { - ComponentBase component = solverComponentNameToComponent.get(creationName); - if (component != null) { - component.solverComponentName = newName; - } - }); - solverComponentNameToComponent.clear(); - } catch(Throwable e) { - Policy.logError(e); - throw new SynchronizationException(e); - } - } - - private boolean isAttached(Collection properties) { - for(SerializedVariable property : properties) - if(property.name.equals("IsAttached")) - try { - return (Boolean)property.value.getValue(Bindings.BOOLEAN); - } catch (AdaptException e) { - throw new SynchronizationException(e); - } - return false; - } - - private boolean isDesynchronized(Collection properties) { - for(SerializedVariable property : properties) - if(property.name.equals("IsDesynchronized")) - try { - return (Boolean)property.value.getValue(Bindings.BOOLEAN); - } catch (AdaptException e) { - throw new SynchronizationException(e); - } - return false; - } - - @Override - public void beginComponent(String name, String typeId, - Collection properties, - Collection connections, - Collection children) - throws SynchronizationException { - try { - if(TRACE_EVENTS) { - System.out.println("beginComponent("+name+", " + (component != null ? component.uid : "null") + "," + typeId + ")"); - if(!children.isEmpty()) { - System.out.println(" Children:"); - for(ChildInfo child : children) - System.out.println(" " + child.name + " " + child.uid); - } - if(!connections.isEmpty()) { - System.out.println(" Connections:"); - for(Connection connection : connections) - System.out.println(" " + connection.relation + " " + connection.connectionPoints); - } - } - - String parentSolverComponentName; - - // Finds the composite - if(component == null) { - name = "COMP_ROOT"; - parentSolverComponentName = ""; - component = mapping.getConfiguration(); - component.setModuleId(solver.getId(name)); - component.solverComponentName = name; - } - else { - parentSolverComponentName = component.solverComponentName; - component = component.getChild(name); - if(component == null) - throw new SynchronizationException("Didn't find '"+name+"'. " - + "It should have been mentioned as a child in the parent beginComponent method."); - } - - potentiallyUpdatedComponents.remove(component); - - ModuleUpdaterBase updater = null; - if(typeId != null) { - updater = moduleUpdaters.get(typeId); - if(updater == null) - throw new SynchronizationException("Undefined typeId " + typeId + "."); - } - - // Handle composite - if(typeId == null || updater.isUserComponent || updater.isComposite) { - // Create or update a subprocess - int moduleId = component.getModuleId(); - boolean justCreated = false; - if(isAttached(properties)) - ; // Subprocesses are not created for attached composites - else if(moduleId <= 0) { - String subprocessName = nameUtil.getFreshName( - parentSolverComponentName, - getSubprocessName(name, properties)); - try { - solver.addSubprocess(subprocessName, updater.subprocessType); - } catch(Exception e) { - reportProblem("Exception while adding subprocess.", e); - } - moduleId = solver.getId(subprocessName); - if(moduleId <= 0) - throw new SynchronizationException("Failed to create a subprocess " + subprocessName); - component.setModuleId(moduleId); - - // TODO these two lines can be removed when IncludedInSimulation -property is given to all composites - if(component.getParent() != null) { - String parentName = solver.getName(component.getParent().getModuleId()); - solver.includeSubprocess(parentName, subprocessName); - component.solverComponentName = subprocessName; - solverComponentNameToComponent.put(subprocessName, component); - } - - if(updater.isComposite) { - final ModuleUpdateContext context = new ModuleUpdateContext(this, updater, component); - updater.create(context, properties, connections); - } - - justCreated = true; - - } else { - - component.solverComponentName = nameUtil.ensureNameIsVariationOf( - parentSolverComponentName, moduleId, - getSubprocessName(name, properties)); - - if(updater.isComposite) { - final ModuleUpdateContext context = new ModuleUpdateContext(this, updater, component); - updater.update(context, properties, connections); - } - - } - if(mapping.getTrustUids()) { - // Create a new child map - THashMap newChildMap = - new THashMap(); - for(ChildInfo info : children) { - // Detach from the existing configuration the children with - // the right uids or create new components if uid is unknown. - T conf = mapping.detachOrCreateComponent(info.uid); - newChildMap.put(info.name, conf); - resolver.markPending(conf); - potentiallyUpdatedComponents.add(conf); - } - - // Put old children not detached in the previous phase - // to the pending removal set. They might have been - // moved somewhere else. - THashMap oldChildMap = - component.setChildMapAndReturnOld(newChildMap); - resolver.unmarkPending(component); - if(oldChildMap != null) - for(T component : oldChildMap.values()) { - component.clearParent(); - mapping.addPendingRemoval(component); - } - } - // Alternative implementation when uids are not available. - else { - // Create a new child map - THashMap newChildMap = - new THashMap(); - Map oldChildMap = - component.getChildMap(); - if(oldChildMap == null) - oldChildMap = Collections.emptyMap(); - for(ChildInfo info : children) { - T conf = oldChildMap.remove(info.name); - if(conf == null) - conf = componentFactory.create(info.uid); - else - conf.uid = info.uid; - newChildMap.put(info.name, conf); - resolver.markPending(conf); - } - component.setChildMap(newChildMap); - - resolver.unmarkPending(component); - if(oldChildMap != null) - for(T component : oldChildMap.values()) { - component.clearParent(); - mapping.addPendingRemoval(component); - } - } - - postCompositeAction(justCreated, properties, connections, updater); - - } - // Handle component - else { - if(!children.isEmpty()) - throw new SynchronizationException("Component with type " + typeId + " cannot have children."); - - boolean attached = isAttached(properties); - component.attached = attached; - - // Create or update the component - final ModuleUpdateContext context = new ModuleUpdateContext(this, updater, component); - int moduleId = component.getModuleId(); - if(moduleId <= 0) { - if(attached) { - component.attached = true; - context.setModuleName(name); - context.setModuleId(solver.getId(name)); - if(context.getModuleId() <= 0) - reportProblem("Didn't find attached module " + name + "."); - else if(!isDesynchronized(properties)) - updater.update(context, properties, connections); - setDidChanges(); - } - else { - component.attached = false; - context.setModuleName(nameUtil.getFreshName(parentSolverComponentName, name)); - context.addPostUpdateAction(new Runnable() { - @Override - public void run() { - context.stateLoadedFromUndo = mapping.undoContext.loadState(solver, - context.component.componentId, - context.component.uid); - } - }); - updater.create(context, properties, connections); - solverComponentNameToComponent.put(context.getModuleName(), component); - } - } - else if(!isDesynchronized(properties)) { - context.setModuleName(nameUtil.ensureNameIsVariationOf(parentSolverComponentName, - moduleId, name)); - updater.update(context, properties, connections); - } - else { - resolver.unmarkPending(component); - } - } - } catch(Throwable e) { - Policy.logError(e); - throw new SynchronizationException(e); - } - } - - private String getSubprocessName(String name, - Collection properties) { - for(SerializedVariable property : properties) - if(property.name.equals("HasSubprocessName")) - try { - String value = (String)property.value.getValue(Bindings.STRING); - if (!value.isEmpty()) - return value; - } catch (AdaptException e) { - // This is very improbable exception. - // Just ignore it and return the name. - e.printStackTrace(); - break; - } - return name; - } - - @Override - public void endComponent() { - try { - if(TRACE_EVENTS) - System.out.println("endComponent(" + (component != null ? component.solverComponentName : "null") + ")"); - if(component == null) return; - for(T child : component.getChildren()) - if(potentiallyUpdatedComponents.remove(child)) - resolver.unmarkPending(child); - T parent = component.getParent(); - if (parent == null && mapping.getConfiguration() != component) - throw new SynchronizationException("BUG: beginComponent/endComponent calls do not match."); - component = parent; - } catch(Throwable e) { - Policy.logError(e); - throw new SynchronizationException(e); - } - } - - @Override - public void beginType(String id, Collection properties) { - try { - /*if(TRACE_EVENTS) - System.out.println("beginType("+id+")");*/ - ModuleUpdaterBase updater; - try { - updater = moduleUpdaterFactory.createUpdater(id); - } catch (DatabaseException e) { - throw new RuntimeException(e); - } - if(updater == null) - throw new SynchronizationException("Failed to create module updater for id " + id + "."); - moduleUpdaters.put(id, updater); - } catch(Throwable e) { - Policy.logError(e); - throw new SynchronizationException(e); - } - } - - @Override - public void endType() { - /*if(TRACE_EVENTS) - System.out.println("endType()");*/ - } - - public boolean getDidChanges() { - return didChanges; - } - - public void setDidChanges() { - didChanges = true; - } - - public void reportProblem(String description) { - getLogger().error(description); - } - - public void reportProblem(String description, Exception e) { - getLogger().error(description, e); - } - - public void addPostSynchronizationAction(Runnable action) { - postSynchronizationActions.add(action); - } - - protected void postCompositeAction(boolean justCreated, Collection properties, - Collection connections, ModuleUpdaterBase updater) throws Exception { - } - - - public long getFromRevision() { - return mapping.currentRevision; - } - - public abstract Logger getLogger(); -}