1 package org.simantics.structural.synchronization.base;
3 import java.util.Collection;
4 import java.util.Collections;
7 import org.simantics.databoard.binding.mutable.Variant;
8 import org.simantics.structural.synchronization.protocol.Connection;
9 import org.simantics.structural.synchronization.protocol.SerializedVariable;
10 import org.simantics.structural.synchronization.utils.ComponentBase;
12 import gnu.trove.map.hash.THashMap;
14 abstract public class ModuleUpdaterBase<T extends ComponentBase<T>> {
16 public String moduleType;
17 public THashMap<String, PropertyUpdateRule<T>> propertyUpdateRules =
18 new THashMap<String, PropertyUpdateRule<T>>();
19 public THashMap<String, ConnectionUpdateRule<T>> connectionUpdateRules =
20 new THashMap<String, ConnectionUpdateRule<T>>();
21 public boolean isUserComponent;
22 public boolean isComposite;
23 public String subprocessType;
25 public ModuleUpdaterBase(String moduleType) {
26 this.moduleType = moduleType;
29 public void addPropertyUpdateRule(PropertyUpdateRule<T> rule) {
30 propertyUpdateRules.put(rule.getPropertyName(), rule);
33 public void addConnectionUpdateRule(ConnectionUpdateRule<T> rule) {
34 connectionUpdateRules.put(rule.getConnectionPointName(), rule);
37 public void create(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
38 context.command = createAddCommandBuilder(context.getModuleName());
39 applyRules(context, true, properties, connections);
42 abstract public CommandBuilder createAddCommandBuilder(String name);
44 public void update(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
45 // Check that the module type matches
46 int moduleTypeId = context.getSolver().getModuleType(context.getModuleId());
47 String moduleTypeName = context.getSolver().getName(moduleTypeId);
48 if(!moduleTypeName.equals(moduleType)) {
49 context.getSolver().remove(context.getModuleId());
50 context.component.componentId = -1;
51 context.setModuleId(-1);
52 create(context, properties, connections);
57 context.command = createUpdateCommandBuilder(context.getModuleName());
58 applyRules(context, false, properties, connections);
62 abstract public CommandBuilder createUpdateCommandBuilder(String name);
64 private void applyRules(ModuleUpdateContext<T> context, boolean inCreate,
65 Collection<SerializedVariable> properties, Collection<Connection> connections) {
66 THashMap<String, Variant> propertyMap = new THashMap<String, Variant>(properties.size());
67 Map<String, Collection<String>> connectionMap = connections.isEmpty()
68 ? Collections.<String, Collection<String>>emptyMap()
69 : new THashMap<String, Collection<String>>(connections.size());
70 for(SerializedVariable property : properties)
71 propertyMap.put(property.name, property.value);
72 for(Connection connection : connections)
73 connectionMap.put(connection.relation, connection.connectionPoints);
75 context.incPendingCount(); // To prevent premature execution of the command
76 for(SerializedVariable property : properties) {
77 PropertyUpdateRule<T> rule = propertyUpdateRules.get(property.name);
79 rule.apply(context, inCreate, propertyMap, connectionMap, property.value);
80 else if(property.name.equals("IsAttached"))
83 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
84 System.out.println(" skipped property " + property.name + " " + property.toString());
87 for(Connection connection : connections) {
88 ConnectionUpdateRule<T> rule = connectionUpdateRules.get(connection.relation);
90 rule.apply(context, propertyMap, connection.connectionPoints);
92 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
93 System.out.println(" skipped connection " + connection.relation + " " + connection.connectionPoints);
97 THashMap<String, ConnectionUpdateRule<T>> unusedConnectionUpdateRules =
98 new THashMap<String, ConnectionUpdateRule<T>>(connectionUpdateRules);
99 for(Connection connection : connections) {
100 ConnectionUpdateRule<T> rule = unusedConnectionUpdateRules.remove(connection.relation);
102 rule.apply(context, propertyMap, connection.connectionPoints);
104 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
105 System.out.println(" skipped connection " + connection.relation + " " + connection.connectionPoints);
107 for(ConnectionUpdateRule<T> rule : unusedConnectionUpdateRules.values())
108 rule.apply(context, propertyMap, Collections.<String>emptyList());
110 context.decPendingCount();