]> gerrit.simantics Code Review - simantics/platform.git/blob
9ec63c06167846f619da56d24f939e5603d150ad
[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
13 abstract public class ModuleUpdaterBase<T extends ComponentBase<T>> {
14
15     public String moduleType;
16     public THashMap<String, PropertyUpdateRule<T>> propertyUpdateRules =
17             new THashMap<String, PropertyUpdateRule<T>>();
18     public THashMap<String, ConnectionUpdateRule<T>> connectionUpdateRules =
19             new THashMap<String, ConnectionUpdateRule<T>>();
20     public boolean isUserComponent;
21     public boolean isComposite;
22     public String subprocessType;
23     
24     public ModuleUpdaterBase(String moduleType) {
25         this.moduleType = moduleType;
26     }
27     
28     public void addPropertyUpdateRule(PropertyUpdateRule<T> rule) {
29         propertyUpdateRules.put(rule.getPropertyName(), rule);
30     }
31     
32     public void addConnectionUpdateRule(ConnectionUpdateRule<T> rule) {
33         connectionUpdateRules.put(rule.getConnectionPointName(), rule);
34     }
35
36     public void create(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
37         context.command = createAddCommandBuilder(context.getModuleName()); 
38         applyRules(context, true, properties, connections);
39     }
40     
41     abstract public CommandBuilder createAddCommandBuilder(String name);
42
43     public void update(ModuleUpdateContext<T> context, Collection<SerializedVariable> properties, Collection<Connection> connections) {
44         // Check that the module type matches
45         int moduleTypeId = context.getSolver().getModuleType(context.getModuleId());
46         String moduleTypeName = context.getSolver().getName(moduleTypeId);
47         if(!moduleTypeName.equals(moduleType)) {
48             context.getSolver().remove(context.getModuleId());
49             context.component.componentId = -1;
50             context.setModuleId(-1);
51             create(context, properties, connections);
52         }
53         
54         // Update
55         else {
56             context.command = createUpdateCommandBuilder(context.getModuleName());
57             applyRules(context, false, properties, connections);
58         }
59     }
60     
61     abstract public CommandBuilder createUpdateCommandBuilder(String name);
62     
63     private void applyRules(ModuleUpdateContext<T> context, boolean inCreate,
64             Collection<SerializedVariable> properties, Collection<Connection> connections) {
65         THashMap<String, Variant> propertyMap = new THashMap<String, Variant>(properties.size());
66         Map<String, Collection<String>> connectionMap = connections.isEmpty()
67                 ? Collections.<String, Collection<String>>emptyMap()
68                 : new THashMap<String, Collection<String>>(connections.size());
69         for(SerializedVariable property : properties)
70             propertyMap.put(property.name, property.value);
71         for(Connection connection : connections)
72             connectionMap.put(connection.relation, connection.connectionPoints);
73
74         context.incPendingCount(); // To prevent premature execution of the command
75         for(SerializedVariable property : properties) {
76             PropertyUpdateRule<T> rule = propertyUpdateRules.get(property.name);
77             if(rule != null)
78                 rule.apply(context, inCreate, propertyMap, connectionMap, property.value);
79             else if(property.name.equals("IsAttached"))
80                 ;
81             else
82                 if(SynchronizationEventHandlerBase.TRACE_EVENTS)
83                     System.out.println("    skipped property " + property.name + " " + property.toString());
84         }
85         if(inCreate) {
86             for(Connection connection : connections) {
87                 ConnectionUpdateRule<T> rule = connectionUpdateRules.get(connection.relation);
88                 if(rule != null)
89                     rule.apply(context, propertyMap, connection.connectionPoints);
90                 else
91                         if(SynchronizationEventHandlerBase.TRACE_EVENTS)
92                             System.out.println("    skipped connection " + connection.relation + " " + connection.connectionPoints);
93             }
94         }
95         else {
96             THashMap<String, ConnectionUpdateRule<T>> unusedConnectionUpdateRules =
97                     new THashMap<String, ConnectionUpdateRule<T>>(connectionUpdateRules);
98             for(Connection connection : connections) {
99                 ConnectionUpdateRule<T> rule = unusedConnectionUpdateRules.remove(connection.relation);
100                 if(rule != null)
101                     rule.apply(context, propertyMap, connection.connectionPoints);
102                 else
103                     if(SynchronizationEventHandlerBase.TRACE_EVENTS)
104                         System.out.println("    skipped connection " + connection.relation + " " + connection.connectionPoints);
105             }
106             for(ConnectionUpdateRule<T> rule : unusedConnectionUpdateRules.values())
107                 rule.apply(context, propertyMap, Collections.<String>emptyList());
108         }
109         context.decPendingCount();
110     }
111
112 }