001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/context/LayerList.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.LinkedList;
040    import java.util.List;
041    
042    /**
043     *
044     *
045     *
046     * @version $Revision: 18195 $
047     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
048     * @author last edited by: $Author: mschneider $
049     *
050     * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
051     *
052     * @since 2.0
053     */
054    public class LayerList {
055    
056        private List<Layer> list = new ArrayList<Layer>( 50 );
057    
058        private List<Layer> treeList = new ArrayList<Layer>( 50 );
059    
060        /**
061         * Creates a new LayerList object.
062         *
063         * @param layers
064         */
065        public LayerList( Layer[] layers ) {
066            setLayers( layers );
067        }
068    
069        /**
070         * returns a layer identifies by its name
071         *
072         * @param name
073         *            name ofthe layer
074         *
075         * @return names layer
076         * @deprecated use
077         * @see #getLayer(String, String) instead
078         */
079        @Deprecated
080        public Layer getLayer( String name ) {
081            for ( Layer layer : list ) {
082                if ( layer.getName().equals( name ) ) {
083                    return layer;
084                }
085            }
086            return null;
087        }
088    
089        /**
090         * returns a layer identifies by its name and service address
091         *
092         * @param name
093         *            name ofthe layer
094         * @param serverAddress
095         *            address of the server which servers the layer
096         *
097         * @return named layer
098         */
099        public Layer getLayer( String name, String serverAddress ) {
100    
101            if ( serverAddress != null ) {
102                for ( Layer layer : list ) {
103                    String s = layer.getServer().getOnlineResource().toExternalForm();
104                    if ( layer.getName().equals( name ) && s.equals( serverAddress ) ) {
105                        return layer;
106                    }
107                }
108            } else {
109                for ( Layer layer : list ) {
110                    if ( layer.getName().equals( name ) ) {
111                        return layer;
112                    }
113                }
114            }
115            return null;
116        }
117    
118        /**
119         * returns all layers of the web map context
120         *
121         * @return array of layers
122         */
123        public Layer[] getLayers() {
124            Layer[] cl = new Layer[list.size()];
125            return list.toArray( cl );
126        }
127    
128        /**
129         * sets all layers of the web map context
130         *
131         * @param layers
132         */
133        public void setLayers( Layer[] layers ) {
134            this.list.clear();
135    
136            if ( layers != null ) {
137                for ( int i = 0; i < layers.length; i++ ) {
138                    list.add( layers[i] );
139                }
140            }
141        }
142    
143        /**
144         * @param id
145         *
146         * @return the layers of a node of the tree of the web map context
147         */
148        public Layer[] getLayersByNodeId( int id ) {
149            List<Layer> nodeLayerList = new ArrayList<Layer>( list.size() );
150            int parentNodeId;
151            for ( int k = 0; k < list.size(); k++ ) {
152                parentNodeId = ( list.get( k ) ).getExtension().getParentNodeId();
153                if ( parentNodeId == id ) {
154                    nodeLayerList.add( list.get( k ) );
155                }
156            }
157            Layer[] nodeLayers = new Layer[nodeLayerList.size()];
158            return nodeLayerList.toArray( nodeLayers );
159        }
160    
161        /**
162         * TODO: review this changed; it has been introduced as of TreeLayerView Portlet
163         *
164         * @param root
165         */
166        public void orderLayerListByLayerTree( Node root ) {
167            treeList.clear();
168            Node[] rootNode = new Node[1];
169            rootNode[0] = root;
170            treeList = getLayerListByNode( rootNode );
171            setLayers( treeList.toArray( new Layer[treeList.size()] ) );
172        }
173    
174        /**
175         *
176         * @param nodes
177         * @return list of layers
178         */
179        private List<Layer> getLayerListByNode( Node[] nodes ) {
180            for ( int i = 0; i < nodes.length; i++ ) {
181                getLayerListByNode( nodes[i].getNodes() );
182                Layer[] nl = getLayersByNodeId( nodes[i].getId() );
183                for ( int j = 0; j < nl.length; j++ ) {
184                    treeList.add( nl[j] );
185                }
186    
187            }
188            return treeList;
189        }
190    
191        /**
192         * adds one layer to the the web map context. If a layer with the same name as the passed layer already exits it
193         * will be overwritten
194         *
195         * @param layer
196         */
197        public void addLayer( Layer layer ) {
198            list.add( layer );
199        }
200    
201        /**
202         * adds one layer to the top of the web map context. If a layer with the same name as the passed layer already exits
203         * it will be overwritten
204         *
205         * @param layer
206         */
207        public void addLayerToTop( Layer layer ) {
208            list.add( 0, layer );
209        }
210    
211        /**
212         * removes a layer identified by its name from the web map context
213         *
214         * @param name
215         *            name of the layer to be removed
216         *
217         * @return removed layer
218         * @deprecated use #removeLayer(String, String) instead
219         */
220        @Deprecated
221        public Layer removeLayer( String name ) {
222            Layer layer = getLayer( name );
223            list.remove( layer );
224            return layer;
225        }
226    
227        /**
228         * removes a layer identified by its name from the web map context
229         *
230         * @param name
231         *            name of the layer to be removed
232         * @param serverAddress
233         *
234         * @return removed layer
235         */
236        public Layer removeLayer( String name, String serverAddress ) {
237            Layer layer = getLayer( name, serverAddress );
238            list.remove( layer );
239            return layer;
240        }
241    
242        /**
243         * moves a layer within the layer list up or down
244         *
245         * @param layer
246         *            layer to be moved
247         * @param up
248         *            if true the layer will be moved up otherwise it will be moved down
249         */
250        public void move( Layer layer, boolean up ) {
251            int i = 0;
252            Layer target = null;
253            while ( i < list.size() && target == null ) {
254                Layer tmp = list.get( i );
255                if ( tmp.getName().equals( layer.getName() )
256                     && tmp.getServer().getOnlineResource().equals( layer.getServer().getOnlineResource() ) ) {
257                    target = tmp;
258                }
259                i++;
260            }
261            i--;
262            if ( i > 0 && up ) {
263                Layer o = list.get( i );
264                list.set( i, list.get( i - 1 ) );
265                list.set( i - 1, o );
266            } else if ( i < list.size() - 1 && !up ) {
267                Layer o = list.get( i );
268                list.set( i, list.get( i + 1 ) );
269                list.set( i + 1, o );
270            }
271        }
272    
273        /**
274         * moves a layer within the layer list before the beforeLayer
275         *
276         * @param layer
277         *            layer to be moved
278         * @param beforeLayer
279         *            put the layer before this beforeLayer. If beforeLayer is <code>null</code> move to bottom.
280         *
281         */
282        public void move( Layer layer, Layer beforeLayer ) {
283            if ( beforeLayer != null ) { // move layer before beforeLayer
284                int i = 0;
285                ArrayList<Layer> newList = new ArrayList<Layer>( list.size() );
286    
287                while ( i < list.size() ) {
288                    Layer tmp = list.get( i );
289                    if ( tmp.getName().equals( beforeLayer.getName() )
290                         && tmp.getServer().getOnlineResource().equals( beforeLayer.getServer().getOnlineResource() ) ) {
291                        newList.add( layer );
292                        newList.add( beforeLayer );
293                    } else if ( tmp.getName().equals( layer.getName() )
294                                && tmp.getServer().getOnlineResource().equals( layer.getServer().getOnlineResource() ) ) {
295                        // do nothing
296                    } else {
297                        newList.add( tmp );
298                    }
299                    i++;
300                }
301                list = newList;
302            } else { // move to end...
303                // removeLayer( layer.getName(), layer.getServer().getOnlineResource().toString() );
304                // addLayer( layer );
305                // ...but not at the end of the list! some utils need the list ordered
306                // by the parent node IDs.
307                int parentNodeID = layer.getExtension().getParentNodeId();
308                removeLayer( layer.getName(), layer.getServer().getOnlineResource().toString() );
309                boolean inParentNode = false;
310                boolean inserted = false;
311                List<Layer> newList = new LinkedList<Layer>();
312                int i = 0;
313                while ( i < list.size() ) {
314                    Layer tmp = list.get( i );
315                    if ( tmp.getExtension().getParentNodeId() == parentNodeID ) {
316                        inParentNode = true;
317                    } else if ( inParentNode ) { // end of parentNode, point to insert layer
318                        newList.add( layer );
319                        inParentNode = false;
320                        inserted = true;
321                    }
322                    newList.add( tmp );
323                    i++;
324                }
325    
326                if ( !inserted ) {
327                    newList.add( layer );
328                }
329                list = newList;
330            }
331        }
332    
333        /**
334         * move all layers with parent <code>nodeID</code> befor the layers with parent <code>beforeNodeID</code>.
335         *
336         * @param nodeID
337         * @param beforeNodeID
338         */
339        public void moveNodes( int nodeID, int beforeNodeID ) {
340            List<Layer> result = new LinkedList<Layer>();
341            List<Layer> tmpNodeLayers = new LinkedList<Layer>();
342            boolean nodeLayersInserted = false;
343    
344            // collect all affected nodes
345            for ( Layer layer : list ) {
346                if ( layer.getExtension().getParentNodeId() == nodeID ) {
347                    tmpNodeLayers.add( layer );
348                }
349            }
350    
351            for ( Layer layer : list ) {
352                if ( layer.getExtension().getParentNodeId() == nodeID ) {
353                    // don't insert
354                } else {
355                    // insert before beforeNodeID
356                    if ( !nodeLayersInserted && layer.getExtension().getParentNodeId() == beforeNodeID ) {
357                        result.addAll( tmpNodeLayers );
358                        nodeLayersInserted = true;
359                    }
360                    // add all other nodes
361                    result.add( layer );
362                }
363            }
364            // if not inserted put at the end (eg. beforeNodeID not found)
365            if ( !nodeLayersInserted ) {
366                result.addAll( tmpNodeLayers );
367            }
368            list = result;
369        }
370    
371        /**
372         * removes all layers from the web map context
373         */
374        public void clear() {
375            list.clear();
376        }
377    
378        /**
379         * remove all layer with <code>nodeID</code> as parent node
380         *
381         * @param nodeID
382         */
383        public void removeLayers( int nodeID ) {
384            List<Layer> result = new LinkedList<Layer>();
385            for ( Layer layer : list ) {
386                if ( layer.getExtension().getParentNodeId() != nodeID ) {
387                    result.add( layer );
388                }
389            }
390            list = result;
391        }
392    
393    }