001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/context/Node.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.portal.context;
037
038 import java.util.ArrayList;
039 import java.util.Collections;
040 import java.util.List;
041
042 /**
043 * encapsulates about a node described/contained by a Web Map Context
044 *
045 * @version $Revision: 18195 $
046 * @author <a href="mailto:vesll@idgis.nl">Linda Vels</a>
047 * @author last edited by: $Author: mschneider $
048 *
049 * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
050 *
051 * @since 2.0
052 */
053 public class Node {
054
055 private int id;
056
057 private String title = null;
058
059 private boolean selectable = false;
060
061 private boolean collapsed = false;
062
063 private Node[] nodes = new Node[0];
064
065 private Node parent = null;
066
067 List<Node[]> tree = new ArrayList<Node[]>( 50 );
068
069 /**
070 * Creates a new ContextNode object.
071 *
072 * @param id
073 * id of the selected node
074 * @param parent
075 * @param title
076 * title of the selected node
077 * @param selectable
078 * @param collapsed
079 * defines if the node is collapsed in the legend viewer
080 * @throws ContextException
081 */
082 public Node( int id, Node parent, String title, boolean selectable, boolean collapsed ) throws ContextException {
083 setId( id );
084 setParent( parent );
085 setTitle( title );
086 setCollapsed( collapsed );
087 setSelectable( selectable );
088 }
089
090 /**
091 * The childnodes of the selected node in the tree
092 *
093 * @return all nodes
094 */
095 public Node[] getNodes() {
096 return nodes;
097 }
098
099 /**
100 * Returns a childnode of the selected node by id
101 *
102 * @param nodeId
103 * to retrieve
104 *
105 * @return node by id or <code>null</code> if not found
106 */
107 public Node getNode( int nodeId ) {
108 Node node = null;
109 for ( int i = 0; i < nodes.length; i++ ) {
110 node = nodes[i].getNode( nodeId );
111 if ( node != null ) {
112 return node;
113 }
114 if ( nodes[i].getId() == nodeId ) {
115 return nodes[i];
116 }
117 }
118 return node;
119 }
120
121 /**
122 *
123 * @param nodeId
124 * @param nodes
125 * @return node by id from a list
126 */
127 public Node getNode( int nodeId, Node[] nodes ) {
128 Node node = null;
129 for ( int i = 0; i < nodes.length; i++ ) {
130 node = nodes[i].getNode( nodeId, nodes[i].getNodes() );
131 if ( node != null ) {
132 return node;
133 }
134 if ( nodes[i].getId() == nodeId ) {
135 return nodes[i];
136 }
137
138 }
139 return node;
140 }
141
142 /**
143 * return the maximum id of all nodes
144 *
145 * @return maximum id of all nodes
146 */
147 public int getMaxNodeId() {
148 int maxNodeId = id;
149 for ( int i = 0; i < nodes.length; i++ ) {
150 Node[] brancheNodes = nodes[i].getNodes();
151 if ( nodes[i].getId() > maxNodeId ) {
152 maxNodeId = nodes[i].getId();
153
154 }
155 maxNodeId = getMaxId( brancheNodes, maxNodeId );
156 }
157 return maxNodeId;
158 }
159
160 /**
161 *
162 * @param nodes
163 * @param maxNodeId
164 * @return maximum id
165 */
166 private int getMaxId( Node[] nodes, int maxNodeId ) {
167 for ( int i = 0; i < nodes.length; i++ ) {
168 Node[] brancheNodes = nodes[i].getNodes();
169 if ( nodes[i].getId() > maxNodeId ) {
170 maxNodeId = nodes[i].getId();
171
172 }
173 maxNodeId = getMaxId( brancheNodes, maxNodeId );
174 }
175 return maxNodeId;
176 }
177
178 /**
179 *
180 * @param parent
181 */
182 public void setParent( Node parent ) {
183 this.parent = parent;
184 }
185
186 /**
187 *
188 * @return parent node
189 */
190 public Node getParent() {
191 return parent;
192 }
193
194 /**
195 * The id of the selected node.
196 *
197 * @return id
198 */
199 public int getId() {
200 return id;
201 }
202
203 /**
204 * The title of the selected node.
205 *
206 * @return title
207 */
208 public String getTitle() {
209 return title;
210 }
211
212 /**
213 * The status of the node (collapsed or not (expanded)).
214 *
215 * @return true if node is collapsed
216 */
217 public boolean isCollapsed() {
218 return collapsed;
219 }
220
221 /**
222 * The selectable status of the node.
223 *
224 * @return true if node is selectable
225 */
226 public boolean isSelectable() {
227 return selectable;
228 }
229
230 /**
231 * @param nodes
232 */
233 public void setNodes( Node[] nodes ) {
234 if ( nodes == null ) {
235 nodes = new Node[0];
236 }
237 this.nodes = nodes;
238 }
239
240 /**
241 * @param selectable
242 */
243 public void setSelectable( boolean selectable ) {
244 this.selectable = selectable;
245 }
246
247 /**
248 * @param collapsed
249 */
250 public void setCollapsed( boolean collapsed ) {
251 this.collapsed = collapsed;
252 }
253
254 /**
255 * @param id
256 */
257 public void setId( int id ) {
258 this.id = id;
259 }
260
261 /**
262 *
263 * @param title
264 *
265 * @throws ContextException
266 */
267 public void setTitle( String title )
268 throws ContextException {
269 if ( title == null ) {
270 throw new ContextException( "title isn't allowed to be null" );
271 }
272 this.title = title;
273 }
274
275 /**
276 *
277 * @return flat tree as node matrix
278 */
279 public Node[][] getFlatTree() {
280 tree = new ArrayList<Node[]>();
281 tree = getBranches( nodes );
282 Node[][] flatTree = new Node[tree.size()][];
283 return tree.toArray( flatTree );
284 }
285
286 /**
287 *
288 * @param nodes
289 * @return tree branches
290 */
291 private List<Node[]> getBranches( Node[] nodes ) {
292 for ( int i = 0; i < nodes.length; i++ ) {
293 Node[] branchNodes = nodes[i].getNodes();
294 if ( branchNodes.length == 0 ) {
295 List<Node> treeRowList = new ArrayList<Node>( 50 );
296 Node tmpNode = nodes[i];
297 while ( tmpNode != null ) {
298 treeRowList.add( tmpNode );
299 tmpNode = tmpNode.getParent();
300 }
301 Collections.reverse( treeRowList );
302 Node[] treeRow = new Node[treeRowList.size()];
303 tree.add( treeRowList.toArray( treeRow ) );
304 } else {
305 getBranches( branchNodes );
306 }
307 }
308 return tree;
309
310 }
311
312 /**
313 * moves a node within the tree up or down
314 *
315 * @param nodeId
316 * @param up
317 */
318 public void moveNode( int nodeId, Boolean up ) {
319
320 for ( int i = 0; i < nodes.length; i++ ) {
321 if ( nodes[i].getId() == nodeId ) {
322 Node source = null;
323 Node target = null;
324 if ( up ) {
325 source = nodes[i];
326 target = nodes[i - 1];
327 nodes[i] = target;
328 nodes[i - 1] = source;
329 return;
330 }
331 source = nodes[i];
332 target = nodes[i + 1];
333 nodes[i] = target;
334 nodes[i + 1] = source;
335 return;
336
337 }
338 nodes[i].moveNode( nodeId, up );
339 }
340
341 }
342
343 /**
344 * adds a new child node to the node
345 *
346 * @param childNode
347 */
348 public void appendNode( Node childNode ) {
349 Node[] newNodes = new Node[nodes.length + 1];
350 System.arraycopy( nodes, 0, newNodes, 0, nodes.length );
351 newNodes[nodes.length] = childNode;
352 nodes = newNodes;
353 }
354
355 /**
356 * insert a new child node at given position
357 *
358 * @param childNode
359 * the new child node
360 * @param index
361 * the position of the new child node (0=first node)
362 * @throws IndexOutOfBoundsException
363 */
364 public void insertNode( Node childNode, int index ) {
365 if ( index > nodes.length ) {
366 throw new IndexOutOfBoundsException();
367 }
368 Node[] newNodes = new Node[nodes.length + 1];
369 System.arraycopy( nodes, 0, newNodes, 0, index );
370 newNodes[index] = childNode;
371 System.arraycopy( nodes, index, newNodes, index + 1, nodes.length - index );
372 nodes = newNodes;
373 }
374
375 /**
376 * removes a node
377 *
378 * @param nodeID
379 * the id of the node
380 * @return true if node is removed
381 */
382 public boolean removeNode( int nodeID ) {
383 boolean removed = false;
384
385 for ( int i = 0; i < nodes.length; i++ ) {
386 if ( nodes[i].id == nodeID ) {
387 Node[] tmpNodes = new Node[nodes.length - 1];
388 System.arraycopy( nodes, 0, tmpNodes, 0, i );
389 System.arraycopy( nodes, i + 1, tmpNodes, i, tmpNodes.length - i );
390 nodes = tmpNodes;
391 removed = true;
392 break;
393 }
394 // try to find and remove in child node
395 if ( nodes[i].removeNode( nodeID ) ) {
396 removed = true;
397 break;
398 }
399 }
400 return removed;
401 }
402
403 /**
404 * returns the index of the child node
405 *
406 * @param nodeID
407 * the node id to look for
408 * @return index of the child node, -1 if node is not found
409 */
410 public int getIndex( int nodeID ) {
411 for ( int i = 0; i < nodes.length; i++ ) {
412 if ( nodes[i].id == nodeID ) {
413 return i;
414 }
415 }
416 return -1;
417 }
418
419 }