001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }