-package org.simantics.db.layer0.variable;\r
-\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.Map;\r
-\r
-import org.simantics.databoard.util.ObjectUtils;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.Variables.NodeStructure;\r
-import org.simantics.db.procedure.Listener;\r
-import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-@SuppressWarnings("rawtypes")\r
-class NodeStructureRequest extends ParametrizedPrimitiveRead<VariableNode, NodeStructure> implements VariableNodeReadRunnable {\r
-\r
- private Listener<NodeStructure> listener = null;\r
- private NodeStructure value = Variables.PENDING_NODE_STRUCTURE;\r
- private boolean wasRun = false;\r
-\r
- static class Probe implements Runnable {\r
-\r
- private VariableNode node;\r
- public NodeStructure result;\r
-\r
- public Probe(VariableNode node) {\r
- this.node = node;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public void run() {\r
- try {\r
- result = NodeStructureRequest.get(node);\r
- node.support.structureCache.put(node.node, result, 1000000000L);\r
- } catch (NodeManagerException e) {\r
- e.printStackTrace();\r
- }\r
- }\r
-\r
- }\r
-\r
- public NodeStructureRequest(VariableNode node) {\r
- super(node);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public void register(ReadGraph graph, final Listener<NodeStructure> procedure) {\r
-\r
- if(procedure.isDisposed()) {\r
-\r
- // We are not listening\r
- NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);\r
-\r
- if(result != null) {\r
- // Return cached value immediately\r
- procedure.execute(result);\r
- } else {\r
- NodeStructureRequest.Probe probe = new Probe(parameter);\r
- parameter.support.manager.getRealm().asyncExec(probe);\r
- if(probe.result != null) {\r
- procedure.execute(probe.result);\r
- } else {\r
- procedure.execute(Variables.PENDING_NODE_STRUCTURE);\r
- }\r
- }\r
-\r
- return;\r
-\r
- }\r
-\r
- // We need to listen\r
- listener = procedure;\r
- // Register listening\r
- parameter.support.manager.addNodeListener(parameter.node, this);\r
- synchronized(this) {\r
- if(wasRun) {\r
- procedure.execute(value);\r
- } else {\r
- NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);\r
- if(result != null) {\r
- procedure.execute(result);\r
- } else {\r
- procedure.execute(Variables.PENDING_NODE_STRUCTURE);\r
- }\r
- }\r
- }\r
-\r
- }\r
-\r
- static class NodeListener implements VariableNodeReadRunnable {\r
-\r
- private VariableNode node;\r
- private NodeStructureRequest request;\r
-\r
- public NodeListener(VariableNode node, NodeStructureRequest request) {\r
- this.node = node;\r
- this.request = request;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public void run() {\r
- node.support.manager.addNodeListener(node.node, request);\r
- }\r
-\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public void unregistered() {\r
- parameter.support.manager.removeNodeListener(parameter.node, this);\r
- parameter.support.structureCache.removeListening(parameter.node);\r
- listener = null;\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- public static NodeStructure get(VariableNode parameter) throws NodeManagerException {\r
- List<?> children = parameter.support.manager.getChildren(parameter.node);\r
- List<?> properties = parameter.support.manager.getProperties(parameter.node);\r
- Map<String, Object> childMap = Collections.emptyMap();\r
- Map<String, Object> propertyMap = childMap;\r
- if(!children.isEmpty()) {\r
- childMap = new THashMap<>(children.size());\r
- for(Object o : children) {\r
- String name = parameter.support.manager.getName(o);\r
- childMap.put(name, o);\r
- }\r
- }\r
- if(!properties.isEmpty()) {\r
- propertyMap = new THashMap<>(properties.size());\r
- for(Object o : properties) {\r
- String name = parameter.support.manager.getName(o);\r
- propertyMap.put(name, o);\r
- }\r
- }\r
- return new NodeStructure(childMap, propertyMap);\r
- }\r
-\r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public synchronized void run() {\r
- try {\r
- // Cache this value with infinite cache time since we are listening\r
- NodeStructure newValue = get(parameter);\r
- if (wasRun && ObjectUtils.objectEquals(value, newValue)) {\r
- //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node);\r
- return;\r
- }\r
- value = newValue;\r
- parameter.support.structureCache.put(parameter.node, value);\r
- } catch (Throwable e) {\r
- // Must catch everything to prevent DB client from getting stuck.\r
- Logger.defaultLogError(e);\r
- // Invoke the exception method of the listener\r
- Listener<NodeStructure> listener = this.listener;\r
- if (listener != null) listener.exception(new DatabaseException("External data access error", e));\r
- wasRun = true;\r
- return;\r
- }\r
-\r
- // Must always invoke an existing listener, regardless of earlier errors.\r
- Listener<NodeStructure> listener = this.listener;\r
- if (listener != null) {\r
- listener.execute(value);\r
- }\r
- wasRun = true;\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return "NodeStructureRequest.run @ " + System.identityHashCode(this);\r
- }\r
-\r
+package org.simantics.db.layer0.variable;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.Variables.NodeStructure;
+import org.simantics.db.procedure.Listener;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+
+import gnu.trove.map.hash.THashMap;
+
+@SuppressWarnings("rawtypes")
+class NodeStructureRequest extends ParametrizedPrimitiveRead<VariableNode, NodeStructure> implements VariableNodeReadRunnable {
+
+ private Listener<NodeStructure> listener = null;
+ private NodeStructure value = Variables.PENDING_NODE_STRUCTURE;
+ private boolean wasRun = false;
+
+ static class Probe implements Runnable {
+
+ private VariableNode node;
+ public NodeStructure result;
+
+ public Probe(VariableNode node) {
+ this.node = node;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ try {
+ result = NodeStructureRequest.get(node);
+ node.support.structureCache.put(node.node, result, 1000000000L);
+ } catch (NodeManagerException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ public NodeStructureRequest(VariableNode node) {
+ super(node);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void register(ReadGraph graph, final Listener<NodeStructure> procedure) {
+
+ if(procedure.isDisposed()) {
+
+ // We are not listening
+ NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
+
+ if(result != null) {
+ // Return cached value immediately
+ procedure.execute(result);
+ } else {
+ NodeStructureRequest.Probe probe = new Probe(parameter);
+ parameter.support.manager.getRealm().asyncExec(probe);
+ if(probe.result != null) {
+ procedure.execute(probe.result);
+ } else {
+ procedure.execute(Variables.PENDING_NODE_STRUCTURE);
+ }
+ }
+
+ return;
+
+ }
+
+ // We need to listen
+ listener = procedure;
+ // Register listening
+ parameter.support.manager.addNodeListener(parameter.node, this);
+ synchronized(this) {
+ if(wasRun) {
+ procedure.execute(value);
+ } else {
+ NodeStructure result = (NodeStructure)parameter.support.structureCache.get(parameter.node);
+ if(result != null) {
+ procedure.execute(result);
+ } else {
+ procedure.execute(Variables.PENDING_NODE_STRUCTURE);
+ }
+ }
+ }
+
+ }
+
+ static class NodeListener implements VariableNodeReadRunnable {
+
+ private VariableNode node;
+ private NodeStructureRequest request;
+
+ public NodeListener(VariableNode node, NodeStructureRequest request) {
+ this.node = node;
+ this.request = request;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void run() {
+ node.support.manager.addNodeListener(node.node, request);
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void unregistered() {
+ parameter.support.manager.removeNodeListener(parameter.node, this);
+ parameter.support.structureCache.removeListening(parameter.node);
+ listener = null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static NodeStructure get(VariableNode parameter) throws NodeManagerException {
+ List<?> children = parameter.support.manager.getChildren(parameter.node);
+ List<?> properties = parameter.support.manager.getProperties(parameter.node);
+ Map<String, Object> childMap = Collections.emptyMap();
+ Map<String, Object> propertyMap = childMap;
+ if(!children.isEmpty()) {
+ childMap = new THashMap<>(children.size());
+ for(Object o : children) {
+ String name = parameter.support.manager.getName(o);
+ childMap.put(name, o);
+ }
+ }
+ if(!properties.isEmpty()) {
+ propertyMap = new THashMap<>(properties.size());
+ for(Object o : properties) {
+ String name = parameter.support.manager.getName(o);
+ propertyMap.put(name, o);
+ }
+ }
+ return new NodeStructure(childMap, propertyMap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public synchronized void run() {
+ try {
+ // Cache this value with infinite cache time since we are listening
+ NodeStructure newValue = get(parameter);
+ if (wasRun && ObjectUtils.objectEquals(value, newValue)) {
+ //System.out.println("CACHE VALUE MATCH (" + newValue + ") for " + node.node);
+ return;
+ }
+ value = newValue;
+ parameter.support.structureCache.put(parameter.node, value);
+ } catch (Throwable e) {
+ // Must catch everything to prevent DB client from getting stuck.
+ Logger.defaultLogError(e);
+ // Invoke the exception method of the listener
+ Listener<NodeStructure> listener = this.listener;
+ if (listener != null) listener.exception(new DatabaseException("External data access error", e));
+ wasRun = true;
+ return;
+ }
+
+ // Must always invoke an existing listener, regardless of earlier errors.
+ Listener<NodeStructure> listener = this.listener;
+ if (listener != null) {
+ listener.execute(value);
+ }
+ wasRun = true;
+ }
+
+ @Override
+ public String toString() {
+ return "NodeStructureRequest.run @ " + System.identityHashCode(this);
+ }
+