]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java
63a1924dcaad8621a9f9968e478fbe05b7909c70
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / scenegraph / base / ParentNode.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g3d.scenegraph.base;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collection;\r
16 import java.util.List;\r
17 \r
18 import org.simantics.utils.datastructures.MapList;\r
19 \r
20 public abstract class ParentNode<T extends INode> extends Node {\r
21 \r
22         private MapList<String, T> children = new MapList<String, T>();\r
23 \r
24         public synchronized void addNode(String relName, T child) {\r
25                 if (child.getParent() != null)\r
26                         child.getParent().removeNode(child.getParentRel(), child);\r
27 \r
28                 child.setParent(this, relName);\r
29                 children.add(relName, (T) child);\r
30 \r
31                 childrenChanged();\r
32                 fireNodeAdded(child, relName);\r
33         }\r
34 \r
35         /**\r
36          * Removes child node and it's hierarchy.\r
37          * @param relName\r
38          * @param child\r
39          * @return\r
40          */\r
41         @SuppressWarnings("unchecked")\r
42         public synchronized final boolean removeNode(String relName, INode child) {\r
43                 if (children.remove(relName, (T) child)) {\r
44                         fireNodeRemoved(child, relName);\r
45                     child.remove();\r
46                         child.setParent(null, null);\r
47                         return true;\r
48                 }\r
49                 return false;\r
50         }\r
51         \r
52         /**\r
53          * Removes child node. The child nodes hierarchy is left intact.\r
54          * @param relName\r
55          * @param child\r
56          * @return\r
57          */\r
58         @SuppressWarnings("unchecked")\r
59         public synchronized final boolean deattachNode(String relName, INode child) {\r
60                 if (children.remove(relName, (T) child)) {\r
61                         fireNodeRemoved(child, relName);\r
62                         child.setParent(null, null);\r
63                         return true;\r
64                 }\r
65                 return false;\r
66         }\r
67         \r
68         public synchronized final boolean removeNodes(String relName) {\r
69                 List<T> nodes = children.getValues(relName);\r
70                 for (T child : nodes) {\r
71                         if (children.remove(relName, (T) child)) {\r
72                                 fireNodeRemoved(child, relName);\r
73                             child.remove();\r
74                                 child.setParent(null, null);\r
75                                 \r
76                         }\r
77                 }\r
78                 return nodes.size() > 0;\r
79         }\r
80 \r
81         public synchronized final void removeNodes() {\r
82                 synchronized (children) {\r
83                         boolean changed = false;\r
84                         for (String key : children.getKeys()) {\r
85                                 for (T child : children.getValues(key)) {\r
86                                         if (child != null) {\r
87                                                 changed = true;\r
88                                                 if (child instanceof ParentNode<?>) {\r
89                                                         ((ParentNode<?>) child).removeNodes();\r
90                                                 }\r
91                                                 child.cleanup();\r
92                                                 child.setParent(null, null);\r
93                                                 // if (propertyChangeListener != null) {\r
94                                                 // propertyChangeListener.propertyChange(new\r
95                                                 // PropertyChangeEvent(this,\r
96                                                 // "children["+child.getId()+"]", child.getClass(),\r
97                                                 // NULL)); // "children" is a special field name\r
98                                                 // }\r
99                                         }\r
100                                 }\r
101                         }\r
102                         children.clear();\r
103                         if (changed)\r
104                                 childrenChanged();\r
105                 }\r
106         }\r
107 \r
108         public synchronized List<T> getNodes(String rel) {\r
109                 return children.getValues(rel);\r
110         }\r
111 \r
112         public synchronized List<T> getNodes() {\r
113                 List<T> result = new ArrayList<T>();\r
114                 for (String s : children.getKeys())\r
115                         result.addAll(children.getValues(s));\r
116                 return result;\r
117         }\r
118 \r
119         protected void childrenChanged() {\r
120         }\r
121 \r
122 \r
123         @Override\r
124         public void remove() {\r
125                 synchronized (children) {\r
126                         List<T> toRemove = new ArrayList<T>();\r
127                 \r
128                         for (String key : children.getKeys()) {\r
129                 \r
130                                 for (T child : children.getValues(key)) {\r
131                                         if (child != null) {\r
132                                                 toRemove.add(child);\r
133                                         }\r
134                                 }\r
135                         }\r
136 \r
137                         for (T n : toRemove) {\r
138                                 n.remove();\r
139                         }\r
140                         \r
141                         children.clear();\r
142                         if (toRemove.size() > 0)\r
143                                 childrenChanged();\r
144                         super.remove();\r
145                         \r
146                 }\r
147         }\r
148         \r
149         \r
150         \r
151         \r
152         protected void fireNodeAdded(INode node, String rel) {\r
153                 for (NodeListener listener : listeners) {\r
154                         listener.nodeAdded(this, node, rel);\r
155                 }\r
156         }\r
157         \r
158         protected void fireNodeRemoved(INode node, String rel) {\r
159                 for (NodeListener listener : listeners) {\r
160                         listener.nodeRemoved(this, node, rel);\r
161                 }\r
162         }\r
163         \r
164 }\r