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