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