1 package org.simantics.scenegraph.utils;
\r
3 import java.util.Collection;
\r
4 import java.util.HashMap;
\r
5 import java.util.Map;
\r
6 import java.util.UUID;
\r
8 import org.simantics.scenegraph.ILookupService;
\r
9 import org.simantics.scenegraph.INode;
\r
12 * A scene graph utility that manages a set of String ID <-> {@link INode}
\r
13 * mappings by ensuring that a specified set of nodes have ID mappings.
\r
15 * When a node mapper is no longer needed, you should perform cleanup by
\r
16 * invoking {@link #clear()}. This will remove all the ID <-> INode mappings
\r
17 * managed by the mapper.
\r
19 * The implementation is not thread-safe, it should only be used from the canvas
\r
20 * context thread (see {@link ICanvasContext#getThreadAccess()).
\r
22 * @author Tuukka Lehtonen
\r
24 public final class NodeMapper {
\r
26 Map<INode, String> nodes = new HashMap<INode, String>();
\r
27 Map<INode, String> managedNodes = new HashMap<INode, String>();
\r
29 public NodeMapper() {
\r
32 public NodeMapper(INode node) {
\r
36 public void clear() {
\r
37 for (Map.Entry<INode, String> entry : managedNodes.entrySet()) {
\r
38 ILookupService lu = NodeUtil.tryGetLookupService(entry.getKey());
\r
40 String mappedId = lu.lookupId(entry.getKey());
\r
41 if (entry.getValue().equals(mappedId)) {
\r
42 lu.unmap(entry.getKey());
\r
46 managedNodes.clear();
\r
50 public NodeMapper(Collection<? extends INode> nodes) {
\r
54 public String add(INode node) {
\r
58 public void addAll(Collection<? extends INode> nodes) {
\r
59 for (INode n : nodes) {
\r
68 public String remove(INode node) {
\r
69 return remove0(node);
\r
72 public String getId(INode node) {
\r
73 return nodes.get(node);
\r
76 private String add0(INode node) {
\r
77 String id = nodes.get(node);
\r
81 id = NodeUtil.lookupId(node);
\r
83 nodes.put(node, id);
\r
87 id = UUID.randomUUID().toString();
\r
88 NodeUtil.map(node, id);
\r
89 nodes.put(node, id);
\r
90 managedNodes.put(node, id);
\r
95 * Removes mapping for specified node if and only if it is mapped through
\r
96 * <em>this</em> mapper and the ID currently mapped to matches this mapper's
\r
97 * conception of what the ID should be.
\r
102 private String remove0(INode node) {
\r
104 if ((id = nodes.remove(node)) != null) {
\r
105 if (managedNodes.remove(node) != null) {
\r
106 ILookupService lu = NodeUtil.tryGetLookupService(node);
\r
108 String mappedId = lu.lookupId(node);
\r
109 if (id.equals(mappedId)) {
\r