##### Coverage Report - org.apache.commons.configuration.tree.DefaultConfigurationNode

Classes in this File | Line Coverage | Branch Coverage | Complexity
DefaultConfigurationNode |
97% | 72/74
100% | 4/4
| 1.6041666666666667;1,604
DefaultConfigurationNode$SubNodes |
100% | 58/58
100% | 18/18
| 1.6041666666666667;1,604

1 |  |
     /*
2 |  |
      * Licensed to the Apache Software Foundation (ASF) under one or more
3 |  |
      * contributor license agreements.  See the NOTICE file distributed with
4 |  |
      * this work for additional information regarding copyright ownership.
5 |  |
      * The ASF licenses this file to You under the Apache License, Version 2.0
6 |  |
      * (the "License"); you may not use this file except in compliance with
7 |  |
      * the License.  You may obtain a copy of the License at
8 |  |
      *
9 |  |
      *     http://www.apache.org/licenses/LICENSE-2.0
10 |  |
      *
11 |  |
      * Unless required by applicable law or agreed to in writing, software
12 |  |
      * distributed under the License is distributed on an "AS IS" BASIS,
13 |  |
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 |  |
      * See the License for the specific language governing permissions and
15 |  |
      * limitations under the License.
16 |  |
      */
17 |  |
     package org.apache.commons.configuration.tree;
18 |  |
19 |  |
     import java.util.ArrayList;
20 |  |
     import java.util.Collection;
21 |  |
     import java.util.Collections;
22 |  |
     import java.util.HashMap;
23 |  |
     import java.util.Iterator;
24 |  |
     import java.util.LinkedList;
25 |  |
     import java.util.List;
26 |  |
     import java.util.Map;
27 |  |
28 |  |
     import org.apache.commons.configuration.ConfigurationRuntimeException;
29 |  |
30 |  |
     /**
31 |  |
      * <p>
32 |  |
      * A default implementation of the <code>ConfigurationNode</code> interface.
33 |  |
      * </p>
34 |  |
      *
35 |  |
      * @since 1.3
36 |  |
      * @author Oliver Heger
37 |  |
      */
38 |  |
     public class DefaultConfigurationNode implements ConfigurationNode, Cloneable
39 |  |
     {
40 |  |
         /** Stores the children of this node. */
41 |  |
         private SubNodes children;
42 |  |
43 |  |
         /** Stores the attributes of this node. */
44 |  |
         private SubNodes attributes;
45 |  |
46 |  |
         /** Stores a reference to this node's parent. */
47 |  |
         private ConfigurationNode parent;
48 |  |
49 |  |
         /** Stores the value of this node. */
50 |  |
         private Object value;
51 |  |
52 |  |
         /** Stores the reference. */
53 |  |
         private Object reference;
54 |  |
55 |  |
         /** Stores the name of this node. */
56 |  |
         private String name;
57 |  |
58 |  |
         /** Stores a flag if this is an attribute. */
59 |  |
         private boolean attribute;
60 |  |
61 |  |
         /**
62 |  |
          * Creates a new uninitialized instance of
63 |  |
          * <code>DefaultConfigurationNode</code>.
64 |  |
          */
65 |  |
         public DefaultConfigurationNode()
66 |  |
         {
67 | 3482 |
             this(null);
68 | 3482 |
         }
69 |  |
70 |  |
         /**
71 |  |
          * Creates a new instance of <code>DefaultConfigurationNode</code> and
72 |  |
          * initializes it with the node name.
73 |  |
          *
74 |  |
          * @param name the name of this node
75 |  |
          */
76 |  |
         public DefaultConfigurationNode(String name)
77 |  |
         {
78 | 45019 |
             this(name, null);
79 | 45019 |
         }
80 |  |
81 |  |
         /**
82 |  |
          * Creates a new instance of <code>DefaultConfigurationNode</code> and
83 |  |
          * initializes it with the name and a value.
84 |  |
          *
85 |  |
          * @param name the node's name
86 |  |
          * @param value the node's value
87 |  |
          */
88 |  |
         public DefaultConfigurationNode(String name, Object value)
89 | 90927 |
         {
90 | 90927 |
             setName(name);
91 | 90927 |
             setValue(value);
92 | 90927 |
             initSubNodes();
93 | 90927 |
         }
94 |  |
95 |  |
         /**
96 |  |
          * Returns the name of this node.
97 |  |
          *
98 |  |
          * @return the name of this node
99 |  |
          */
100 |  |
         public String getName()
101 |  |
         {
102 | 291644 |
             return name;
103 |  |
         }
104 |  |
105 |  |
         /**
106 |  |
          * Sets the name of this node.
107 |  |
          *
108 |  |
          * @param name the new name
109 |  |
          */
110 |  |
         public void setName(String name)
111 |  |
         {
112 | 93119 |
             checkState();
113 | 93119 |
             this.name = name;
114 | 93119 |
         }
115 |  |
116 |  |
         /**
117 |  |
          * Returns the value of this node.
118 |  |
          *
119 |  |
          * @return the value of this node
120 |  |
          */
121 |  |
         public Object getValue()
122 |  |
         {
123 | 108204 |
             return value;
124 |  |
         }
125 |  |
126 |  |
         /**
127 |  |
          * Sets the value of this node.
128 |  |
          *
129 |  |
          * @param val the value of this node
130 |  |
          */
131 |  |
         public void setValue(Object val)
132 |  |
         {
133 | 146255 |
             value = val;
134 | 146255 |
         }
135 |  |
136 |  |
         /**
137 |  |
          * Returns the reference.
138 |  |
          *
139 |  |
          * @return the reference
140 |  |
          */
141 |  |
         public Object getReference()
142 |  |
         {
143 | 114063 |
             return reference;
144 |  |
         }
145 |  |
146 |  |
         /**
147 |  |
          * Sets the reference.
148 |  |
          *
149 |  |
          * @param reference the reference object
150 |  |
          */
151 |  |
         public void setReference(Object reference)
152 |  |
         {
153 | 40788 |
             this.reference = reference;
154 | 40788 |
         }
155 |  |
156 |  |
         /**
157 |  |
          * Returns a reference to this node's parent.
158 |  |
          *
159 |  |
          * @return the parent node or <b>null </b> if this is the root
160 |  |
          */
161 |  |
         public ConfigurationNode getParentNode()
162 |  |
         {
163 | 200924 |
             return parent;
164 |  |
         }
165 |  |
166 |  |
         /**
167 |  |
          * Sets the parent of this node.
168 |  |
          *
169 |  |
          * @param parent the parent of this node
170 |  |
          */
171 |  |
         public void setParentNode(ConfigurationNode parent)
172 |  |
         {
173 | 198090 |
             this.parent = parent;
174 | 198090 |
         }
175 |  |
176 |  |
         /**
177 |  |
          * Adds a new child to this node.
178 |  |
          *
179 |  |
          * @param child the new child
180 |  |
          */
181 |  |
         public void addChild(ConfigurationNode child)
182 |  |
         {
183 | 60729 |
             children.addNode(child);
184 | 60727 |
             child.setAttribute(false);
185 | 60727 |
             child.setParentNode(this);
186 | 60727 |
         }
187 |  |
188 |  |
         /**
189 |  |
          * Returns a list with all children of this node.
190 |  |
          *
191 |  |
          * @return a list with all child nodes
192 |  |
          */
193 |  |
         public List getChildren()
194 |  |
         {
195 | 14194 |
             return children.getSubNodes();
196 |  |
         }
197 |  |
198 |  |
         /**
199 |  |
          * Returns the number of all children of this node.
200 |  |
          *
201 |  |
          * @return the number of all children
202 |  |
          */
203 |  |
         public int getChildrenCount()
204 |  |
         {
205 | 11711 |
             return children.getSubNodes().size();
206 |  |
         }
207 |  |
208 |  |
         /**
209 |  |
          * Returns a list of all children with the given name.
210 |  |
          *
211 |  |
          * @param name the name; can be <b>null </b>, then all children are returned
212 |  |
          * @return a list of all children with the given name
213 |  |
          */
214 |  |
         public List getChildren(String name)
215 |  |
         {
216 | 25571 |
             return children.getSubNodes(name);
217 |  |
         }
218 |  |
219 |  |
         /**
220 |  |
          * Returns the number of children with the given name.
221 |  |
          *
222 |  |
          * @param name the name; can be <b>null </b>, then the number of all
223 |  |
          * children is returned
224 |  |
          * @return the number of child nodes with this name
225 |  |
          */
226 |  |
         public int getChildrenCount(String name)
227 |  |
         {
228 | 12450 |
             return children.getSubNodes(name).size();
229 |  |
         }
230 |  |
231 |  |
         /**
232 |  |
          * Returns the child node with the given index.
233 |  |
          *
234 |  |
          * @param index the index (0-based)
235 |  |
          * @return the child with this index
236 |  |
          */
237 |  |
         public ConfigurationNode getChild(int index)
238 |  |
         {
239 | 861 |
             return children.getNode(index);
240 |  |
         }
241 |  |
242 |  |
         /**
243 |  |
          * Removes the specified child node from this node.
244 |  |
          *
245 |  |
          * @param child the node to be removed
246 |  |
          * @return a flag if a node was removed
247 |  |
          */
248 |  |
         public boolean removeChild(ConfigurationNode child)
249 |  |
         {
250 | 10185 |
             return children.removeNode(child);
251 |  |
         }
252 |  |
253 |  |
         /**
254 |  |
          * Removes all children with the given name.
255 |  |
          *
256 |  |
          * @param childName the name of the children to be removed
257 |  |
          * @return a flag if at least one child node was removed
258 |  |
          */
259 |  |
         public boolean removeChild(String childName)
260 |  |
         {
261 | 9 |
             return children.removeNodes(childName);
262 |  |
         }
263 |  |
264 |  |
         /**
265 |  |
          * Removes all child nodes of this node.
266 |  |
          */
267 |  |
         public void removeChildren()
268 |  |
         {
269 | 3 |
             children.clear();
270 | 3 |
         }
271 |  |
272 |  |
         /**
273 |  |
          * Checks if this node is an attribute node.
274 |  |
          *
275 |  |
          * @return a flag if this is an attribute node
276 |  |
          */
277 |  |
         public boolean isAttribute()
278 |  |
         {
279 | 29400 |
             return attribute;
280 |  |
         }
281 |  |
282 |  |
         /**
283 |  |
          * Sets the attribute flag. Note: this method can only be called if the node
284 |  |
          * is not already part of a node hierarchy.
285 |  |
          *
286 |  |
          * @param f the attribute flag
287 |  |
          */
288 |  |
         public void setAttribute(boolean f)
289 |  |
         {
290 | 93538 |
             checkState();
291 | 93537 |
             attribute = f;
292 | 93537 |
         }
293 |  |
294 |  |
         /**
295 |  |
          * Adds the specified attribute to this node.
296 |  |
          *
297 |  |
          * @param attr the attribute to be added
298 |  |
          */
299 |  |
         public void addAttribute(ConfigurationNode attr)
300 |  |
         {
301 | 32798 |
             attributes.addNode(attr);
302 | 32798 |
             attr.setAttribute(true);
303 | 32798 |
             attr.setParentNode(this);
304 | 32798 |
         }
305 |  |
306 |  |
         /**
307 |  |
          * Returns a list with the attributes of this node. This list contains
308 |  |
          * <code>ConfigurationNode</code> objects, too.
309 |  |
          *
310 |  |
          * @return the attribute list, never <b>null </b>
311 |  |
          */
312 |  |
         public List getAttributes()
313 |  |
         {
314 | 11112 |
             return attributes.getSubNodes();
315 |  |
         }
316 |  |
317 |  |
         /**
318 |  |
          * Returns the number of attributes contained in this node.
319 |  |
          *
320 |  |
          * @return the number of attributes
321 |  |
          */
322 |  |
         public int getAttributeCount()
323 |  |
         {
324 | 3616 |
             return attributes.getSubNodes().size();
325 |  |
         }
326 |  |
327 |  |
         /**
328 |  |
          * Returns a list with all attributes of this node with the given name.
329 |  |
          *
330 |  |
          * @param name the attribute's name
331 |  |
          * @return all attributes with this name
332 |  |
          */
333 |  |
         public List getAttributes(String name)
334 |  |
         {
335 | 7675 |
             return attributes.getSubNodes(name);
336 |  |
         }
337 |  |
338 |  |
         /**
339 |  |
          * Returns the number of attributes of this node with the given name.
340 |  |
          *
341 |  |
          * @param name the name
342 |  |
          * @return the number of attributes with this name
343 |  |
          */
344 |  |
         public int getAttributeCount(String name)
345 |  |
         {
346 | 39 |
             return getAttributes(name).size();
347 |  |
         }
348 |  |
349 |  |
         /**
350 |  |
          * Removes the specified attribute.
351 |  |
          *
352 |  |
          * @param node the attribute node to be removed
353 |  |
          * @return a flag if the attribute could be removed
354 |  |
          */
355 |  |
         public boolean removeAttribute(ConfigurationNode node)
356 |  |
         {
357 | 1 |
             return attributes.removeNode(node);
358 |  |
         }
359 |  |
360 |  |
         /**
361 |  |
          * Removes all attributes with the specified name.
362 |  |
          *
363 |  |
          * @param name the name
364 |  |
          * @return a flag if at least one attribute was removed
365 |  |
          */
366 |  |
         public boolean removeAttribute(String name)
367 |  |
         {
368 | 7 |
             return attributes.removeNodes(name);
369 |  |
         }
370 |  |
371 |  |
         /**
372 |  |
          * Returns the attribute with the given index.
373 |  |
          *
374 |  |
          * @param index the index (0-based)
375 |  |
          * @return the attribute with this index
376 |  |
          */
377 |  |
         public ConfigurationNode getAttribute(int index)
378 |  |
         {
379 | 791 |
             return attributes.getNode(index);
380 |  |
         }
381 |  |
382 |  |
         /**
383 |  |
          * Removes all attributes of this node.
384 |  |
          */
385 |  |
         public void removeAttributes()
386 |  |
         {
387 | 1 |
             attributes.clear();
388 | 1 |
         }
389 |  |
390 |  |
         /**
391 |  |
          * Returns a flag if this node is defined. This means that the node contains
392 |  |
          * some data.
393 |  |
          *
394 |  |
          * @return a flag whether this node is defined
395 |  |
          */
396 |  |
         public boolean isDefined()
397 |  |
         {
398 | 1 |
             return getValue() != null || getChildrenCount() > 0
399 |  |
                     || getAttributeCount() > 0;
400 |  |
         }
401 |  |
402 |  |
         /**
403 |  |
          * Visits this node and all its sub nodes.
404 |  |
          *
405 |  |
          * @param visitor the visitor
406 |  |
          */
407 |  |
         public void visit(ConfigurationNodeVisitor visitor)
408 |  |
         {
409 | 45574 |
             if (visitor == null)
410 |  |
             {
411 | 1 |
                 throw new IllegalArgumentException("Visitor must not be null!");
412 |  |
             }
413 |  |
414 | 45573 |
             if (!visitor.terminate())
415 |  |
             {
416 | 45573 |
                 visitor.visitBeforeChildren(this);
417 | 45573 |
                 children.visit(visitor);
418 | 45573 |
                 attributes.visit(visitor);
419 | 45573 |
                 visitor.visitAfterChildren(this);
420 |  |
             } /* if */
421 | 45573 |
         }
422 |  |
423 |  |
         /**
424 |  |
          * Creates a copy of this object. This is not a deep copy, the children are
425 |  |
          * not cloned.
426 |  |
          *
427 |  |
          * @return a copy of this object
428 |  |
          */
429 |  |
         public Object clone()
430 |  |
         {
431 |  |
             try
432 |  |
             {
433 | 827 |
                 DefaultConfigurationNode copy = (DefaultConfigurationNode) super
434 |  |
                         .clone();
435 | 827 |
                 copy.initSubNodes();
436 | 827 |
                 return copy;
437 |  |
             }
438 | 0 |
             catch (CloneNotSupportedException cex)
439 |  |
             {
440 |  |
                 // should not happen
441 | 0 |
                 throw new ConfigurationRuntimeException("Cannot clone " + getClass());
442 |  |
             }
443 |  |
         }
444 |  |
445 |  |
         /**
446 |  |
          * Checks if a modification of this node is allowed. Some properties of a
447 |  |
          * node must not be changed when the node has a parent. This method checks
448 |  |
          * this and throws a runtime exception if necessary.
449 |  |
          */
450 |  |
         protected void checkState()
451 |  |
         {
452 | 186657 |
             if (getParentNode() != null)
453 |  |
             {
454 | 1 |
                 throw new IllegalStateException(
455 |  |
                         "Node cannot be modified when added to a parent!");
456 |  |
             }
457 | 186656 |
         }
458 |  |
459 |  |
         /**
460 |  |
          * Creates a <code>SubNodes</code> instance that is used for storing
461 |  |
          * either this node's children or attributes.
462 |  |
          *
463 |  |
          * @param attributes <b>true</b> if the returned instance is used for
464 |  |
          * storing attributes, <b>false</b> for storing child nodes
465 |  |
          * @return the <code>SubNodes</code> object to use
466 |  |
          */
467 |  |
         protected SubNodes createSubNodes(boolean attributes)
468 |  |
         {
469 | 183508 |
             return new SubNodes();
470 |  |
         }
471 |  |
472 |  |
         /**
473 |  |
          * Deals with the reference when a node is removed. This method is called
474 |  |
          * for each removed child node or attribute. It can be overloaded in sub
475 |  |
          * classes, for which the reference has a concrete meaning and remove
476 |  |
          * operations need some update actions. This default implementation is
477 |  |
          * empty.
478 |  |
          */
479 |  |
         protected void removeReference()
480 |  |
         {
481 | 252 |
         }
482 |  |
483 |  |
         /**
484 |  |
          * Helper method for initializing the sub nodes objects.
485 |  |
          */
486 |  |
         private void initSubNodes()
487 |  |
         {
488 | 91754 |
             children = createSubNodes(false);
489 | 91754 |
             attributes = createSubNodes(true);
490 | 91754 |
         }
491 |  |
492 |  |
         /**
493 |  |
          * An internally used helper class for managing a collection of sub nodes.
494 |  |
          */
495 | 183508 |
         protected static class SubNodes
496 |  |
         {
497 |  |
             /** Stores a list for the sub nodes. */
498 |  |
             private List nodes;
499 |  |
500 |  |
             /** Stores a map for accessing subnodes by name. */
501 |  |
             private Map namedNodes;
502 |  |
503 |  |
             /**
504 |  |
              * Adds a new sub node.
505 |  |
              *
506 |  |
              * @param node the node to add
507 |  |
              */
508 |  |
             public void addNode(ConfigurationNode node)
509 |  |
             {
510 | 93527 |
                 if (node == null || node.getName() == null)
511 |  |
                 {
512 | 2 |
                     throw new IllegalArgumentException(
513 |  |
                             "Node to add must have a defined name!");
514 |  |
                 }
515 | 93525 |
                 node.setParentNode(null);  // reset, will later be set
516 |  |
517 | 93525 |
                 if (nodes == null)
518 |  |
                 {
519 | 45317 |
                     nodes = new ArrayList();
520 | 45317 |
                     namedNodes = new HashMap();
521 |  |
                 }
522 |  |
523 | 93525 |
                 nodes.add(node);
524 | 93525 |
                 List lst = (List) namedNodes.get(node.getName());
525 | 93525 |
                 if (lst == null)
526 |  |
                 {
527 | 66461 |
                     lst = new LinkedList();
528 | 66461 |
                     namedNodes.put(node.getName(), lst);
529 |  |
                 }
530 | 93525 |
                 lst.add(node);
531 | 93525 |
             }
532 |  |
533 |  |
             /**
534 |  |
              * Removes a sub node.
535 |  |
              *
536 |  |
              * @param node the node to remove
537 |  |
              * @return a flag if the node could be removed
538 |  |
              */
539 |  |
             public boolean removeNode(ConfigurationNode node)
540 |  |
             {
541 | 10186 |
                 if (nodes != null && node != null && nodes.contains(node))
542 |  |
                 {
543 | 7588 |
                     detachNode(node);
544 | 7588 |
                     nodes.remove(node);
545 |  |
546 | 7588 |
                     List lst = (List) namedNodes.get(node.getName());
547 | 7588 |
                     if (lst != null)
548 |  |
                     {
549 | 7588 |
                         lst.remove(node);
550 | 7588 |
                         if (lst.isEmpty())
551 |  |
                         {
552 | 4939 |
                             namedNodes.remove(node.getName());
553 |  |
                         }
554 |  |
                     }
555 | 7588 |
                     return true;
556 |  |
                 }
557 |  |
558 |  |
                 else
559 |  |
                 {
560 | 2598 |
                     return false;
561 |  |
                 }
562 |  |
             }
563 |  |
564 |  |
             /**
565 |  |
              * Removes all sub nodes with the given name.
566 |  |
              *
567 |  |
              * @param name the name
568 |  |
              * @return a flag if at least on sub node was removed
569 |  |
              */
570 |  |
             public boolean removeNodes(String name)
571 |  |
             {
572 | 16 |
                 if (nodes != null && name != null)
573 |  |
                 {
574 | 9 |
                     List lst = (List) namedNodes.remove(name);
575 | 9 |
                     if (lst != null)
576 |  |
                     {
577 | 7 |
                         detachNodes(lst);
578 | 7 |
                         nodes.removeAll(lst);
579 | 7 |
                         return true;
580 |  |
                     }
581 |  |
                 }
582 | 9 |
                 return false;
583 |  |
             }
584 |  |
585 |  |
             /**
586 |  |
              * Removes all sub nodes.
587 |  |
              */
588 |  |
             public void clear()
589 |  |
             {
590 | 4 |
                 if (nodes != null)
591 |  |
                 {
592 | 3 |
                     detachNodes(nodes);
593 | 3 |
                     nodes = null;
594 | 3 |
                     namedNodes = null;
595 |  |
                 }
596 | 4 |
             }
597 |  |
598 |  |
             /**
599 |  |
              * Returns the node with the given index. If this index cannot be found,
600 |  |
              * an <code>IndexOutOfBoundException</code> exception will be thrown.
601 |  |
              *
602 |  |
              * @param index the index (0-based)
603 |  |
              * @return the sub node at the specified index
604 |  |
              */
605 |  |
             public ConfigurationNode getNode(int index)
606 |  |
             {
607 | 1652 |
                 if (nodes == null)
608 |  |
                 {
609 | 1 |
                     throw new IndexOutOfBoundsException("No sub nodes available!");
610 |  |
                 }
611 | 1651 |
                 return (ConfigurationNode) nodes.get(index);
612 |  |
             }
613 |  |
614 |  |
             /**
615 |  |
              * Returns a list with all stored sub nodes. The return value is never
616 |  |
              * <b>null</b>.
617 |  |
              *
618 |  |
              * @return a list with the sub nodes
619 |  |
              */
620 |  |
             public List getSubNodes()
621 |  |
             {
622 | 40634 |
                 return (nodes == null) ? Collections.EMPTY_LIST : Collections
623 |  |
                         .unmodifiableList(nodes);
624 |  |
             }
625 |  |
626 |  |
             /**
627 |  |
              * Returns a list of the sub nodes with the given name. The return value
628 |  |
              * is never <b>null</b>.
629 |  |
              *
630 |  |
              * @param name the name; if <b>null</b> is passed, all sub nodes will
631 |  |
              * be returned
632 |  |
              * @return all sub nodes with this name
633 |  |
              */
634 |  |
             public List getSubNodes(String name)
635 |  |
             {
636 | 45696 |
                 if (name == null)
637 |  |
                 {
638 | 1 |
                     return getSubNodes();
639 |  |
                 }
640 |  |
641 |  |
                 List result;
642 | 45695 |
                 if (nodes == null)
643 |  |
                 {
644 | 1242 |
                     result = null;
645 |  |
                 }
646 |  |
                 else
647 |  |
                 {
648 | 44453 |
                     result = (List) namedNodes.get(name);
649 |  |
                 }
650 |  |
651 | 45695 |
                 return (result == null) ? Collections.EMPTY_LIST : Collections
652 |  |
                         .unmodifiableList(result);
653 |  |
             }
654 |  |
655 |  |
             /**
656 |  |
              * Let the passed in visitor visit all sub nodes.
657 |  |
              *
658 |  |
              * @param visitor the visitor
659 |  |
              */
660 |  |
             public void visit(ConfigurationNodeVisitor visitor)
661 |  |
             {
662 | 91146 |
                 if (nodes != null)
663 |  |
                 {
664 | 22235 |
                     for (Iterator it = nodes.iterator(); it.hasNext()
665 | 50483 |
                             && !visitor.terminate();)
666 |  |
                     {
667 | 28248 |
                         ((ConfigurationNode) it.next()).visit(visitor);
668 |  |
                     }
669 |  |
                 }
670 | 91146 |
             }
671 |  |
672 |  |
             /**
673 |  |
              * This method is called whenever a sub node is removed from this
674 |  |
              * object. It ensures that the removed node's parent is reset and its
675 |  |
              * <code>removeReference()</code> method gets called.
676 |  |
              *
677 |  |
              * @param subNode the node to be removed
678 |  |
              */
679 |  |
             protected void detachNode(ConfigurationNode subNode)
680 |  |
             {
681 | 7613 |
                 subNode.setParentNode(null);
682 | 7613 |
                 if (subNode instanceof DefaultConfigurationNode)
683 |  |
                 {
684 | 7613 |
                     ((DefaultConfigurationNode) subNode).removeReference();
685 |  |
                 }
686 | 7613 |
             }
687 |  |
688 |  |
             /**
689 |  |
              * Detaches a list of sub nodes. This method calls
690 |  |
              * <code>detachNode()</code> for each node contained in the list.
691 |  |
              *
692 |  |
              * @param subNodes the list with nodes to be detached
693 |  |
              */
694 |  |
             protected void detachNodes(Collection subNodes)
695 |  |
             {
696 | 10 |
                 for (Iterator it = subNodes.iterator(); it.hasNext();)
697 |  |
                 {
698 | 25 |
                     detachNode((ConfigurationNode) it.next());
699 |  |
                 }
700 | 10 |
             }
701 |  |
         }
702 |  |
     }