]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.server/src/org/simantics/document/server/state/StateNodeManager.java
399fbd7d19c17d99c868ab4a28a7c455e3215539
[simantics/platform.git] / bundles / org.simantics.document.server / src / org / simantics / document / server / state / StateNodeManager.java
1 package org.simantics.document.server.state;
2
3 import java.io.IOException;
4 import java.util.Map;
5
6 import org.simantics.databoard.Bindings;
7 import org.simantics.databoard.binding.Binding;
8 import org.simantics.databoard.binding.error.BindingConstructionException;
9 import org.simantics.databoard.binding.mutable.Variant;
10 import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
11 import org.simantics.databoard.serialization.SerializerConstructionException;
12 import org.simantics.simulator.toolkit.StandardRealm;
13 import org.simantics.simulator.toolkit.db.StandardVariableNodeManager;
14 import org.simantics.simulator.variable.exceptions.NodeManagerException;
15 import org.slf4j.LoggerFactory;
16
17 public class StateNodeManager extends StandardVariableNodeManager<StateNode, StateNodeManagerSupport> {
18
19         private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StateNodeManager.class);
20
21         public StateNodeManager(StandardRealm<StateNode, StateNodeManagerSupport> realm, StateNode root) {
22                 super(realm, root);
23         }
24
25         public void setState(String key, Object value) {
26                 try {
27                         getRealm().syncExec(() -> {
28                                 try {
29                                         StateRootNode rootNode = (StateRootNode) getRoot();
30                                         StatePropertyNode propertyNode = rootNode.getProperty(key);
31                                         if (propertyNode == null) {
32                                                 setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
33                                                 refreshVariable(rootNode);
34                                         } else {
35                                                 setValue(propertyNode, value, Bindings.OBJECT);
36                                         }
37                                 } catch (NodeManagerException e) {
38                                         LOGGER.error("Failed to set state.", e);
39                                 }
40                         });
41                 } catch (InterruptedException e) {
42                         LOGGER.error("Setting state was interrupted.", e);
43                 }
44         }
45         private class PropertyRunnable implements Runnable {
46                 String key;
47                 StatePropertyNode propertyNode;
48                 
49                 public PropertyRunnable(String key) {
50                         this.key = key;
51                 }
52                 
53                 @Override
54                 public void run() {
55                         StateRootNode rootNode = (StateRootNode) getRoot();
56                         propertyNode = rootNode.getProperty(key);
57                 }
58         }
59         
60         public StatePropertyNode getState(String key) {
61                 try {
62                         PropertyRunnable r = new PropertyRunnable(key);
63                         getRealm().syncExec(r);
64                         return r.propertyNode;
65                 } catch (InterruptedException e) {
66                         LOGGER.error("Getting state was interrupted.", e);
67                         return null;
68                 }
69         }
70
71         public byte[] serialize() {
72                 final byte [][] result = new byte[1][];
73                 try {
74                         getRealm().syncExec(() -> {
75                                 State state = new State();
76                                 StateRootNode root = (StateRootNode) getRoot();
77                                 for (StateNode node : root.getProperties().values()) {
78                                         StatePropertyNode property = (StatePropertyNode)node;
79                                         try {
80                                                 Binding binding = Bindings.getInstanceBinding(property.getValue());
81                                                 if (binding != null) {
82                                                         state.properties.put(property.getName(), new Variant(binding, property.getValue()));
83                                                 }
84                                         } catch (BindingConstructionException e) {
85                                                 // skip
86                                         }
87                                 }
88
89                                 try {
90                                         result[0] = Bindings.getSerializerUnchecked(State.BINDING).serialize(state);
91                                 } catch (RuntimeSerializerConstructionException | IOException e) {
92                                 }
93                         });
94                 } catch (InterruptedException e) {
95                         LOGGER.error("Serializing state was interrupted.", e);
96                 }
97                 return result[0];
98         }
99
100         public void deserialize(byte[] bytes) {
101                 try {
102                         getRealm().syncExec(() -> {
103                                 StateRootNode rootNode = (StateRootNode) getRoot();
104                                 rootNode.clear();
105                                 try {
106                                         State state = (State) Bindings.getSerializer(State.BINDING).deserialize(bytes);
107                                         for (Map.Entry<String, Variant> entry : state.properties.entrySet()) {
108                                                 String key = entry.getKey();
109                                                 Object value = entry.getValue().getValue();
110                                                 try {
111                                                         setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
112                                                 } catch (NodeManagerException e) {
113                                                         LOGGER.error("Failed to deserialize state.", e);
114                                                 }
115                                         }
116                                         refreshVariable(rootNode);
117                                 } catch (IOException e1) {
118                                         LOGGER.error("Failed to deserialize state.", e1);
119                                 } catch (SerializerConstructionException e1) {
120                                         LOGGER.error("Failed to deserialize state.", e1);
121                                 }
122                         });
123                 } catch (InterruptedException e) {
124                         LOGGER.error("Deserializing state was interrupted.", e);
125                 }
126         }
127
128         public void clearState() {
129                 try {
130                         getRealm().syncExec(() -> {
131                                 StateRootNode rootNode = (StateRootNode) getRoot();
132                                 rootNode.clear();
133                                 refreshVariable(rootNode);
134                         });
135                 } catch (InterruptedException e) {
136                         LOGGER.error("Clearing state was interrupted.", e);
137                 }
138         }
139
140         public void removeState(String key) {
141                 try {
142                         getRealm().syncExec(() -> {
143                                 StateRootNode rootNode = (StateRootNode) getRoot();
144                                 if (rootNode.removeProperty(key)) {
145                                         refreshVariable(rootNode);
146                                 }
147                         });
148                 } catch (InterruptedException e) {
149                         LOGGER.error("Removing state was interrupted.", e);
150                 }
151         }
152
153 }