]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/NodeMapper.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / NodeMapper.java
1 package org.simantics.scenegraph.utils;
2
3 import java.util.Collection;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.UUID;
7
8 import org.simantics.scenegraph.ILookupService;
9 import org.simantics.scenegraph.INode;
10
11 /**
12  * A scene graph utility that manages a set of String ID <-> {@link INode}
13  * mappings by ensuring that a specified set of nodes have ID mappings.
14  * 
15  * When a node mapper is no longer needed, you should perform cleanup by
16  * invoking {@link #clear()}. This will remove all the ID <-> INode mappings
17  * managed by the mapper.
18  * 
19  * The implementation is not thread-safe, it should only be used from the canvas
20  * context thread (see {@link ICanvasContext#getThreadAccess()).
21  * 
22  * @author Tuukka Lehtonen
23  */
24 public final class NodeMapper {
25
26     Map<INode, String> nodes        = new HashMap<INode, String>();
27     Map<INode, String> managedNodes = new HashMap<INode, String>();
28
29     public NodeMapper() {
30     }
31
32     public NodeMapper(INode node) {
33         add0(node);
34     }
35
36     public void clear() {
37         for (Map.Entry<INode, String> entry : managedNodes.entrySet()) {
38             ILookupService lu = NodeUtil.tryGetLookupService(entry.getKey());
39             if (lu != null) {
40                 String mappedId = lu.lookupId(entry.getKey());
41                 if (entry.getValue().equals(mappedId)) {
42                     lu.unmap(entry.getKey());
43                 }
44             }
45         }
46         managedNodes.clear();
47         nodes.clear();
48     }
49
50     public NodeMapper(Collection<? extends INode> nodes) {
51         addAll(nodes);
52     }
53
54     public String add(INode node) {
55         return add0(node);
56     }
57
58     public void addAll(Collection<? extends INode> nodes) {
59         for (INode n : nodes) {
60             add0(n);
61         }
62     }
63
64     /**
65      * @param node
66      * @return
67      */
68     public String remove(INode node) {
69         return remove0(node);
70     }
71
72     public String getId(INode node) {
73         return nodes.get(node);
74     }
75
76     private String add0(INode node) {
77         String id = nodes.get(node);
78         if (id != null)
79             return id;
80
81         id = NodeUtil.lookupId(node);
82         if (id != null) {
83             nodes.put(node, id);
84             return id;
85         }
86
87         id = UUID.randomUUID().toString();
88         NodeUtil.map(node, id);
89         nodes.put(node, id);
90         managedNodes.put(node, id);
91         return id;
92     }
93
94     /**
95      * Removes mapping for specified node if and only if it is mapped through
96      * <em>this</em> mapper and the ID currently mapped to matches this mapper's
97      * conception of what the ID should be.
98      * 
99      * @param node
100      * @return
101      */
102     private String remove0(INode node) {
103         String id = null;
104         if ((id = nodes.remove(node)) != null) {
105             if (managedNodes.remove(node) != null) {
106                 ILookupService lu = NodeUtil.tryGetLookupService(node);
107                 if (lu != null) {
108                     String mappedId = lu.lookupId(node);
109                     if (id.equals(mappedId)) {
110                         lu.unmap(node);
111                     }
112                 }
113             }
114         }
115         return id;
116     }
117
118 }