]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/SCLNodeManager.java
Some fixes for resource cleaning spreadsheets in simupedia
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / SCLNodeManager.java
index a062eb76bfb1a00a52fd924d7c54f462a3e5222e..2e53ce85a8227591f968c592ed4e5fe789f8c662 100644 (file)
-package org.simantics.modeling.scl;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.concurrent.atomic.AtomicBoolean;\r
-\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.variable.NodeSupport;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.simulator.variable.Realm;\r
-import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
-import org.simantics.simulator.variable.exceptions.NotInRealmException;\r
-import org.simantics.simulator.variable.impl.AbstractNodeManager;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectProcedure;\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-public class SCLNodeManager extends AbstractNodeManager<String> {\r
-\r
-    public static final String ROOT = "@";\r
-    \r
-    SCLRealm realm;\r
-    THashMap<String, Object> valueCache = new THashMap<String, Object>(); \r
-    THashMap<String, THashSet<Runnable>> listeners = new THashMap<String, THashSet<Runnable>>(); \r
-    \r
-    AtomicBoolean fireNodeListenersScheduled = new AtomicBoolean(false);\r
-    Runnable fireNodeListeners = new Runnable() {\r
-        @Override\r
-        public void run() {\r
-            fireNodeListenersScheduled.set(false);\r
-            final TObjectProcedure<Runnable> procedure = new TObjectProcedure<Runnable>() {\r
-                @Override\r
-                public boolean execute(Runnable object) {\r
-                    object.run();\r
-                    return true;\r
-                }\r
-            };\r
-            synchronized(listeners) {\r
-                listeners.forEachValue(new TObjectProcedure<THashSet<Runnable>>() {\r
-                    @Override\r
-                    public boolean execute(THashSet<Runnable> object) {\r
-                        object.forEach(procedure);\r
-                        return true;\r
-                    }\r
-                });\r
-            }\r
-        }\r
-    };\r
-    \r
-    Runnable clearValueCache = new Runnable() {\r
-        @Override\r
-        public void run() {\r
-            valueCache.clear(); \r
-        }\r
-    };\r
-    \r
-    public SCLNodeManager(SCLRealm realm) {\r
-        super();\r
-        this.realm = realm;\r
-    }\r
-\r
-    @Override\r
-    public Realm getRealm() {\r
-        return realm;\r
-    }\r
-\r
-    public String getRoot() {\r
-       return ROOT;\r
-    }\r
-    \r
-    @Override\r
-    public String getName(String node) {\r
-        if(ROOT.equals(node)) {\r
-               String id = realm.id;\r
-               int lastSlash = id.lastIndexOf("/");\r
-               if(lastSlash == -1) throw new IllegalStateException("Invalid realm id " + id);\r
-               String name = id.substring(lastSlash+1); \r
-               return name;\r
-        } else\r
-            return node;\r
-    }\r
-\r
-    @Override\r
-    public void addNodeListener(String node, Runnable listener) {\r
-        synchronized(listeners) {\r
-            THashSet<Runnable> l = listeners.get(node);\r
-            if(l == null) {\r
-                l = new THashSet<Runnable>();\r
-                listeners.put(node, l);\r
-            }\r
-            l.add(listener);\r
-        }\r
-        realm.asyncExec(listener);\r
-    }\r
-\r
-    @Override\r
-    public void removeNodeListener(String node, Runnable listener) {\r
-        synchronized(listeners) {\r
-            THashSet<Runnable> l = listeners.get(node);\r
-            if(l != null) {\r
-                l.remove(listener);\r
-                if(l.isEmpty())\r
-                    listeners.remove(node);\r
-            }\r
-        }\r
-    }\r
-    \r
-    public void fireNodeListeners() {\r
-        if(!fireNodeListenersScheduled.getAndSet(true))\r
-            realm.asyncExec(fireNodeListeners);\r
-    }\r
-    \r
-    public void fireNodeListenersSync() {\r
-       try {\r
-                       realm.syncExec(fireNodeListeners);\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-    }\r
-\r
-    public void refreshVariables() {\r
-        realm.asyncExec(clearValueCache);\r
-        fireNodeListeners();\r
-    }\r
-\r
-    public void refreshVariablesSync() {\r
-        try {\r
-                       realm.syncExec(clearValueCache);\r
-               } catch (InterruptedException e) {\r
-                       e.printStackTrace();\r
-               }\r
-        fireNodeListenersSync();\r
-    }\r
-\r
-    @Override\r
-    public String getNode(String path) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        throw new UnsupportedOperationException();\r
-    }\r
-\r
-    @Override\r
-    public String getChild(String node, String name)\r
-            throws NodeManagerException {\r
-        checkThreadAccess();\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public String getProperty(String node, String name)\r
-            throws NodeManagerException {\r
-        checkThreadAccess();\r
-        if(node.equals(ROOT))\r
-            return name;\r
-        else\r
-            return null;\r
-    }\r
-\r
-    @Override\r
-    public List<String> getChildren(String node) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        return Collections.emptyList();\r
-    }\r
-\r
-    @Override\r
-    public List<String> getProperties(String node) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        if(!node.equals(ROOT))\r
-            return Collections.emptyList();\r
-               \r
-        Set<String> variables = realm.getConnection().getVariables();\r
-        return new ArrayList<String>(variables);\r
-               \r
-    }\r
-\r
-    @Override\r
-    public Datatype getDatatype(String node) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        try {\r
-            Datatype type = getDatatypeForValue(getSCLValue(node));\r
-            return type;\r
-        } catch (DatabaseException e) {\r
-            e.printStackTrace();\r
-        }\r
-        return null;\r
-    }\r
-\r
-    @Override\r
-    public Object getValue(String node, Binding binding) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        return getSCLValue(node);\r
-    }\r
-\r
-    \r
-    private Type getType(String name) {\r
-        return realm.getConnection().getVariableType(name);\r
-    }\r
-\r
-    private Datatype getDatatypeForValue(Object value) throws DatabaseException {\r
-       if(value instanceof Double) return Datatypes.DOUBLE;\r
-       if(value instanceof Float) return Datatypes.FLOAT;\r
-       if(value instanceof Integer) return Datatypes.INTEGER;\r
-       if(value instanceof Long) return Datatypes.LONG;\r
-       if(value instanceof String) return Datatypes.STRING;\r
-       if(value instanceof Boolean) return Datatypes.BOOLEAN;\r
-       \r
-       if (value instanceof List) return null;\r
-       \r
-       if (value instanceof Object) return null;\r
-       \r
-       if (value == null) return null;\r
-        \r
-       else throw new DatabaseException("No Datatype for value " + value);\r
-    }\r
-\r
-    @Override\r
-    public void setValue(String node, Object value, Binding binding)\r
-            throws NodeManagerException {\r
-       checkThreadAccess();\r
-       valueCache.put(node, value);\r
-       realm.getConnection().setVariable(node, getType(node), value);\r
-       realm.nodeManager.valueCache.put(node, value);\r
-       refreshVariables();\r
-    }\r
-\r
-    public void setValue(String node, Type type, Object value)\r
-            throws NodeManagerException {\r
-       \r
-       checkThreadAccess();\r
-       valueCache.put(node, value);\r
-       realm.getConnection().setVariable(node, type, value);\r
-       \r
-       NodeSupport support = SCLSessionManager.getOrCreateNodeSupport(realm.getId());\r
-       support.structureCache.put(ROOT, null);\r
-       support.valueCache.put(node, null);\r
-       \r
-       realm.nodeManager.valueCache.put(node, value);\r
-       realm.nodeManager.\r
-       refreshVariables();\r
-    }\r
-    \r
-    static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);\r
-            \r
-    @Override\r
-    public Set<String> getClassifications(String node) throws NodeManagerException {\r
-        checkThreadAccess();\r
-        if(node.equals(ROOT))\r
-            return COMPONENT_CLASS;\r
-        else\r
-            return Collections.emptySet();\r
-    }\r
-\r
-    private Object getSCLValue(String node) throws NodeManagerException {\r
-        Object value = valueCache.get(node);\r
-        if(value == null) {\r
-               value = realm.getConnection().getVariableValue(node);\r
-            valueCache.put(node, value);\r
-        }\r
-        return value;\r
-    }\r
-    \r
-    private void checkThreadAccess() throws NodeManagerException {\r
-        if(Thread.currentThread() != realm.getThread())\r
-            throw new NotInRealmException();\r
-    }\r
-    \r
-    @Override\r
-    public String getPropertyURI(String parent, String property) {\r
-        return "http://www.simantics.org/Modeling-1.2/CommandSession/hasValue";\r
-    }\r
-}\r
+package org.simantics.modeling.scl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.NodeSupport;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.simulator.variable.Realm;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.simantics.simulator.variable.exceptions.NotInRealmException;
+import org.simantics.simulator.variable.impl.AbstractNodeManager;
+import org.simantics.structural.stubs.StructuralResource2;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectProcedure;
+import gnu.trove.set.hash.THashSet;
+
+public class SCLNodeManager extends AbstractNodeManager<String> {
+
+    public static final String ROOT = "@";
+    
+    SCLRealm realm;
+    THashMap<String, Object> valueCache = new THashMap<String, Object>(); 
+    THashMap<String, THashSet<Runnable>> listeners = new THashMap<String, THashSet<Runnable>>(); 
+    
+    AtomicBoolean fireNodeListenersScheduled = new AtomicBoolean(false);
+    Runnable fireNodeListeners = new Runnable() {
+        @Override
+        public void run() {
+            fireNodeListenersScheduled.set(false);
+            final TObjectProcedure<Runnable> procedure = new TObjectProcedure<Runnable>() {
+                @Override
+                public boolean execute(Runnable object) {
+                    object.run();
+                    return true;
+                }
+            };
+            synchronized(listeners) {
+                listeners.forEachValue(new TObjectProcedure<THashSet<Runnable>>() {
+                    @Override
+                    public boolean execute(THashSet<Runnable> object) {
+                        object.forEach(procedure);
+                        return true;
+                    }
+                });
+            }
+        }
+    };
+    
+    Runnable clearValueCache = new Runnable() {
+        @Override
+        public void run() {
+            valueCache.clear(); 
+        }
+    };
+    
+    public SCLNodeManager(SCLRealm realm) {
+        super();
+        this.realm = realm;
+    }
+
+    @Override
+    public Realm getRealm() {
+        return realm;
+    }
+
+    public String getRoot() {
+       return ROOT;
+    }
+    
+    @Override
+    public String getName(String node) {
+        if(ROOT.equals(node)) {
+               String id = realm.getId();
+               int lastSlash = id.lastIndexOf("/");
+               if(lastSlash == -1) throw new IllegalStateException("Invalid realm id " + id);
+               String name = id.substring(lastSlash+1); 
+               return name;
+        } else
+            return node;
+    }
+
+    @Override
+    public void addNodeListener(String node, Runnable listener) {
+        synchronized(listeners) {
+            THashSet<Runnable> l = listeners.get(node);
+            if(l == null) {
+                l = new THashSet<Runnable>();
+                listeners.put(node, l);
+            }
+            l.add(listener);
+        }
+        realm.asyncExec(listener);
+    }
+
+    @Override
+    public void removeNodeListener(String node, Runnable listener) {
+        synchronized(listeners) {
+            THashSet<Runnable> l = listeners.get(node);
+            if(l != null) {
+                l.remove(listener);
+                if(l.isEmpty())
+                    listeners.remove(node);
+            }
+        }
+    }
+    
+    public void fireNodeListeners() {
+        if(!fireNodeListenersScheduled.getAndSet(true))
+            realm.asyncExec(fireNodeListeners);
+    }
+    
+    public void fireNodeListenersSync() {
+       try {
+                       realm.syncExec(fireNodeListeners);
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+    }
+
+    public void refreshVariables() {
+        realm.asyncExec(clearValueCache);
+        fireNodeListeners();
+    }
+
+    public void refreshVariablesSync() {
+        try {
+                       realm.syncExec(clearValueCache);
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+        fireNodeListenersSync();
+    }
+
+    @Override
+    public String getNode(String path) throws NodeManagerException {
+        checkThreadAccess();
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getChild(String node, String name)
+            throws NodeManagerException {
+        checkThreadAccess();
+        return null;
+    }
+
+    @Override
+    public String getProperty(String node, String name)
+            throws NodeManagerException {
+        checkThreadAccess();
+        if(node.equals(ROOT))
+            return name;
+        else
+            return null;
+    }
+
+    @Override
+    public List<String> getChildren(String node) throws NodeManagerException {
+        checkThreadAccess();
+        return Collections.emptyList();
+    }
+
+    @Override
+    public List<String> getProperties(String node) throws NodeManagerException {
+        checkThreadAccess();
+        if(!node.equals(ROOT))
+            return Collections.emptyList();
+               
+        Set<String> variables = realm.getConnection().getVariables();
+        return new ArrayList<String>(variables);
+               
+    }
+
+    @Override
+    public Datatype getDatatype(String node) throws NodeManagerException {
+        checkThreadAccess();
+        try {
+            Datatype type = getDatatypeForValue(getSCLValue(node));
+            return type;
+        } catch (DatabaseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public Object getValue(String node, Binding binding) throws NodeManagerException {
+        checkThreadAccess();
+        return getSCLValue(node);
+    }
+
+    
+    private Type getType(String name) {
+        return realm.getConnection().getVariableType(name);
+    }
+
+    private Datatype getDatatypeForValue(Object value) throws DatabaseException {
+       if(value instanceof Double) return Datatypes.DOUBLE;
+       if(value instanceof Float) return Datatypes.FLOAT;
+       if(value instanceof Integer) return Datatypes.INTEGER;
+       if(value instanceof Long) return Datatypes.LONG;
+       if(value instanceof String) return Datatypes.STRING;
+       if(value instanceof Boolean) return Datatypes.BOOLEAN;
+       
+       if (value instanceof List) return null;
+       
+       if (value instanceof Object) return null;
+       
+       if (value == null) return null;
+        
+       else throw new DatabaseException("No Datatype for value " + value);
+    }
+
+    @Override
+    public void setValue(String node, Object value, Binding binding)
+            throws NodeManagerException {
+       checkThreadAccess();
+       valueCache.put(node, value);
+       realm.getConnection().setVariable(node, getType(node), value);
+       realm.getNodeManager().valueCache.put(node, value);
+       refreshVariables();
+    }
+
+    public void setValue(String node, Type type, Object value)
+            throws NodeManagerException {
+       
+       checkThreadAccess();
+       valueCache.put(node, value);
+       realm.getConnection().setVariable(node, type, value);
+       
+       NodeSupport support = SCLSessionManager.getOrCreateNodeSupport(realm.getId());
+       support.structureCache.put(ROOT, null);
+       support.valueCache.put(node, null);
+       
+       realm.getNodeManager().valueCache.put(node, value);
+       realm.getNodeManager().
+       refreshVariables();
+    }
+    
+    static final Set<String> COMPONENT_CLASS = Collections.singleton(StructuralResource2.URIs.Component);
+            
+    @Override
+    public Set<String> getClassifications(String node) throws NodeManagerException {
+        checkThreadAccess();
+        if(node.equals(ROOT))
+            return COMPONENT_CLASS;
+        else
+            return Collections.emptySet();
+    }
+
+    private Object getSCLValue(String node) throws NodeManagerException {
+        Object value = valueCache.get(node);
+        if(value == null) {
+               value = realm.getConnection().getVariableValue(node);
+            valueCache.put(node, value);
+        }
+        return value;
+    }
+    
+    private void checkThreadAccess() throws NodeManagerException {
+        if(Thread.currentThread() != realm.getThread())
+            throw new NotInRealmException();
+    }
+    
+    @Override
+    public String getPropertyURI(String parent, String property) {
+        return ModelingResources.URIs.SCLCommandSession_hasValue;
+    }
+
+    public void clear() {
+        valueCache.clear();
+        listeners.clear();
+    }
+}