1 package org.apache.onami.configuration.variables;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25
26
27
28
29
30 final class Tree<T>
31 {
32
33
34 private T data;
35
36
37 private Tree<T> parent = null;
38
39
40 private List<Tree<T>> children = new ArrayList<Tree<T>>();
41
42
43
44
45
46
47 public Tree( T data )
48 {
49 this.data = data;
50 }
51
52
53
54
55 public boolean isRoot()
56 {
57 return parent == null;
58 }
59
60
61
62
63 public boolean isLeaf()
64 {
65 return children.isEmpty();
66 }
67
68
69
70
71
72
73
74 public Tree<T> addLeaf( T child )
75 {
76 Tree<T> leaf = new Tree<T>( child );
77 leaf.parent = this;
78 children.add( leaf );
79 return leaf;
80 }
81
82
83
84
85 public Tree<T> getParent()
86 {
87 return parent;
88 }
89
90
91
92
93 public void removeFromParent()
94 {
95 if ( !isRoot() )
96 {
97 getParent().removeSubtree( this );
98 }
99 }
100
101
102
103
104
105
106 public void removeSubtree( Tree<T> subtree )
107 {
108 if ( children.remove( subtree ) )
109 {
110 subtree.parent = null;
111 }
112 }
113
114
115
116
117 public T getData()
118 {
119 return data;
120 }
121
122
123
124
125
126 public int getDepth()
127 {
128 int depth = 0;
129 Tree<T> curr = parent;
130 while ( curr != null )
131 {
132 curr = curr.parent;
133 depth++;
134 }
135 return depth;
136 }
137
138
139
140
141 public List<Tree<T>> getChildren()
142 {
143 return children;
144 }
145
146
147
148
149
150
151
152 public Tree<T> addSubtree( Tree<T> subtree )
153 {
154 Tree<T> copy = addLeaf( subtree.data );
155 copy.children = new ArrayList<Tree<T>>( subtree.children );
156 return copy;
157 }
158
159
160
161
162
163 public boolean inSubtrees( T element )
164 {
165 for ( Tree<T> child : getChildren() )
166 {
167 if ( child.isElement( element ) || child.inSubtrees( element ) )
168 {
169 return true;
170 }
171 }
172 return false;
173 }
174
175
176
177
178
179 public boolean isElement( T element )
180 {
181 return ( data.equals( element ) );
182 }
183
184
185
186
187
188
189 public boolean inAncestors( T element )
190 {
191 if ( !isRoot() )
192 {
193 return getParent().isElement( element ) || getParent().inAncestors( element );
194 }
195 return false;
196 }
197
198
199
200
201 public Tree<T> getRoot()
202 {
203 if ( isRoot() )
204 {
205 return this;
206 }
207 return getParent().getRoot();
208 }
209
210 @Override
211 public String toString()
212 {
213 StringBuilder buffer = new StringBuilder();
214 toString( buffer, 0 );
215 return buffer.toString();
216 }
217
218 private void toString( StringBuilder buffer, int level )
219 {
220
221
222 StringBuilder indent = new StringBuilder();
223 Tree<T> prev;
224 Tree<T> curr = this;
225 for ( int i = level - 1; i >= 0; i-- )
226 {
227 prev = curr;
228 curr = prev.parent;
229 if ( i == level - 1 )
230 {
231 indent.append( " _|" );
232 }
233 else
234 {
235 indent.append( " " );
236
237 if ( i < level && curr.children.indexOf( prev ) < curr.children.size() - 1 )
238 {
239 indent.append( "|" );
240 }
241 else
242 {
243 indent.append( " " );
244 }
245 }
246 }
247 buffer.append( indent.reverse() );
248
249
250 buffer.append( getData() ).append( "\n" );
251
252
253 for ( Tree<T> child : getChildren() )
254 {
255 child.toString( buffer, level + 1 );
256 }
257 }
258
259 }