5c04aee3864708bfbeed5c311950b4043f9117ba
[jSite2.git] / src / net / pterodactylus / util / data / NodeImpl.java
1
2 package net.pterodactylus.util.data;
3
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7
8 /**
9  * Implementation of the {@link Node} interface.
10  * 
11  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
12  * @param <E>
13  *            The type of the element to store
14  */
15 class NodeImpl<E> implements Node<E> {
16
17         /** The parent node of this node. */
18         private final Node<E> parentNode;
19
20         /** The element contained in this node. */
21         private final E element;
22
23         /** The child nodes of this node. */
24         private final List<Node<E>> children = new ArrayList<Node<E>>();
25
26         /**
27          * Creates a new root node.
28          */
29         NodeImpl() {
30                 this.parentNode = null;
31                 this.element = null;
32         }
33
34         /**
35          * Creates a new node with the given parent and element.
36          * 
37          * @param parentNode
38          *            The parent of this node
39          * @param element
40          *            The element of this node
41          */
42         NodeImpl(Node<E> parentNode, E element) {
43                 if ((parentNode == null) || (element == null)) {
44                         throw new NullPointerException("null is not allowed as parent or element");
45                 }
46                 this.parentNode = parentNode;
47                 this.element = element;
48         }
49
50         /**
51          * {@inheritDoc}
52          */
53         public Node<E> getParent() {
54                 return parentNode;
55         }
56
57         /**
58          * {@inheritDoc}
59          */
60         public E getElement() {
61                 return element;
62         }
63
64         /**
65          * {@inheritDoc}
66          */
67         public Node<E> addChild(E child) {
68                 Node<E> childNode = new NodeImpl<E>(this, child);
69                 children.add(childNode);
70                 return childNode;
71         }
72
73         /**
74          * {@inheritDoc}
75          */
76         public int size() {
77                 return children.size();
78         }
79
80         /**
81          * {@inheritDoc}
82          */
83         public Node<E> getChild(int childIndex) {
84                 return children.get(childIndex);
85         }
86
87         /**
88          * {@inheritDoc}
89          */
90         public boolean hasChild(Node<E> childNode) {
91                 return children.contains(childNode);
92         }
93
94         /**
95          * {@inheritDoc}
96          */
97         public boolean hasChild(E element) {
98                 for (Node<E> childNode: children) {
99                         if (childNode.getElement().equals(element)) {
100                                 return true;
101                         }
102                 }
103                 return false;
104         }
105
106         /**
107          * {@inheritDoc}
108          */
109         public int getIndexOfChild(Node<E> childNode) {
110                 int childIndex = 0;
111                 for (Node<E> node: children) {
112                         if (node.equals(childNode)) {
113                                 return childIndex;
114                         }
115                         childIndex++;
116                 }
117                 return -1;
118         }
119
120         /**
121          * {@inheritDoc}
122          */
123         public int getIndexOfChild(E element) {
124                 int childIndex = 0;
125                 for (Node<E> node: children) {
126                         if (node.getElement().equals(element)) {
127                                 return childIndex;
128                         }
129                         childIndex++;
130                 }
131                 return -1;
132         }
133
134         /**
135          * {@inheritDoc}
136          */
137         public void removeChild(Node<E> childNode) {
138                 children.remove(childNode);
139         }
140
141         /**
142          * {@inheritDoc}
143          */
144         public void removeChild(E child) {
145                 for (Node<E> childNode: children) {
146                         if (child.equals(childNode.getElement())) {
147                                 children.remove(childNode);
148                                 break;
149                         }
150                 }
151         }
152
153         /**
154          * {@inheritDoc}
155          */
156         public void removeChild(int childIndex) {
157                 children.remove(childIndex);
158         }
159
160         /**
161          * {@inheritDoc}
162          */
163         public void removeAllChildren() {
164                 children.clear();
165         }
166
167         /**
168          * {@inheritDoc}
169          */
170         public Iterator<Node<E>> iterator() {
171                 return children.iterator();
172         }
173
174         /**
175          * {@inheritDoc}
176          */
177         public Node<E> findChild(E element) {
178                 for (Node<E> childNode: children) {
179                         Node<E> wantedNode = childNode.findChild(element);
180                         if (wantedNode != null) {
181                                 return wantedNode;
182                         }
183                 }
184                 if (this.element.equals(element)) {
185                         return this;
186                 }
187                 return null;
188         }
189
190 }