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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
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);
- }
+ private static final Logger LOGGER = LoggerFactory.getLogger(NodeStructureRequest.class);
+
+ 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) {
+ 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.error("Error while computing node structure", 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);
+ }
}
\ No newline at end of file