1 package org.simantics.document.server.state;
3 import java.io.IOException;
4 import java.util.Collections;
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;
20 public class StateNodeManager extends StandardNodeManager<StateNode, StateNodeManagerSupport> {
22 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StateNodeManager.class);
24 private NodeSupport<StateNode> support;
26 public StateNodeManager(StandardRealm<StateNode, StateNodeManagerSupport> realm, StateNode root) {
30 public void registerSupport(NodeSupport<StateNode> support) {
31 this.support = support;
35 public Set<String> getClassifications(StateNode node) throws NodeManagerException {
36 return Collections.emptySet();
40 public void refreshVariable(StateNode node) {
41 super.refreshVariable(node);
42 support.valueCache.clearExpired();
43 support.structureCache.clearExpired();
46 public void setState(String key, Object value) {
48 getRealm().syncExec(() -> {
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);
56 setValue(propertyNode, value, Bindings.OBJECT);
58 } catch (NodeManagerException e) {
59 LOGGER.error("Failed to set state.", e);
62 } catch (InterruptedException e) {
63 LOGGER.error("Setting state was interrupted.", e);
67 public byte[] serialize() {
68 final byte [][] result = new byte[1][];
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;
76 Binding binding = Bindings.getInstanceBinding(property.getValue());
77 if (binding != null) {
78 state.properties.put(property.getName(), new Variant(binding, property.getValue()));
80 } catch (BindingConstructionException e) {
86 result[0] = Bindings.getSerializerUnchecked(State.BINDING).serialize(state);
87 } catch (RuntimeSerializerConstructionException | IOException e) {
90 } catch (InterruptedException e) {
91 LOGGER.error("Serializing state was interrupted.", e);
96 public void deserialize(byte[] bytes) {
98 getRealm().syncExec(() -> {
99 StateRootNode rootNode = (StateRootNode) getRoot();
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();
107 setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
108 } catch (NodeManagerException e) {
109 LOGGER.error("Failed to deserialize state.", e);
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);
119 } catch (InterruptedException e) {
120 LOGGER.error("Deserializing state was interrupted.", e);
124 public void clearState() {
126 getRealm().syncExec(() -> {
127 StateRootNode rootNode = (StateRootNode) getRoot();
129 refreshVariable(rootNode);
131 } catch (InterruptedException e) {
132 LOGGER.error("Clearing state was interrupted.", e);
136 public void removeState(String key) {
138 getRealm().syncExec(() -> {
139 StateRootNode rootNode = (StateRootNode) getRoot();
140 if (rootNode.removeProperty(key)) {
141 refreshVariable(rootNode);
144 } catch (InterruptedException e) {
145 LOGGER.error("Removing state was interrupted.", e);