]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/NodeMapper.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / NodeMapper.java
diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/NodeMapper.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/NodeMapper.java
new file mode 100644 (file)
index 0000000..478d917
--- /dev/null
@@ -0,0 +1,118 @@
+package org.simantics.scenegraph.utils;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import java.util.UUID;\r
+\r
+import org.simantics.scenegraph.ILookupService;\r
+import org.simantics.scenegraph.INode;\r
+\r
+/**\r
+ * A scene graph utility that manages a set of String ID <-> {@link INode}\r
+ * mappings by ensuring that a specified set of nodes have ID mappings.\r
+ * \r
+ * When a node mapper is no longer needed, you should perform cleanup by\r
+ * invoking {@link #clear()}. This will remove all the ID <-> INode mappings\r
+ * managed by the mapper.\r
+ * \r
+ * The implementation is not thread-safe, it should only be used from the canvas\r
+ * context thread (see {@link ICanvasContext#getThreadAccess()).\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ */\r
+public final class NodeMapper {\r
+\r
+    Map<INode, String> nodes        = new HashMap<INode, String>();\r
+    Map<INode, String> managedNodes = new HashMap<INode, String>();\r
+\r
+    public NodeMapper() {\r
+    }\r
+\r
+    public NodeMapper(INode node) {\r
+        add0(node);\r
+    }\r
+\r
+    public void clear() {\r
+        for (Map.Entry<INode, String> entry : managedNodes.entrySet()) {\r
+            ILookupService lu = NodeUtil.tryGetLookupService(entry.getKey());\r
+            if (lu != null) {\r
+                String mappedId = lu.lookupId(entry.getKey());\r
+                if (entry.getValue().equals(mappedId)) {\r
+                    lu.unmap(entry.getKey());\r
+                }\r
+            }\r
+        }\r
+        managedNodes.clear();\r
+        nodes.clear();\r
+    }\r
+\r
+    public NodeMapper(Collection<? extends INode> nodes) {\r
+        addAll(nodes);\r
+    }\r
+\r
+    public String add(INode node) {\r
+        return add0(node);\r
+    }\r
+\r
+    public void addAll(Collection<? extends INode> nodes) {\r
+        for (INode n : nodes) {\r
+            add0(n);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param node\r
+     * @return\r
+     */\r
+    public String remove(INode node) {\r
+        return remove0(node);\r
+    }\r
+\r
+    public String getId(INode node) {\r
+        return nodes.get(node);\r
+    }\r
+\r
+    private String add0(INode node) {\r
+        String id = nodes.get(node);\r
+        if (id != null)\r
+            return id;\r
+\r
+        id = NodeUtil.lookupId(node);\r
+        if (id != null) {\r
+            nodes.put(node, id);\r
+            return id;\r
+        }\r
+\r
+        id = UUID.randomUUID().toString();\r
+        NodeUtil.map(node, id);\r
+        nodes.put(node, id);\r
+        managedNodes.put(node, id);\r
+        return id;\r
+    }\r
+\r
+    /**\r
+     * Removes mapping for specified node if and only if it is mapped through\r
+     * <em>this</em> mapper and the ID currently mapped to matches this mapper's\r
+     * conception of what the ID should be.\r
+     * \r
+     * @param node\r
+     * @return\r
+     */\r
+    private String remove0(INode node) {\r
+        String id = null;\r
+        if ((id = nodes.remove(node)) != null) {\r
+            if (managedNodes.remove(node) != null) {\r
+                ILookupService lu = NodeUtil.tryGetLookupService(node);\r
+                if (lu != null) {\r
+                    String mappedId = lu.lookupId(node);\r
+                    if (id.equals(mappedId)) {\r
+                        lu.unmap(node);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return id;\r
+    }\r
+\r
+}\r