1 package org.simantics.document.server.state;
3 import java.io.IOException;
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;
17 public class StateNodeManager extends StandardVariableNodeManager<StateNode, StateNodeManagerSupport> {
19 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(StateNodeManager.class);
21 public StateNodeManager(StandardRealm<StateNode, StateNodeManagerSupport> realm, StateNode root) {
25 public void setState(String key, Object value) {
27 getRealm().syncExec(() -> {
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);
35 setValue(propertyNode, value, Bindings.OBJECT);
37 } catch (NodeManagerException e) {
38 LOGGER.error("Failed to set state.", e);
41 } catch (InterruptedException e) {
42 LOGGER.error("Setting state was interrupted.", e);
46 public byte[] serialize() {
47 final byte [][] result = new byte[1][];
49 getRealm().syncExec(() -> {
50 State state = new State();
51 StateRootNode root = (StateRootNode) getRoot();
52 for (StateNode node : root.getProperties().values()) {
53 StatePropertyNode property = (StatePropertyNode)node;
55 Binding binding = Bindings.getInstanceBinding(property.getValue());
56 if (binding != null) {
57 state.properties.put(property.getName(), new Variant(binding, property.getValue()));
59 } catch (BindingConstructionException e) {
65 result[0] = Bindings.getSerializerUnchecked(State.BINDING).serialize(state);
66 } catch (RuntimeSerializerConstructionException | IOException e) {
69 } catch (InterruptedException e) {
70 LOGGER.error("Serializing state was interrupted.", e);
75 public void deserialize(byte[] bytes) {
77 getRealm().syncExec(() -> {
78 StateRootNode rootNode = (StateRootNode) getRoot();
81 State state = (State) Bindings.getSerializer(State.BINDING).deserialize(bytes);
82 for (Map.Entry<String, Variant> entry : state.properties.entrySet()) {
83 String key = entry.getKey();
84 Object value = entry.getValue().getValue();
86 setValue(rootNode.createProperty(key), value, Bindings.OBJECT);
87 } catch (NodeManagerException e) {
88 LOGGER.error("Failed to deserialize state.", e);
91 refreshVariable(rootNode);
92 } catch (IOException e1) {
93 LOGGER.error("Failed to deserialize state.", e1);
94 } catch (SerializerConstructionException e1) {
95 LOGGER.error("Failed to deserialize state.", e1);
98 } catch (InterruptedException e) {
99 LOGGER.error("Deserializing state was interrupted.", e);
103 public void clearState() {
105 getRealm().syncExec(() -> {
106 StateRootNode rootNode = (StateRootNode) getRoot();
108 refreshVariable(rootNode);
110 } catch (InterruptedException e) {
111 LOGGER.error("Clearing state was interrupted.", e);
115 public void removeState(String key) {
117 getRealm().syncExec(() -> {
118 StateRootNode rootNode = (StateRootNode) getRoot();
119 if (rootNode.removeProperty(key)) {
120 refreshVariable(rootNode);
123 } catch (InterruptedException e) {
124 LOGGER.error("Removing state was interrupted.", e);