]> gerrit.simantics Code Review - simantics/platform.git/blob
45ea7400fbbf8682d0da92ce463cc008fdbe62d1
[simantics/platform.git] /
1 package org.simantics.structural.synchronization.base;
2
3 import gnu.trove.map.hash.THashMap;
4
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.Map;
8
9 import org.simantics.databoard.binding.mutable.Variant;
10 import org.simantics.structural.synchronization.protocol.Connection;
11 import org.simantics.structural.synchronization.protocol.SerializedVariable;
12 import org.simantics.structural.synchronization.utils.ComponentBase;
13
14 abstract public class ModuleUpdaterBase<T extends ComponentBase<T>> {
15
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;
24     
25     public ModuleUpdaterBase(String moduleType) {
26         this.moduleType = moduleType;
27     }
28     
29     public void addPropertyUpdateRule(PropertyUpdateRule<T> rule) {
30         propertyUpdateRules.put(rule.getPropertyName(), rule);
31     }
32     
33     public void addConnectionUpdateRule(ConnectionUpdateRule<T> rule) {
34         connectionUpdateRules.put(rule.getConnectionPointName(), rule);
35     }
36
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);
40     }
41     
42     abstract public CommandBuilder createAddCommandBuilder(String name);
43
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);
53         }
54         
55         // Update
56         else {
57             context.command = createUpdateCommandBuilder(context.getModuleName());
58             applyRules(context, false, properties, connections);
59         }
60     }
61     
62     abstract public CommandBuilder createUpdateCommandBuilder(String name);
63     
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);
74
75         context.incPendingCount(); // To prevent premature execution of the command
76         for(SerializedVariable property : properties) {
77             PropertyUpdateRule<T> rule = propertyUpdateRules.get(property.name);
78             if(rule != null)
79                 rule.apply(context, inCreate, propertyMap, connectionMap, property.value);
80             else if(property.name.equals("IsAttached"))
81                 ;
82             else
83                 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
84                     System.out.println("    skipped property " + property.name + " " + property.toString());
85         }
86         if(inCreate) {
87             for(Connection connection : connections) {
88                 ConnectionUpdateRule<T> rule = connectionUpdateRules.get(connection.relation);
89                 if(rule != null)
90                     rule.apply(context, propertyMap, connection.connectionPoints);
91                 else
92                         if(SynchronizationEventHandlerBase.TRACE_EVENTS)
93                             System.out.println("    skipped connection " + connection.relation + " " + connection.connectionPoints);
94             }
95         }
96         else {
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);
101                 if(rule != null)
102                     rule.apply(context, propertyMap, connection.connectionPoints);
103                 else
104                     if(SynchronizationEventHandlerBase.TRACE_EVENTS)
105                         System.out.println("    skipped connection " + connection.relation + " " + connection.connectionPoints);
106             }
107             for(ConnectionUpdateRule<T> rule : unusedConnectionUpdateRules.values())
108                 rule.apply(context, propertyMap, Collections.<String>emptyList());
109         }
110         context.decPendingCount();
111     }
112
113 }