001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/context/WebMapContextFactory.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.awt.Rectangle;
039    import java.io.File;
040    import java.io.IOException;
041    import java.io.InputStreamReader;
042    import java.io.Reader;
043    import java.net.MalformedURLException;
044    import java.net.URL;
045    import java.util.HashMap;
046    import java.util.Map;
047    
048    import org.apache.commons.httpclient.HttpClient;
049    import org.apache.commons.httpclient.methods.GetMethod;
050    import org.deegree.datatypes.QualifiedName;
051    import org.deegree.enterprise.WebUtils;
052    import org.deegree.framework.log.ILogger;
053    import org.deegree.framework.log.LoggerFactory;
054    import org.deegree.framework.util.HttpUtils;
055    import org.deegree.framework.util.Parameter;
056    import org.deegree.framework.util.ParameterList;
057    import org.deegree.framework.util.StringTools;
058    import org.deegree.framework.xml.ElementList;
059    import org.deegree.framework.xml.NamespaceContext;
060    import org.deegree.framework.xml.XMLFragment;
061    import org.deegree.framework.xml.XMLParsingException;
062    import org.deegree.framework.xml.XMLTools;
063    import org.deegree.graphics.sld.FeatureTypeStyle;
064    import org.deegree.graphics.sld.SLDFactory;
065    import org.deegree.graphics.sld.StyledLayerDescriptor;
066    import org.deegree.model.crs.CRSFactory;
067    import org.deegree.model.crs.CoordinateSystem;
068    import org.deegree.model.crs.UnknownCRSException;
069    import org.deegree.model.metadata.iso19115.Address;
070    import org.deegree.model.metadata.iso19115.CitedResponsibleParty;
071    import org.deegree.model.metadata.iso19115.ContactInfo;
072    import org.deegree.model.metadata.iso19115.Phone;
073    import org.deegree.model.metadata.iso19115.RoleCode;
074    import org.deegree.model.spatialschema.GeometryFactory;
075    import org.deegree.model.spatialschema.Point;
076    import org.deegree.ogcbase.BaseURL;
077    import org.deegree.ogcbase.CommonNamespaces;
078    import org.deegree.ogcbase.ImageURL;
079    import org.deegree.ogcwebservices.OWSUtils;
080    import org.deegree.ogcwebservices.getcapabilities.MetadataURL;
081    import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
082    import org.deegree.ogcwebservices.getcapabilities.OGCCapabilitiesDocument;
083    import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilities;
084    import org.deegree.ogcwebservices.wcs.getcapabilities.WCSCapabilitiesDocument;
085    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilities;
086    import org.deegree.ogcwebservices.wfs.capabilities.WFSCapabilitiesDocument;
087    import org.deegree.ogcwebservices.wms.capabilities.LegendURL;
088    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilities;
089    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocument;
090    import org.deegree.ogcwebservices.wms.capabilities.WMSCapabilitiesDocumentFactory;
091    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
092    import org.deegree.owscommon_new.HTTP;
093    import org.deegree.owscommon_new.Operation;
094    import org.deegree.owscommon_new.OperationsMetadata;
095    import org.deegree.security.drm.model.User;
096    import org.w3c.dom.Element;
097    import org.w3c.dom.Text;
098    import org.xml.sax.SAXException;
099    
100    /**
101     * Factory class for creating an instance of a web map Context (<tt>ViewContext</tt>). The factory is able to parse
102     * deegree specific extensions (General and Layer) as well as standard web map context documents.
103     * 
104     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
105     * @author last edited by: $Author: jmays $
106     * 
107     * @version $Revision: 23790 $, $Date: 2010-04-23 14:22:04 +0200 (Fr, 23 Apr 2010) $
108     */
109    public class WebMapContextFactory {
110    
111        private static final ILogger LOG = LoggerFactory.getLogger( WebMapContextFactory.class );
112    
113        /**
114         * Caching the wms capabilities. Key is the wms address (URL), value is the WMSCapabilities.
115         */
116        private static Map<URL, WMSCapabilities> wmsCache = new HashMap<URL, WMSCapabilities>();
117    
118        private static Map<URL, WFSCapabilities> wfsCache = new HashMap<URL, WFSCapabilities>();
119    
120        private static Map<URL, WCSCapabilities> wcsCache = new HashMap<URL, WCSCapabilities>();
121    
122        /**
123         * creates an instance of a ViewContext from the web map context document read from the passed URL
124         * 
125         * @param url
126         * @param user
127         * @param sessionID
128         * @return new ViewContext for web map context document from <code>url</code>
129         * @throws IOException
130         * @throws XMLParsingException
131         * @throws ContextException
132         * @throws SAXException
133         * @throws UnknownCRSException
134         */
135        public synchronized static ViewContext createViewContext( URL url, User user, String sessionID )
136                                throws IOException, XMLParsingException, ContextException, SAXException,
137                                UnknownCRSException {
138            // cache have to be cleared because contained capabilities may has been
139            // requested with other user identification
140            wmsCache.clear();
141    
142            XMLFragment xml = new XMLFragment( url );
143    
144            return createViewContext( xml, user, sessionID );
145        }
146    
147        /**
148         * @param xml
149         * @param user
150         * @param sessionID
151         * @return new ViewContext for web map context document from <code>xml</code>
152         * @throws IOException
153         * @throws XMLParsingException
154         * @throws ContextException
155         * @throws UnknownCRSException
156         */
157        public synchronized static ViewContext createViewContext( XMLFragment xml, User user, String sessionID )
158                                throws IOException, XMLParsingException, ContextException, UnknownCRSException {
159            // general section
160            Element element = XMLTools.getRequiredChildElement( "General", CommonNamespaces.CNTXTNS, xml.getRootElement() );
161            General general = createGeneral( element, xml );
162    
163            // Layer (List) section
164            element = XMLTools.getRequiredChildElement( "LayerList", CommonNamespaces.CNTXTNS, xml.getRootElement() );
165    
166            final LayerList layerList = createLayerList( element, user, sessionID );
167    
168            GeneralExtension ge = general.getExtension();
169            MapModel mapModel = ge.getMapModel();
170            if ( mapModel != null ) {
171                // WMC layers assigned to MapModel layers just can be set after WMC layer
172                // list has been parsed
173                try {
174                    mapModel.walkLayerTree( new MapModelVisitor() {
175    
176                        public void visit( LayerGroup layerGroup )
177                                                throws Exception {
178                        }
179    
180                        public void visit( MMLayer layer )
181                                                throws Exception {
182                            Layer[] layers = layerList.getLayers();
183                            for ( Layer layer2 : layers ) {
184                                if ( layer.getIdentifier().equals( layer2.getExtension().getIdentifier() ) ) {
185                                    layer.setLayer( layer2 );
186                                    break;
187                                }
188                            }
189                        }
190                    } );
191                } catch ( Exception e ) {
192                    e.printStackTrace();
193                }
194            }
195    
196            ViewContext vc = new ViewContext( general, layerList );
197    
198            return vc;
199        }
200    
201        /**
202         * creates an instance of a class encapsulating the general context informations
203         * 
204         * @param element
205         *            <General>
206         * @param xml
207         * 
208         * @return instance of <tt>General</tt>
209         * 
210         * @throws XMLParsingException
211         * @throws UnknownCRSException
212         */
213        private static General createGeneral( Element element, XMLFragment xml )
214                                throws XMLParsingException, MalformedURLException, UnknownCRSException {
215    
216            // <Window>
217            Element elem = XMLTools.getChildElement( "Window", CommonNamespaces.CNTXTNS, element );
218            Rectangle rect = createWindow( elem );
219    
220            // <BoundingBox>
221            elem = XMLTools.getRequiredChildElement( "BoundingBox", CommonNamespaces.CNTXTNS, element );
222            Point[] bbox = createBoundingBox( elem );
223    
224            // <Title>
225            String title = XMLTools.getRequiredStringValue( "Title", CommonNamespaces.CNTXTNS, element );
226    
227            // <KeywordList>
228            elem = XMLTools.getChildElement( "KeywordList", CommonNamespaces.CNTXTNS, element );
229            String[] keywords = createKeywords( elem );
230    
231            // <Abstract>
232            String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.CNTXTNS, element, null );
233    
234            // <LogoURL>
235            elem = XMLTools.getChildElement( "LogoURL", CommonNamespaces.CNTXTNS, element );
236            ImageURL logoURL = createImageURL( elem );
237    
238            // <DescriptionURL>
239    
240            // elem = XMLTools.getChildElement( "DescriptionURL", CommonNamespaces.CNTXTNS, element );
241            elem = XMLTools.getRequiredElement( element, CommonNamespaces.CNTXT_PREFIX + ":DescriptionURL",
242                                                CommonNamespaces.getNamespaceContext() );
243    
244            BaseURL descriptionURL = createBaseURL( elem );
245    
246            // <ContactInformation>
247            elem = XMLTools.getChildElement( "ContactInformation", CommonNamespaces.CNTXTNS, element );
248            CitedResponsibleParty contact = createContactInformation( elem );
249    
250            // <Extension>
251            elem = XMLTools.getChildElement( "Extension", CommonNamespaces.CNTXTNS, element );
252            GeneralExtension extension = createGeneralExtension( elem, xml );
253    
254            General general = null;
255            try {
256                general = new General( title, abstract_, rect, contact, bbox, descriptionURL, logoURL, keywords, extension );
257            } catch ( Exception e ) {
258                throw new XMLParsingException( e.getMessage(), e );
259            }
260    
261            return general;
262        }
263    
264        /**
265         * creates a <tt>Rectangle<tt> (Window) instance from the passed Element.
266         * 
267         * @param element
268         *            <Window>
269         * 
270         * @return instance of <tt>Rectangle</tt>
271         * 
272         * @throws XMLParsingException
273         */
274        private static Rectangle createWindow( Element element )
275                                throws XMLParsingException {
276    
277            Rectangle rect = null;
278    
279            if ( element != null ) {
280                String tmp = XMLTools.getRequiredAttrValue( "width", null, element );
281                int width = Integer.parseInt( tmp );
282                tmp = XMLTools.getRequiredAttrValue( "height", null, element );
283    
284                int height = Integer.parseInt( tmp );
285                rect = new Rectangle( width, height );
286            }
287    
288            return rect;
289        }
290    
291        /**
292         * creates a <tt>Envelope </tt> from the passed Element
293         * 
294         * @param element
295         *            <BoundingBox>
296         * 
297         * @return instance of <tt>Envelope</tt>
298         * 
299         * @throws XMLParsingException
300         * @throws UnknownCRSException
301         */
302        private static Point[] createBoundingBox( Element element )
303                                throws XMLParsingException, UnknownCRSException {
304    
305            String srs = XMLTools.getRequiredAttrValue( "SRS", null, element );
306            CoordinateSystem crs = CRSFactory.create( srs );
307            String tmp = XMLTools.getRequiredAttrValue( "minx", null, element );
308            double minx = Double.parseDouble( tmp );
309            tmp = XMLTools.getRequiredAttrValue( "miny", null, element );
310    
311            double miny = Double.parseDouble( tmp );
312            tmp = XMLTools.getRequiredAttrValue( "maxx", null, element );
313    
314            double maxx = Double.parseDouble( tmp );
315            tmp = XMLTools.getRequiredAttrValue( "maxy", null, element );
316    
317            double maxy = Double.parseDouble( tmp );
318    
319            Point[] points = new Point[2];
320            points[0] = GeometryFactory.createPoint( minx, miny, crs );
321            points[1] = GeometryFactory.createPoint( maxx, maxy, crs );
322    
323            return points;
324        }
325    
326        /**
327         * creates an array of keywords (String) from the passed Keyword list
328         * 
329         * @param element
330         *            <KeywordList>
331         * 
332         * @return array of Strings
333         * 
334         */
335        private static String[] createKeywords( Element element ) {
336    
337            ElementList el = XMLTools.getChildElements( "Keyword", CommonNamespaces.CNTXTNS, element );
338            String[] keywords = new String[el.getLength()];
339    
340            for ( int i = 0; i < keywords.length; i++ ) {
341                keywords[i] = XMLTools.getStringValue( el.item( i ) );
342            }
343    
344            return keywords;
345        }
346    
347        /**
348         * creates an instance of an ImageURL that is used for <LogoURL> and LegendURL
349         * 
350         * @param element
351         *            <LogoURL> or <LegendURL>
352         * 
353         * @return instance of <tt>ImageURL</tt>
354         * 
355         * @throws XMLParsingException
356         */
357        private static ImageURL createImageURL( Element element )
358                                throws XMLParsingException {
359    
360            ImageURL imageURL = null;
361    
362            if ( element != null ) {
363                String tmp = XMLTools.getAttrValue( element, null, "width", null );
364                int width = -1;
365                if ( tmp != null ) {
366                    width = Integer.parseInt( tmp );
367                }
368                tmp = XMLTools.getAttrValue( element, null, "height", null );
369                int height = -1;
370                if ( tmp != null ) {
371                    height = Integer.parseInt( tmp );
372                }
373                String format = XMLTools.getAttrValue( element, null, "format", null );
374    
375                Element elem = XMLTools.getRequiredChildElement( "OnlineResource", CommonNamespaces.CNTXTNS, element );
376                URL onlineResource = createOnlineResource( elem );
377    
378                imageURL = new ImageURL( width, height, format, onlineResource );
379            }
380    
381            return imageURL;
382        }
383    
384        /**
385         * creates an instance of an URL described by a <OnlineResource> element
386         * 
387         * @param element
388         *            <OnlineResource>
389         * 
390         * @return instance of <tt>URL</tt>
391         * 
392         * @throws XMLParsingException
393         */
394        private static URL createOnlineResource( Element element )
395                                throws XMLParsingException {
396    
397            URL onlineResource = null;
398    
399            if ( element != null ) {
400                String type = element.getAttributeNS( CommonNamespaces.XLNNS.toASCIIString(), "type" );
401                if ( ( type != null ) && !"".equals( type ) && !type.equals( "simple" ) ) {
402                    throw new XMLParsingException( "unknown type of online resource: " + type );
403                }
404                String tmp = element.getAttributeNS( CommonNamespaces.XLNNS.toASCIIString(), "href" );
405                tmp = OWSUtils.validateHTTPGetBaseURL( tmp );
406    
407                // System.out.println("href is: " + tmp);
408                try {
409                    onlineResource = new URL( tmp );
410                } catch ( Exception e ) {
411                    throw new XMLParsingException( "couldn't create online resource", e );
412                }
413            }
414    
415            return onlineResource;
416        }
417    
418        /**
419         * creates an instance of BaseURL that is used for <DescriptionURL>
420         * 
421         * @param element
422         *            <DescriptionURL>
423         * @return instance of <tt>BaseURL</tt>, or null, if the passed element is null
424         * @throws XMLParsingException
425         */
426        private static BaseURL createBaseURL( Element element )
427                                throws XMLParsingException {
428    
429            BaseURL baseURL = null;
430    
431            if ( element != null ) {
432                String format = XMLTools.getAttrValue( element, null, "format", null );
433    
434                Element elem = XMLTools.getElement( element, CommonNamespaces.CNTXT_PREFIX + ":OnlineResource",
435                                                    CommonNamespaces.getNamespaceContext() );
436                URL onlineResource = createOnlineResource( elem );
437    
438                baseURL = new BaseURL( format, onlineResource );
439            }
440    
441            return baseURL;
442        }
443    
444        /**
445         * Creates a <tt>ContactInformation</tt>-instance according to the contents of the DOM-subtree starting at the given
446         * 'ContactInformation'-<tt>Element</tt>.
447         * <p>
448         * 
449         * @param element
450         *            the 'ContactInformation'-<tt>Element</tt>
451         * @throws XMLParsingException
452         *             if a syntactic or semantic error in the DOM-subtree is encountered
453         * @return the constructed <tt>ContactInformation</tt>-instance
454         */
455        private static CitedResponsibleParty createContactInformation( Element element )
456                                throws XMLParsingException {
457    
458            CitedResponsibleParty contact = null;
459    
460            if ( element != null ) {
461                // optional: <ContactPersonPrimary>
462                Element contactPersonPrimaryElement = XMLTools.getChildElement( "ContactPersonPrimary",
463                                                                                CommonNamespaces.CNTXTNS, element );
464    
465                String contactPerson = null;
466                String contactOrganization = null;
467                if ( contactPersonPrimaryElement != null ) {
468                    // required: <ContactPerson>
469                    contactPerson = XMLTools.getRequiredStringValue( "ContactPerson", CommonNamespaces.CNTXTNS,
470                                                                     contactPersonPrimaryElement );
471    
472                    // required: <ContactOrganization>
473                    contactOrganization = XMLTools.getRequiredStringValue( "ContactOrganization", CommonNamespaces.CNTXTNS,
474                                                                           contactPersonPrimaryElement );
475                }
476    
477                // optional: <ContactPosition>
478                String contactPosition = XMLTools.getStringValue( "ContactPosition", CommonNamespaces.CNTXTNS, element,
479                                                                  null );
480    
481                // optional: <ContactAddress>
482                Address contactAddress = null;
483                Element contactAddressElement = XMLTools.getChildElement( "ContactAddress", CommonNamespaces.CNTXTNS,
484                                                                          element );
485    
486                if ( contactAddressElement != null ) {
487                    // optional: <ContactElectronicMailAddress>
488                    String eMailAddress = XMLTools.getStringValue( "ContactElectronicMailAddress",
489                                                                   CommonNamespaces.CNTXTNS, element, null );
490                    contactAddress = createContactAddress( eMailAddress, contactAddressElement );
491                }
492    
493                // optional: <ContactVoiceTelephone>
494                String voice = XMLTools.getStringValue( "ContactVoiceTelephone", CommonNamespaces.CNTXTNS, element, null );
495    
496                // optional: <ContactFacsimileTelephone>
497                String fax = XMLTools.getStringValue( "ContactFacsimileTelephone", CommonNamespaces.CNTXTNS, element, null );
498    
499                Phone phone = new Phone( new String[] { fax }, new String[] { voice } );
500                ContactInfo ci = new ContactInfo( contactAddress, null, null, null, phone );
501                contact = new CitedResponsibleParty( new ContactInfo[] { ci }, new String[] { contactPerson },
502                                                     new String[] { contactOrganization },
503                                                     new String[] { contactPosition }, new RoleCode[0] );
504            }
505    
506            return contact;
507        }
508    
509        /**
510         * Creates a <tt>ContactAddress</tt>-instance according to the contents of the DOM-subtree starting at the given
511         * 'ContactAddress'-<tt>Element</tt>.
512         * <p>
513         * 
514         * @param element
515         *            the 'ContactAddress'-<tt>Element</tt>
516         * @throws XMLParsingException
517         *             if a syntactic or semantic error in the DOM-subtree is encountered
518         * @return the constructed <tt>ContactAddress</tt>-instance
519         */
520        private static Address createContactAddress( String eMail, Element element )
521                                throws XMLParsingException {
522    
523            // required: <AddressType>
524            /*
525             * String addressType = XMLTools.getRequiredStringValue( "AddressType", CommonNamespaces.CNTXTNS, element );
526             */
527            // required: <Address>
528            String address = XMLTools.getRequiredStringValue( "Address", CommonNamespaces.CNTXTNS, element );
529    
530            // required: <City>
531            String city = XMLTools.getRequiredStringValue( "City", CommonNamespaces.CNTXTNS, element );
532    
533            // required: <StateOrProvince>
534            String stateOrProvince = XMLTools.getRequiredStringValue( "StateOrProvince", CommonNamespaces.CNTXTNS, element );
535    
536            // required: <PostCode>
537            String postCode = XMLTools.getRequiredStringValue( "PostCode", CommonNamespaces.CNTXTNS, element );
538    
539            // required: <Country>
540            String country = XMLTools.getRequiredStringValue( "Country", CommonNamespaces.CNTXTNS, element );
541    
542            return new Address( stateOrProvince, city, country, new String[] { address }, new String[] { eMail }, postCode );
543        }
544    
545        /**
546         * creates an instance of a class encapsulating the deegree specific extensions of the general section of a web map
547         * context document
548         * 
549         * @param element
550         *            <Extension>
551         * @param xml
552         * 
553         * @return instance of <tt>GeneralExtension</tt>
554         * 
555         * @throws XMLParsingException
556         */
557        private static GeneralExtension createGeneralExtension( Element element, XMLFragment xml )
558                                throws XMLParsingException, MalformedURLException {
559    
560            GeneralExtension ge = null;
561    
562            if ( element != null ) {
563    
564                // retunrs the current mode of a client using a WMC
565                String mode = XMLTools.getStringValue( "Mode", CommonNamespaces.DGCNTXTNS, element, "ZOOMIN" );
566    
567                // <AuthentificationSettings>
568                Element elem = XMLTools.getChildElement( "AuthentificationSettings", CommonNamespaces.DGCNTXTNS, element );
569                AuthentificationSettings authSettings = null;
570                if ( elem != null ) {
571                    authSettings = createAuthentificationSettings( elem );
572                }
573                // <IOSetiings>
574                elem = XMLTools.getChildElement( "IOSettings", CommonNamespaces.DGCNTXTNS, element );
575                IOSettings ioSettings = null;
576                if ( elem != null ) {
577                    ioSettings = createIOSettings( elem, xml );
578                }
579                // <Frontend>
580                elem = XMLTools.getChildElement( "Frontend", CommonNamespaces.DGCNTXTNS, element );
581                Frontend frontend = null;
582                if ( elem != null ) {
583                    frontend = createFrontend( elem );
584                }
585                // <MapParameter>
586                elem = XMLTools.getRequiredChildElement( "MapParameter", CommonNamespaces.DGCNTXTNS, element );
587                MapParameter mapParameter = createMapParameter( elem );
588    
589                // <LayerTree> old version
590                elem = XMLTools.getChildElement( "LayerTree", CommonNamespaces.DGCNTXTNS, element );
591    
592                Node layerTreeRoot = null;
593                if ( elem != null ) {
594                    Element nodeElem = XMLTools.getRequiredChildElement( "Node", CommonNamespaces.DGCNTXTNS, elem );
595                    layerTreeRoot = createNode( nodeElem, null );
596                } else {
597                    try {
598                        layerTreeRoot = new Node( 0, null, "root", false, false );
599                        Node[] nodes = new Node[] { new Node( 1, layerTreeRoot, "deegree", false, false ) };
600                        layerTreeRoot.setNodes( nodes );
601                    } catch ( ContextException e ) {
602                        throw new XMLParsingException( "couldn't create layertree node", e );
603                    }
604                }
605    
606                elem = XMLTools.getChildElement( "MapModel", CommonNamespaces.DGCNTXTNS, element );
607                MapModel mapModel = null;
608                if ( elem != null ) {
609                    MapModelDocument doc = new MapModelDocument( elem );
610                    mapModel = doc.parseMapModel();
611                }
612    
613                String tmp = XMLTools.getStringValue( "XSLT", CommonNamespaces.DGCNTXTNS, element, "context2HTML.xsl" );
614                URL xslt = xml.resolve( tmp );
615                File file = new File( xslt.getFile() );
616                if ( !file.exists() ) {
617                    // address xslt script from WEB-INF/conf/igeoportal
618                    file = new File( file.getParentFile().getParentFile().getParent() + File.separatorChar + file.getName() );
619                    xslt = file.toURL();
620                }
621    
622                ge = new GeneralExtension( ioSettings, frontend, mapParameter, authSettings, mode, layerTreeRoot, mapModel,
623                                           xslt );
624            }
625    
626            return ge;
627        }
628    
629        /**
630         * creates a node in the layerTree
631         */
632        private static Node createNode( Element nodeElem, Node parent )
633                                throws XMLParsingException {
634    
635            int id = Integer.parseInt( XMLTools.getRequiredAttrValue( "id", null, nodeElem ) );
636            String title = XMLTools.getRequiredAttrValue( "title", null, nodeElem );
637            String s = XMLTools.getAttrValue( nodeElem, null, "selectable", null );
638            boolean selectable = "true".equals( s ) || "1".equals( s );
639            s = XMLTools.getAttrValue( nodeElem, null, "collapsed", null );
640            boolean collapsed = "true".equals( s ) || "1".equals( s );
641            Node node = null;
642            try {
643                node = new Node( id, parent, title, selectable, collapsed );
644            } catch ( Exception e ) {
645                throw new XMLParsingException( "couldn't create layertree node", e );
646            }
647    
648            // get Child nodes
649            ElementList nl = XMLTools.getChildElements( "Node", CommonNamespaces.DGCNTXTNS, nodeElem );
650            Node[] nodes = new Node[nl.getLength()];
651            for ( int i = 0; i < nodes.length; i++ ) {
652                nodes[i] = createNode( nl.item( i ), node );
653            }
654            // set child nodes
655            node.setNodes( nodes );
656    
657            return node;
658        }
659    
660        /**
661         * creates an instance of a class encapsulating access descrition to an authentification service for a deegree map
662         * client
663         * 
664         * @param element
665         *            <AuthentificationSettings>
666         * @return instance of <tt>AuthentificationSettings</tt>
667         * @throws XMLParsingException
668         */
669        private static AuthentificationSettings createAuthentificationSettings( Element element )
670                                throws XMLParsingException {
671    
672            Element elem = XMLTools.getRequiredChildElement( "AuthentificationService", CommonNamespaces.DGCNTXTNS, element );
673            elem = XMLTools.getRequiredChildElement( "OnlineResource", CommonNamespaces.CNTXTNS, elem );
674    
675            URL url = createOnlineResource( elem );
676            BaseURL bu = new BaseURL( "text/xml", url );
677    
678            return new AuthentificationSettings( bu );
679        }
680    
681        /**
682         * creates an instance of a class encapsulating the frontend (GUI) description of a deegree map client
683         * 
684         * @param element
685         *            <Frontend>
686         * 
687         * @return instance of <tt>Frontend</tt>
688         * 
689         * @throws XMLParsingException
690         */
691        private static Frontend createFrontend( Element element )
692                                throws XMLParsingException {
693    
694            // <Controller>
695            String controller = XMLTools.getRequiredStringValue( "Controller", CommonNamespaces.DGCNTXTNS, element );
696            // <Style>
697            String style = XMLTools.getStringValue( "Style", CommonNamespaces.DGCNTXTNS, element, null );
698            // <Buttons>
699            String buttons = XMLTools.getStringValue( "Buttons", CommonNamespaces.DGCNTXTNS, element, null );
700            // <CommonJS>
701            Element elem = XMLTools.getChildElement( "CommonJS", CommonNamespaces.DGCNTXTNS, element );
702            String[] commonJS = createCommonJS( elem );
703            // <West>
704            elem = XMLTools.getChildElement( "West", CommonNamespaces.DGCNTXTNS, element );
705            GUIArea west = createGUIArea( elem );
706            // <East>
707            elem = XMLTools.getChildElement( "East", CommonNamespaces.DGCNTXTNS, element );
708            GUIArea east = createGUIArea( elem );
709            // <North>
710            elem = XMLTools.getChildElement( "North", CommonNamespaces.DGCNTXTNS, element );
711            GUIArea north = createGUIArea( elem );
712            // <South>
713            elem = XMLTools.getChildElement( "South", CommonNamespaces.DGCNTXTNS, element );
714            GUIArea south = createGUIArea( elem );
715            // <Center>
716            elem = XMLTools.getChildElement( "Center", CommonNamespaces.DGCNTXTNS, element );
717            GUIArea center = createGUIArea( elem );
718            // <Header>
719            String header = XMLTools.getStringValue( "Header", CommonNamespaces.DGCNTXTNS, element, null );
720            // <Footer>
721            String footer = XMLTools.getStringValue( "Footer", CommonNamespaces.DGCNTXTNS, element, null );
722    
723            Frontend frontend = new JSPFrontend( controller, west, east, south, north, center, style, buttons, commonJS,
724                                                 header, footer );
725    
726            return frontend;
727        }
728    
729        /**
730         * creates a list of javascript pages (names) that contains javascript objects and methods that are used by more
731         * than one module
732         * 
733         * @param element
734         *            <CommonJS>
735         * 
736         * @return instance of <tt>String[]</tt>
737         * 
738         */
739        private static String[] createCommonJS( Element element ) {
740            String[] commonJS = null;
741            if ( element != null ) {
742                ElementList el = XMLTools.getChildElements( "Name", CommonNamespaces.DGCNTXTNS, element );
743                commonJS = new String[el.getLength()];
744                for ( int i = 0; i < commonJS.length; i++ ) {
745                    commonJS[i] = XMLTools.getStringValue( el.item( i ) );
746                }
747            }
748    
749            return commonJS;
750        }
751    
752        /**
753         * creates an instance of a class encapsulating the GUI description of one region of the GUI
754         * 
755         * @param element
756         *            <West>; <East>; <South>; <North> or <Center>
757         * 
758         * @return instance of <tt>GUIArea</tt>
759         * 
760         * @throws XMLParsingException
761         */
762        private static GUIArea createGUIArea( Element element )
763                                throws XMLParsingException {
764    
765            GUIArea gui = null;
766            if ( element != null ) {
767                String tmp = element.getLocalName();
768                int area = 0;
769                if ( tmp.equals( "West" ) ) {
770                    area = GUIArea.WEST;
771                } else if ( tmp.equals( "East" ) ) {
772                    area = GUIArea.EAST;
773                } else if ( tmp.equals( "South" ) ) {
774                    area = GUIArea.SOUTH;
775                } else if ( tmp.equals( "North" ) ) {
776                    area = GUIArea.NORTH;
777                } else if ( tmp.equals( "Center" ) ) {
778                    area = GUIArea.CENTER;
779                }
780    
781                NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
782                int w = XMLTools.getNodeAsInt( element, "./@width", nsContext, -1 );
783                int h = XMLTools.getNodeAsInt( element, "./@height", nsContext, -1 );
784                int l = XMLTools.getNodeAsInt( element, "./@left", nsContext, -1 );
785                int t = XMLTools.getNodeAsInt( element, "./@top", nsContext, -1 );
786                int r = XMLTools.getNodeAsInt( element, "./@right", nsContext, -1 );
787                int b = XMLTools.getNodeAsInt( element, "./@bottom", nsContext, -1 );
788                boolean ov = XMLTools.getNodeAsBoolean( element, "./@overlay", nsContext, false );
789                boolean head = XMLTools.getNodeAsBoolean( element, "./@header", nsContext, false );
790                boolean close = XMLTools.getNodeAsBoolean( element, "./@closable", nsContext, false );
791    
792                // hidden
793                tmp = XMLTools.getAttrValue( element, null, "hidden", null );
794                boolean hidden = "1".equals( tmp ) || "true".equals( tmp );
795                // <Module>
796                ElementList el = XMLTools.getChildElements( "Module", CommonNamespaces.DGCNTXTNS, element );
797                Module[] modules = new Module[el.getLength()];
798                for ( int i = 0; i < modules.length; i++ ) {
799                    modules[i] = createModule( el.item( i ) );
800                }
801                gui = new GUIArea( area, hidden, w, h, l, t, r, b, ov, head, close, modules );
802            }
803    
804            return gui;
805        }
806    
807        /**
808         * creates an instance of a class encapsulating module informations
809         * 
810         * @param element
811         *            <Module>
812         * 
813         * @return instance of <tt>Module</tt>
814         * 
815         * @throws XMLParsingException
816         */
817        private static Module createModule( Element element )
818                                throws XMLParsingException {
819    
820            // hidden
821            String tmp = XMLTools.getAttrValue( element, null, "hidden", null );
822            boolean hidden = tmp.equals( "1" ) || tmp.equals( "true" );
823            // <Name>
824            String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.DGCNTXTNS, element );
825            // <Title>
826            String title = XMLTools.getStringValue( "Title", CommonNamespaces.DGCNTXTNS, element, name );
827            // <Content>
828            String content = XMLTools.getRequiredStringValue( "Content", CommonNamespaces.DGCNTXTNS, element );
829            // <ModuleConfiguration>
830            Element elem = XMLTools.getChildElement( "ModuleConfiguration", CommonNamespaces.DGCNTXTNS, element );
831            ModuleConfiguration mc = createModuleConfiguration( elem );
832            // <ParameterList>
833            elem = XMLTools.getChildElement( "ParameterList", CommonNamespaces.DGCNTXTNS, element );
834            ParameterList paramList = createParameterList( elem );
835    
836            String type = XMLTools.getAttrValue( element, null, "type", null );
837    
838            // width and height of a Module are optional
839            // if not set '0' will be used instead
840            NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
841            int w = XMLTools.getNodeAsInt( element, "./@width", nsContext, -1 );
842            int h = XMLTools.getNodeAsInt( element, "./@height", nsContext, -1 );
843            int l = XMLTools.getNodeAsInt( element, "./@left", nsContext, -1 );
844            int t = XMLTools.getNodeAsInt( element, "./@top", nsContext, -1 );
845            int b = XMLTools.getNodeAsInt( element, "./@bottom", nsContext, -1 );
846            int r = XMLTools.getNodeAsInt( element, "./@right", nsContext, -1 );
847            boolean ov = XMLTools.getNodeAsBoolean( element, "./@overlay", nsContext, false );
848            boolean head = XMLTools.getNodeAsBoolean( element, "./@header", nsContext, false );
849            boolean close = XMLTools.getNodeAsBoolean( element, "./@closable", nsContext, false );
850            boolean collapsed = XMLTools.getNodeAsBoolean( element, "./@collapsed", nsContext, false );
851    
852            String scrollable = XMLTools.getAttrValue( element, null, "scrolling", null );
853    
854            String[] moduleJS = createModuleJSList( element );
855            return new Module( name, title, content, hidden, type, l, t, r, b, w, h, ov, head, close, collapsed,
856                               scrollable, moduleJS, mc, paramList );
857        }
858    
859        /**
860         * creates an instance of a class encapsulating the access the configuration of Module
861         * 
862         * @param element
863         *            <ModuleConfiguration>
864         * 
865         * @return instance of <tt>ModuleConfiguration</tt>
866         * 
867         * @throws XMLParsingException
868         */
869        private static ModuleConfiguration createModuleConfiguration( Element element )
870                                throws XMLParsingException {
871    
872            ModuleConfiguration mc = null;
873            if ( element != null ) {
874                Element elem = XMLTools.getRequiredChildElement( "OnlineResource", CommonNamespaces.DGCNTXTNS, element );
875                URL onlineResource = createOnlineResource( elem );
876                mc = new ModuleConfiguration( onlineResource );
877            }
878    
879            return mc;
880        }
881    
882        /**
883         * creates an instance of a class encapsulating the layer list informations
884         * 
885         * @param element
886         *            <LayerList>
887         * 
888         * @return instance of <tt>LayerList</tt>
889         * 
890         * @throws XMLParsingException
891         */
892        private static ParameterList createParameterList( Element element )
893                                throws XMLParsingException {
894    
895            ParameterList parameterList = new ParameterList();
896            if ( element != null ) {
897                ElementList el = XMLTools.getChildElements( "Parameter", CommonNamespaces.DGCNTXTNS, element );
898                for ( int i = 0; i < el.getLength(); i++ ) {
899                    Parameter parameter = createParameter( el.item( i ) );
900                    parameterList.addParameter( parameter );
901                }
902            }
903    
904            return parameterList;
905        }
906    
907        /**
908         * creates an instance of a class encapsulating a parameter that shall be passed to a module
909         * 
910         * @param element
911         *            <Parameter>
912         * 
913         * @return instance of <tt>Parameter</tt>
914         * 
915         * @throws XMLParsingException
916         */
917        private static Parameter createParameter( Element element )
918                                throws XMLParsingException {
919    
920            String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.DGCNTXTNS, element );
921            String value = XMLTools.getRequiredStringValue( "Value", CommonNamespaces.DGCNTXTNS, element );
922            // Parameter param = new Parameter_Impl( name+":"+value, value );
923            Parameter param = new Parameter( name, value );
924    
925            return param;
926        }
927    
928        /**
929         * creates an instance of a class encapsulating informations about controlling options for a map presented to the
930         * user
931         * 
932         * @param element
933         *            <MapParameter>
934         * 
935         * @return instance of <tt>MapParameter</tt>
936         * 
937         * @throws XMLParsingException
938         */
939        private static MapParameter createMapParameter( Element element )
940                                throws XMLParsingException {
941    
942            // <OfferedInfoFormats>
943            Element elem = XMLTools.getChildElement( "OfferedInfoFormats", CommonNamespaces.DGCNTXTNS, element );
944            Format[] infoFormats = null;
945            if ( elem != null ) {
946                infoFormats = createOfferedInfoFormats( elem );
947            }
948            // <OfferedZoomFactor>
949            elem = XMLTools.getChildElement( "OfferedZoomFactor", CommonNamespaces.DGCNTXTNS, element );
950            MapOperationFactor[] zoomFactors = null;
951            if ( elem != null ) {
952                zoomFactors = createOfferedMapOperationFactors( elem );
953            }
954            // <OfferedPanFactor>
955            elem = XMLTools.getChildElement( "OfferedPanFactor", CommonNamespaces.DGCNTXTNS, element );
956            MapOperationFactor[] panFactors = null;
957            if ( elem != null ) {
958                panFactors = createOfferedMapOperationFactors( elem );
959            }
960            // <MinScale>
961            String tmp = XMLTools.getStringValue( "MinScale", CommonNamespaces.DGCNTXTNS, element, "0" );
962            double minScale = Double.parseDouble( tmp );
963            // <MaxScale>
964            tmp = XMLTools.getStringValue( "MaxScale", CommonNamespaces.DGCNTXTNS, element, "9999999999" );
965            double maxScale = Double.parseDouble( tmp );
966    
967            MapParameter mp = new MapParameter( infoFormats, panFactors, zoomFactors, minScale, maxScale );
968    
969            return mp;
970        }
971    
972        /**
973         * Creates a list of the feature info formats offered by the client.
974         * 
975         * @param element
976         *            <OfferedInfoFormats> element of the configuration
977         * 
978         * @return list of offered feature info formats
979         * 
980         * @throws XMLParsingException
981         */
982        private static Format[] createOfferedInfoFormats( Element element )
983                                throws XMLParsingException {
984    
985            Format[] format = null;
986    
987            // get list of offered feature info formats
988            ElementList el = XMLTools.getChildElements( "Format", CommonNamespaces.DGCNTXTNS, element );
989    
990            format = new Format[el.getLength()];
991    
992            for ( int i = 0; i < el.getLength(); i++ ) {
993                String name = XMLTools.getStringValue( el.item( i ) );
994                String sel = XMLTools.getAttrValue( el.item( i ), null, "selected", null );
995    
996                boolean selected = "1".equals( sel ) || "true".equals( sel );
997                try {
998                    format[i] = new Format( name, selected );
999                } catch ( ContextException e ) {
1000                    throw new XMLParsingException( "", e );
1001                }
1002            }
1003    
1004            return format;
1005        }
1006    
1007        /**
1008         * returns a list of offered numerical map operation factors that can be used to determine zoom or pan levels
1009         * 
1010         * @param element
1011         *            a <tt>Element</tt> that contains <Factor> elements as children
1012         * 
1013         * @return list of <tt>MapOperationFactor</tt>s
1014         * 
1015         */
1016        private static MapOperationFactor[] createOfferedMapOperationFactors( Element element ) {
1017    
1018            // get list of offered factors
1019            ElementList el = XMLTools.getChildElements( "Factor", CommonNamespaces.DGCNTXTNS, element );
1020    
1021            MapOperationFactor[] mof = new MapOperationFactor[el.getLength()];
1022    
1023            for ( int i = 0; i < el.getLength(); i++ ) {
1024                boolean free = true;
1025                String tmp = XMLTools.getStringValue( el.item( i ) );
1026                double fac = -99;
1027    
1028                if ( !tmp.equals( "*" ) ) {
1029                    free = false;
1030                    fac = Double.parseDouble( tmp );
1031                }
1032    
1033                String sel = XMLTools.getAttrValue( el.item( i ), null, "selected", null );
1034                boolean selected = "1".equals( sel ) || "true".equals( sel );
1035                mof[i] = new MapOperationFactor( fac, selected, free );
1036            }
1037    
1038            return mof;
1039        }
1040    
1041        /**
1042         * creates an instance of a class encapsulating the IO setting informations
1043         * 
1044         * @param element
1045         * @param xml
1046         * @return the iosettings.
1047         * @throws XMLParsingException
1048         */
1049        private static IOSettings createIOSettings( Element element, XMLFragment xml )
1050                                throws XMLParsingException, MalformedURLException {
1051    
1052            // temp directory
1053            Element elem = XMLTools.getChildElement( "TempDirectory", CommonNamespaces.DGCNTXTNS, element );
1054            DirectoryAccess temp = null;
1055            if ( elem != null ) {
1056                temp = createDirectoryAccess( elem, null, xml );
1057            }
1058            // download directory
1059            elem = XMLTools.getChildElement( "DownloadDirectory", CommonNamespaces.DGCNTXTNS, element );
1060            DirectoryAccess download = null;
1061            if ( elem != null ) {
1062                download = createDirectoryAccess( elem, temp, xml );
1063            }
1064            if ( temp == null && elem == null ) {
1065                throw new XMLParsingException( "If <TempDirectory> isn't set, " + "downloaddirectory must be set!" );
1066            }
1067            // SLD directory
1068            elem = XMLTools.getChildElement( "SLDDirectory", CommonNamespaces.DGCNTXTNS, element );
1069            DirectoryAccess sld = null;
1070            if ( elem != null ) {
1071                sld = createDirectoryAccess( elem, temp, xml );
1072            }
1073            if ( temp == null && elem == null ) {
1074                throw new XMLParsingException( "If <TempDirectory> isn't set, " + "slddirectory must be set!" );
1075            }
1076            // Print directory
1077            elem = XMLTools.getChildElement( "PrintDirectory", CommonNamespaces.DGCNTXTNS, element );
1078            DirectoryAccess print = null;
1079            if ( elem != null ) {
1080                print = createDirectoryAccess( elem, temp, xml );
1081            }
1082            if ( temp == null && elem == null ) {
1083                throw new XMLParsingException( "If <TempDirectory> isn't set, " + "printdirectory must be set!" );
1084            }
1085    
1086            IOSettings ioSettings = new IOSettings( download, sld, print, temp );
1087    
1088            return ioSettings;
1089        }
1090    
1091        /**
1092         * @param element
1093         * @param tempDir
1094         * @return the directory access.
1095         * @throws XMLParsingException
1096         */
1097        private static DirectoryAccess createDirectoryAccess( Element element, DirectoryAccess tempDir, XMLFragment xml )
1098                                throws XMLParsingException, MalformedURLException {
1099    
1100            // directory name
1101            String name = XMLTools.getStringValue( "Name", CommonNamespaces.DGCNTXTNS, element, null );
1102            name = xml.resolve( name ).toExternalForm();
1103    
1104            URL url = null;
1105            Element elem = XMLTools.getChildElement( "Access", CommonNamespaces.DGCNTXTNS, element );
1106            if ( elem != null ) {
1107                elem = XMLTools.getRequiredChildElement( "OnlineResource", CommonNamespaces.CNTXTNS, elem );
1108                url = createOnlineResource( elem );
1109            }
1110    
1111            DirectoryAccess da = null;
1112            if ( name == null || url == null ) {
1113                da = tempDir;
1114            } else {
1115                da = new DirectoryAccess( xml.resolve( name ).toExternalForm(), url );
1116            }
1117    
1118            return da;
1119    
1120        }
1121    
1122        /**
1123         * creates an instance of a class encapsulating the layer list informations
1124         * 
1125         * @param element
1126         *            <LayerList>
1127         * @param user
1128         * @param sessionID
1129         * 
1130         * @return instance of <tt>LayerList</tt>
1131         * 
1132         * @throws XMLParsingException
1133         */
1134        private static LayerList createLayerList( Element element, User user, String sessionID )
1135                                throws XMLParsingException {
1136    
1137            ElementList el = XMLTools.getChildElements( "Layer", CommonNamespaces.CNTXTNS, element );
1138            Layer[] layers = new Layer[el.getLength()];
1139            for ( int i = 0; i < layers.length; i++ ) {
1140                layers[i] = createLayer( el.item( i ), user, sessionID );
1141            }
1142            LayerList list = new LayerList( layers );
1143    
1144            return list;
1145        }
1146    
1147        /**
1148         * creates an instance of a class encapsulating a web map context layer's attributes
1149         * 
1150         * @param element
1151         *            <Layer>
1152         * @param user
1153         * @param sessionID
1154         * 
1155         * @return instance of <tt>Layer</tt>
1156         * 
1157         * @throws XMLParsingException
1158         */
1159        private static Layer createLayer( Element element, User user, String sessionID )
1160                                throws XMLParsingException {
1161    
1162            String tmp = XMLTools.getRequiredAttrValue( "queryable", null, element );
1163            boolean queryable = "1".equals( tmp ) || "true".equals( tmp );
1164            tmp = XMLTools.getRequiredAttrValue( "hidden", null, element );
1165            boolean hidden = "1".equals( tmp ) || "true".equals( tmp );
1166    
1167            // <Name>
1168            String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.CNTXTNS, element );
1169            // <Title>
1170            String title = XMLTools.getRequiredStringValue( "Title", CommonNamespaces.CNTXTNS, element );
1171            // <Abstract>
1172            String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.CNTXTNS, element, null );
1173            // <DataURL>
1174            Element elem = XMLTools.getChildElement( "DataURL", CommonNamespaces.CNTXTNS, element );
1175            BaseURL dataURL = createBaseURL( elem );
1176            // <MetaDataURL>
1177            elem = XMLTools.getChildElement( "MetadataURL", CommonNamespaces.CNTXTNS, element );
1178            BaseURL metadataURL = createBaseURL( elem );
1179            // <SRS>
1180            tmp = XMLTools.getStringValue( "SRS", CommonNamespaces.CNTXTNS, element, null );
1181            String[] srs = StringTools.toArray( tmp, ",; ", true );
1182            // <FormatList>
1183            elem = XMLTools.getChildElement( "FormatList", CommonNamespaces.CNTXTNS, element );
1184            FormatList formatList = createFormatList( elem );
1185            // <Extension>
1186            Element extElem = XMLTools.getChildElement( "Extension", CommonNamespaces.CNTXTNS, element );
1187            LayerExtension extension = createLayerExtension( extElem, user, sessionID );
1188            // <Server>
1189            elem = XMLTools.getRequiredChildElement( "Server", CommonNamespaces.CNTXTNS, element );
1190            Server server = createServer( elem, user, sessionID, extension.getAuthentication() );
1191    
1192            // try setting metadataURl again. this time from server.
1193            if ( metadataURL == null ) {
1194                metadataURL = createMetadataURL( name, server );
1195            }
1196    
1197            // TODO must be removed, if reading capabilities from remote WMS is too slow
1198            setScaleHint( extElem, name, extension, server, user, sessionID, extension.getAuthentication() );
1199    
1200            // <StyleList>
1201            elem = XMLTools.getChildElement( "StyleList", CommonNamespaces.CNTXTNS, element );
1202            StyleList styleList = createStyleList( elem, name, server );
1203    
1204            Layer layer = null;
1205            try {
1206                layer = new Layer( server, name, title, abstract_, srs, dataURL, metadataURL, formatList, styleList,
1207                                   queryable, hidden, extension );
1208            } catch ( Exception e ) {
1209                throw new XMLParsingException( "couldn't create map context layer", e );
1210            }
1211    
1212            return layer;
1213        }
1214    
1215        /**
1216         * @param layerName
1217         *            the layer name from which to take the MetadataURL information
1218         * @param server
1219         *            the WMS server from which to read the layer information (WMS capabilities document)
1220         * @return only the first MetadataURL from the WMS capabilities for the given layer
1221         * @throws XMLParsingException
1222         */
1223        private static BaseURL createMetadataURL( String layerName, Server server )
1224                                throws XMLParsingException {
1225    
1226            WMSCapabilities capa = (WMSCapabilities) server.getCapabilities();
1227            BaseURL metaURL = null;
1228    
1229            if ( capa != null ) {
1230                org.deegree.ogcwebservices.wms.capabilities.Layer layer = capa.getLayer( layerName );
1231                if ( layer != null ) {
1232                    MetadataURL[] urls = layer.getMetadataURL();
1233                    if ( urls != null && urls.length > 0 ) {
1234                        metaURL = urls[0];
1235                    }
1236                } else {
1237                    if ( LOG.getLevel() == ILogger.LOG_DEBUG ) {
1238                        String msg = StringTools.concat( 500, "LayerName '", layerName,
1239                                                         "' does not exist in the WMSCapabilities of server ",
1240                                                         server.getOnlineResource() );
1241                        LOG.logDebug( msg );
1242                    }
1243                }
1244            }
1245            return metaURL;
1246        }
1247    
1248        /**
1249         * creates an instance of a class encapsulating informations about the server (service) a layer based on
1250         * 
1251         * @param element
1252         *            <Server>
1253         * @param user
1254         * @param sessionID
1255         * @param useAuthentication
1256         * 
1257         * @return instance of <tt>Server</tt>
1258         * 
1259         * @throws XMLParsingException
1260         */
1261        private static Server createServer( Element element, User user, String sessionID, int useAuthentication )
1262                                throws XMLParsingException {
1263    
1264            String service = XMLTools.getRequiredAttrValue( "service", null, element );
1265            String version = XMLTools.getRequiredAttrValue( "version", null, element );
1266            String title = XMLTools.getRequiredAttrValue( "title", null, element );
1267            // <OnlineResource>
1268            Element elem = XMLTools.getRequiredChildElement( "OnlineResource", CommonNamespaces.CNTXTNS, element );
1269            URL onlineResource = createOnlineResource( elem );
1270    
1271            OGCCapabilities capabilities = getCapabilities( onlineResource, service, version, user, sessionID,
1272                                                            useAuthentication );
1273    
1274            Server server = null;
1275            try {
1276                server = new Server( title, version, service, onlineResource, capabilities );
1277            } catch ( Exception e ) {
1278                LOG.logError( e.getMessage(), e );
1279                throw new XMLParsingException( "could not create context server", e );
1280            }
1281    
1282            return server;
1283        }
1284    
1285        /**
1286         * creates an instance of a class encapsulating a list of image formats a layer offers
1287         * 
1288         * @param element
1289         *            <FormatList>
1290         * 
1291         * @return instance of <tt>FormatList</tt>
1292         * 
1293         * @throws XMLParsingException
1294         */
1295        private static FormatList createFormatList( Element element )
1296                                throws XMLParsingException {
1297    
1298            ElementList el = XMLTools.getChildElements( "Format", CommonNamespaces.CNTXTNS, element );
1299            Format[] formats = new Format[el.getLength()];
1300            for ( int i = 0; i < formats.length; i++ ) {
1301                String name = XMLTools.getStringValue( el.item( i ) );
1302                String tmp = XMLTools.getAttrValue( el.item( i ), null, "current", null );
1303                boolean current = "1".equals( tmp ) || "true".equals( tmp ) || formats.length == 1;
1304                try {
1305                    formats[i] = new Format( name, current );
1306                } catch ( Exception e ) {
1307                    throw new XMLParsingException( "could not create context format", e );
1308                }
1309            }
1310    
1311            FormatList formatList = null;
1312            try {
1313                formatList = new FormatList( formats );
1314            } catch ( Exception e ) {
1315                LOG.logDebug( e.getMessage(), e );
1316                throw new XMLParsingException( "could not create context formatList", e );
1317            }
1318    
1319            return formatList;
1320        }
1321    
1322        /**
1323         * creates an instance of a class encapsulating a list of styles available for a layer
1324         * 
1325         * @param element
1326         *            <StyleList>
1327         * @param layerName
1328         * @param server
1329         * 
1330         * @return instance of <tt>StyleList</tt>
1331         * 
1332         * @throws XMLParsingException
1333         */
1334        private static StyleList createStyleList( Element element, String layerName, Server server )
1335                                throws XMLParsingException {
1336    
1337            ElementList el = XMLTools.getChildElements( "Style", CommonNamespaces.CNTXTNS, element );
1338            Style[] styles = new Style[el.getLength()];
1339            boolean current = false;
1340            for ( int i = 0; i < styles.length; i++ ) {
1341                styles[i] = createStyle( el.item( i ), layerName, server );
1342                if ( styles[i].isCurrent() ) {
1343                    current = true;
1344                }
1345            }
1346            if ( !current ) {
1347                styles[0].setCurrent( true );
1348                LOG.logWarning( "not style for layer: " + layerName + " has been defined as current -> first style has been marked as current" );
1349            }
1350            StyleList styleList = null;
1351            try {
1352                styleList = new StyleList( styles );
1353            } catch ( Exception e ) {
1354                LOG.logDebug( e.getMessage(), e );
1355                throw new XMLParsingException( "could not create context stylelist", e );
1356            }
1357    
1358            return styleList;
1359        }
1360    
1361        /**
1362         * creates an instance of a class encapsulating a description of a Style
1363         * 
1364         * @param element
1365         *            <Style>
1366         * 
1367         * @return instance of <tt>Style</tt>
1368         * 
1369         * @throws XMLParsingException
1370         */
1371        private static Style createStyle( Element element, String layerName, Server server )
1372                                throws XMLParsingException {
1373    
1374            Style style = null;
1375    
1376            String tmp = XMLTools.getAttrValue( element, null, "current", null );
1377            boolean current = "1".equals( tmp ) || "true".equals( tmp );
1378    
1379            Element elem = XMLTools.getChildElement( "SLD", CommonNamespaces.CNTXTNS, element );
1380            if ( elem != null ) {
1381                SLD sld = createSLD( elem );
1382                try {
1383                    style = new Style( sld, current );
1384                } catch ( Exception e ) {
1385                    throw new XMLParsingException( "could not create context style", e );
1386                }
1387            } else {
1388                String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.CNTXTNS, element );
1389                String title = XMLTools.getRequiredStringValue( "Title", CommonNamespaces.CNTXTNS, element );
1390                String abstract_ = XMLTools.getStringValue( "Abstract", CommonNamespaces.CNTXTNS, element, null );
1391                // <LegendURL>
1392                elem = XMLTools.getChildElement( "LegendURL", CommonNamespaces.CNTXTNS, element );
1393                ImageURL legendURL = null;
1394                if ( elem != null ) {
1395                    legendURL = createImageURL( elem );
1396                } else {
1397                    try {
1398                        legendURL = createLegendURL( name, layerName, server );
1399                    } catch ( Exception e ) {
1400                        throw new XMLParsingException( "could not create context style", e );
1401                    }
1402                }
1403                try {
1404                    style = new Style( name, title, abstract_, legendURL, current );
1405                } catch ( Exception e ) {
1406                    LOG.logDebug( e.getMessage(), e );
1407                    throw new XMLParsingException( "could not create context style", e );
1408                }
1409            }
1410    
1411            return style;
1412        }
1413    
1414        /**
1415         * creates a legendURL for a style/layer by evaluating the servers capabilities the layer is servered by.
1416         * 
1417         * @return the image url.
1418         * @throws XMLParsingException
1419         */
1420        private static ImageURL createLegendURL( String styleName, String layerName, Server server )
1421                                throws XMLParsingException {
1422    
1423            WMSCapabilities capa = (WMSCapabilities) server.getCapabilities();
1424            ImageURL legendURL = null;
1425            if ( capa != null ) {
1426                org.deegree.ogcwebservices.wms.capabilities.Layer layer = capa.getLayer( layerName );
1427                // null layer will produce NullPointerException@layer.getStyles()
1428                if ( layer == null ) {
1429                    LOG.logDebug( "LayerName: " + layerName + " does not exist in the WMSCapabilities" );
1430                }
1431                // if layer is null, no legend is needed!
1432                if ( layer != null ) {
1433                    org.deegree.ogcwebservices.wms.capabilities.Style[] styles = layer.getStyles();
1434                    org.deegree.ogcwebservices.wms.capabilities.Style style = null;
1435                    for ( int i = 0; i < styles.length; i++ ) {
1436                        // find responsible style definition
1437                        style = styles[i];
1438                        if ( style.getName().equals( styleName ) ) {
1439                            break;
1440                        }
1441                    }
1442    
1443                    LegendURL[] urls = null;
1444    
1445                    if ( style != null ) {
1446                        urls = style.getLegendURL();
1447                    }
1448    
1449                    if ( urls != null && urls.length > 0 && urls[0] != null ) {
1450                        // if style has defined LegendURL(s) take the first
1451                        legendURL = new ImageURL( urls[0].getWidth(), urls[0].getHeight(), urls[0].getFormat(),
1452                                                  urls[0].getOnlineResource() );
1453                    } else {
1454                        // create a GetLegendGraphic request as style URL if the server
1455                        // supports GetLegendGraphic operation
1456                        OperationsMetadata om = capa.getOperationMetadata();
1457                        Operation operation = om.getOperation( new QualifiedName( "GetLegendGraphic" ) );
1458                        if ( operation != null ) {
1459                            HTTP http = (HTTP) operation.getDCP().get( 0 );
1460                            URL url = http.getGetOnlineResources().get( 0 );
1461                            StringBuffer sb = new StringBuffer( 500 );
1462                            sb.append( OWSUtils.validateHTTPGetBaseURL( url.toExternalForm() ) );
1463                            GetLegendGraphic glg = GetLegendGraphic.create( "12", capa.getVersion(), layerName, styleName,
1464                                                                            null, null, 1, null, null, "image/jpeg", 20,
1465                                                                            20, null, null );
1466                            try {
1467                                sb.append( glg.getRequestParameter() );
1468                                url = new URL( sb.toString() );
1469                                legendURL = new ImageURL( 20, 20, "image/jpeg", url );
1470                            } catch ( Exception shouldNeverHappen ) {
1471                                shouldNeverHappen.printStackTrace();
1472                            }
1473                        }
1474                    }
1475                }
1476            }
1477    
1478            return legendURL;
1479        }
1480    
1481        /**
1482         * creates an instance of a class encapsulating a description of a Style based on a SLD
1483         * 
1484         * @param element
1485         *            <SLD>
1486         * 
1487         * @return instance of <tt>SLD</tt>
1488         * 
1489         * @throws XMLParsingException
1490         */
1491        private static SLD createSLD( Element element )
1492                                throws XMLParsingException {
1493    
1494            SLD sld = null;
1495    
1496            String name = XMLTools.getRequiredStringValue( "Name", CommonNamespaces.CNTXTNS, element );
1497            String title = XMLTools.getStringValue( "Title", CommonNamespaces.CNTXTNS, element, null );
1498    
1499            Element elem = XMLTools.getChildElement( "OnlineResource", CommonNamespaces.CNTXTNS, element );
1500            try {
1501                if ( elem != null ) {
1502                    URL onlineResource = createOnlineResource( elem );
1503                    sld = new SLD( name, title, onlineResource );
1504                } else {
1505                    elem = XMLTools.getChildElement( "StyledLayerDescriptor", CommonNamespaces.SLDNS, element );
1506                    if ( elem != null ) {
1507                        XMLFragment xml = new XMLFragment();
1508                        xml.setRootElement( elem );
1509                        StyledLayerDescriptor styledLayerDescriptor = SLDFactory.createSLD( xml );
1510                        sld = new SLD( name, title, styledLayerDescriptor );
1511                    } else {
1512                        FeatureTypeStyle fts = SLDFactory.createFeatureTypeStyle( elem );
1513                        sld = new SLD( name, title, fts );
1514                    }
1515                }
1516            } catch ( Exception e ) {
1517                LOG.logDebug( e.getMessage(), e );
1518                throw new XMLParsingException( "couldn't create map context SLD", e );
1519            }
1520    
1521            return sld;
1522        }
1523    
1524        /**
1525         * creates an instance of a class encapsulating the deegree specific extensions of a Layer.
1526         * 
1527         * Extensions are: DataService, MasterLayer, SelectedForQuery, parentNodeId, showLegendGraphic, identifier,
1528         * ScaleHint.
1529         * 
1530         * @param element
1531         *            Extension
1532         * @param user
1533         * @param sessionID
1534         * 
1535         * @return instance of <tt>LayerExtension</tt>
1536         * 
1537         * @throws XMLParsingException
1538         */
1539        private static LayerExtension createLayerExtension( Element element, User user, String sessionID )
1540                                throws XMLParsingException {
1541    
1542            LayerExtension le = null;
1543            if ( element != null ) {
1544    
1545                String tmp = XMLTools.getNodeAsString( element, "./dgcntxt:UseAuthentication/text()",
1546                                                       CommonNamespaces.getNamespaceContext(), "NONE" );
1547                int ua = LayerExtension.NONE;
1548                if ( "sessionID".equalsIgnoreCase( tmp ) ) {
1549                    ua = LayerExtension.SESSIONID;
1550                } else if ( "user/password".equalsIgnoreCase( tmp ) ) {
1551                    ua = LayerExtension.USERPASSWORD;
1552                }
1553    
1554                // standard edition: download WFS data
1555                DataService dataService = null;
1556                Element elem = XMLTools.getChildElement( "DataService", CommonNamespaces.DGCNTXTNS, element );
1557                if ( elem != null ) {
1558                    Element el = XMLTools.getRequiredChildElement( "Server", CommonNamespaces.CNTXTNS, elem );
1559                    Server server = createServer( el, user, sessionID, ua );
1560                    String geoType = XMLTools.getStringValue( "GeometryType", CommonNamespaces.DGCNTXTNS, elem, null );
1561                    String featureType = XMLTools.getStringValue( "FeatureType", CommonNamespaces.DGCNTXTNS, elem, null );
1562                    dataService = new DataService( server, featureType, geoType );
1563                }
1564    
1565                // project specific
1566                boolean masterLayer = false;
1567                elem = XMLTools.getChildElement( "MasterLayer", CommonNamespaces.DGCNTXTNS, element );
1568                if ( elem != null ) {
1569                    String s = XMLTools.getStringValue( elem );
1570                    masterLayer = "true".equals( s ) || "1".equals( s );
1571                }
1572    
1573                // project specific
1574                boolean selectedForFI = false;
1575                elem = XMLTools.getChildElement( "SelectedForQuery", CommonNamespaces.DGCNTXTNS, element );
1576                if ( elem != null ) {
1577                    String s = XMLTools.getStringValue( elem );
1578                    selectedForFI = "true".equals( s ) || "1".equals( s );
1579                }
1580    
1581                // portlet edition: LayerTree
1582                int parentNodeId = 1;
1583                elem = XMLTools.getChildElement( "parentNodeId", CommonNamespaces.DGCNTXTNS, element );
1584                if ( elem != null ) {
1585                    parentNodeId = Integer.parseInt( XMLTools.getStringValue( elem ) );
1586                }
1587    
1588                // 
1589                boolean showLegendGraphic = false;
1590                elem = XMLTools.getChildElement( "showLegendGraphic", CommonNamespaces.DGCNTXTNS, element );
1591                if ( elem != null ) {
1592                    String s = XMLTools.getStringValue( elem );
1593                    showLegendGraphic = "true".equals( s ) || "1".equals( s );
1594                }
1595    
1596                // standard edition: LayerTree
1597                String identifier = null;
1598                elem = XMLTools.getChildElement( "identifier", CommonNamespaces.DGCNTXTNS, element );
1599                if ( elem != null ) {
1600                    identifier = XMLTools.getStringValue( elem );
1601                }
1602    
1603                // standard edition: ScaleHint
1604                String scaleHint = null;
1605                elem = XMLTools.getChildElement( "ScaleHint", CommonNamespaces.DGCNTXTNS, element );
1606                double minScale = 0;
1607                double maxScale = Double.MAX_VALUE;
1608                if ( elem != null ) {
1609                    minScale = Double.valueOf( XMLTools.getRequiredAttrValue( "min", null, elem ) );
1610                    maxScale = Double.valueOf( XMLTools.getRequiredAttrValue( "max", null, elem ) );
1611                }
1612    
1613                le = new LayerExtension( dataService, masterLayer, minScale, maxScale, selectedForFI, ua, parentNodeId,
1614                                         showLegendGraphic, identifier );
1615    
1616            } else {
1617                le = new LayerExtension();
1618            }
1619    
1620            return le;
1621        }
1622    
1623        /**
1624         * Use information form extension and server elements of a layer to set a scaleHint.
1625         * 
1626         * If layer extension contains scale hints (min, max), then these values are used. Otherwise, the information is
1627         * taken from the WMS capabilities by using {@link #getScaleHintFromCapabilities(Server, String, User, String, int)}
1628         * 
1629         * @param extElem
1630         * @param name
1631         * @param extension
1632         * @param server
1633         * @param user
1634         * @param sessionID
1635         * @param useAuthentication
1636         * @throws XMLParsingException
1637         */
1638        private static void setScaleHint( Element extElem, String name, LayerExtension extension, Server server, User user,
1639                                          String sessionID, int useAuthentication )
1640                                throws XMLParsingException {
1641    
1642            // <deegree:ScaleHint min="0.0" max="41.0"/>
1643            Element elem = null;
1644            if ( extElem != null ) {
1645                elem = XMLTools.getChildElement( "ScaleHint", CommonNamespaces.DGCNTXTNS, extElem );
1646            }
1647    
1648            if ( elem == null ) {
1649                // reade scaleHint from WMS Capabilities
1650                double[] sc = getScaleHintFromCapabilities( server, name, user, sessionID, useAuthentication );
1651                extension.setMinScaleHint( sc[0] );
1652                extension.setMaxScaleHint( sc[1] );
1653            } else {
1654                // do nothing. Values have already been read from layer extension when creating the LayerExtension object.
1655            }
1656        }
1657    
1658        /**
1659         * taken from d1 and adjusted for d2.
1660         * 
1661         * TODO: check if inconsistencies arise regarding user-dependant scaleHint, because of using {@link #wmsCache}.
1662         * 
1663         * @param server
1664         * @param layerName
1665         * @param user
1666         * @param sessionID
1667         * @param useAuthentication
1668         * @return
1669         */
1670        private static double[] getScaleHintFromCapabilities( Server server, String layerName, User user, String sessionID,
1671                                                              int useAuthentication ) {
1672    
1673            double[] sc = new double[] { 0, Double.MAX_VALUE };
1674            WMSCapabilities capa = null;
1675    
1676            // capabilities have not been stored in cache before. getting the capabilities for the specified user
1677            if ( wmsCache.get( server.getOnlineResource() ) == null ) {
1678                capa = (WMSCapabilities) getCapabilities( server.getOnlineResource(), server.getService(),
1679                                                          server.getVersion(), user, sessionID, useAuthentication );
1680            } else {
1681                // get capabilities from cache.
1682                // May cause an inconsistency problem, if cache contains capabilities of a different but the specified user.
1683                // Could be handled with different caches for different users, but this would cause performance problems.
1684                capa = (WMSCapabilities) wmsCache.get( server.getOnlineResource() );
1685            }
1686            if ( capa != null ) {
1687                wmsCache.put( server.getOnlineResource(), capa );
1688                org.deegree.ogcwebservices.wms.capabilities.Layer lay = capa.getLayer( layerName );
1689                if ( lay != null ) {
1690                    try {
1691                        sc[0] = lay.getScaleHint().getMin();
1692                        sc[1] = lay.getScaleHint().getMax();
1693                    } catch ( Exception e ) {
1694                    }
1695                }
1696            }
1697            return sc;
1698        }
1699    
1700        /**
1701         * returns the capabilities for the passed server. The capabilities are read directly from the server or from the
1702         * loacal cache.
1703         * 
1704         * @param url
1705         * @param service
1706         * @param version
1707         * @param user
1708         * @param sessionID
1709         * @param useAuthentication
1710         * @return he capabilities for the passed server. The capabilities are read directly from the server or from the
1711         *         loacal cache.
1712         */
1713        private static OGCCapabilities getCapabilities( URL url, String service, String version, User user,
1714                                                        String sessionID, int useAuthentication ) {
1715    
1716            OGCCapabilities capa = null;
1717    
1718            String href = OWSUtils.validateHTTPGetBaseURL( url.toExternalForm() );
1719            if ( href.toLowerCase().startsWith( "http://" ) || href.toLowerCase().startsWith( "https://" ) ) {
1720                if ( "OGC:WMS".equals( service ) ) {
1721                    // is a HTTP URL so GetCapabilities request must be constructed
1722                    if ( "1.0.0".equals( version ) ) {
1723                        href = StringTools.concat( 1000, href, "request=capabilities&service=WMS", "&WMTVER=", version );
1724                    } else {
1725                        href = StringTools.concat( 1000, href, "request=GetCapabilities&service=WMS", "&version=", version );
1726                    }
1727    
1728                } else if ( "OGC:WFS".equals( service ) ) {
1729                    // is a HTTP URL so GetCapabilities request must be constructed
1730                    href = StringTools.concat( 1000, href, "request=GetCapabilities&service=WFS", "&version=", version );
1731    
1732                } else if ( "OGC:WCS".equals( service ) ) {
1733                    // is a HTTP URL so GetCapabilities request must be constructed
1734                    href = StringTools.concat( 1000, href, "request=GetCapabilities&service=WCS", "&version=", version );
1735    
1736                }
1737    
1738                if ( useAuthentication == LayerExtension.SESSIONID ) {
1739                    href = StringTools.concat( 1000, href, "&sessionID=", sessionID );
1740                } else if ( useAuthentication == LayerExtension.USERPASSWORD ) {
1741                    href = StringTools.concat( 1000, href, "&user=", user.getName(), "&password=", user.getPassword() );
1742                }
1743            }
1744    
1745            if ( wmsCache.get( url ) == null && "OGC:WMS".equals( service ) ) {
1746                LOG.logDebug( "get " + service + " capabilities from GetCapabilities request" );
1747                capa = parseCapabilities( href, service );
1748                if ( capa != null ) {
1749                    // write capabilities into local cache
1750                    wmsCache.put( url, (WMSCapabilities) capa );
1751                }
1752            } else if ( "OGC:WMS".equals( service ) ) {
1753                LOG.logDebug( "get WMS capabilities from cache" );
1754                capa = wmsCache.get( url );
1755            } else if ( wfsCache.get( url ) == null && "OGC:WFS".equals( service ) ) {
1756                LOG.logDebug( "get " + service + " capabilities from GetCapabilities request" );
1757                capa = parseCapabilities( href, service );
1758                if ( capa != null ) {
1759                    // write capabilities into local cache
1760                    wfsCache.put( url, (WFSCapabilities) capa );
1761                }
1762            } else if ( "OGC:WFS".equals( service ) ) {
1763                LOG.logDebug( "get WFS capabilities from cache" );
1764                capa = wfsCache.get( url );
1765            } else if ( wcsCache.get( url ) == null && "OGC:WCS".equals( service ) ) {
1766                LOG.logDebug( "get " + service + " capabilities from GetCapabilities request" );
1767                capa = parseCapabilities( href, service );
1768                if ( capa != null ) {
1769                    // write capabilities into local cache
1770                    wcsCache.put( url, (WCSCapabilities) capa );
1771                }
1772            } else if ( "OGC:WFS".equals( service ) ) {
1773                LOG.logDebug( "get WCS capabilities from cache" );
1774                capa = wcsCache.get( url );
1775            }
1776    
1777            return capa;
1778        }
1779    
1780        /**
1781         * 
1782         * @param href
1783         * @param service
1784         * @return the capabilities bean.
1785         */
1786        private static OGCCapabilities parseCapabilities( String href, String service ) {
1787    
1788            OGCCapabilities capa = null;
1789            try {
1790                URL url = null;
1791                Reader reader = null;
1792    
1793                // consider that the reference to the capabilities may has been
1794                // made by a file URL to a local copy
1795                if ( href.toLowerCase().startsWith( "http://" ) || href.toLowerCase().startsWith( "https://" ) ) {
1796                    HttpClient httpclient = new HttpClient();
1797                    httpclient = WebUtils.enableProxyUsage( httpclient, new URL( href ) );
1798                    int timeout = Integer.parseInt( Messages.getString( "WebMapContextFactory.timeout" ) );
1799                    httpclient.getHttpConnectionManager().getParams().setSoTimeout( timeout );
1800    
1801                    GetMethod httpget = new GetMethod( href );
1802                    LOG.logDebug( "GetCapabilities: ", href );
1803    
1804                    httpclient.executeMethod( httpget );
1805                    reader = new InputStreamReader( httpget.getResponseBodyAsStream() );
1806                } else {
1807                    if ( href.endsWith( "?" ) ) {
1808                        url = new URL( href.substring( 0, href.length() - 1 ) );
1809                    }
1810                    reader = new InputStreamReader( url.openStream() );
1811                }
1812    
1813                OGCCapabilitiesDocument doc = null;
1814                if ( "OGC:WMS".equals( service ) ) {
1815                    doc = new WMSCapabilitiesDocument();
1816                    doc.load( reader, XMLFragment.DEFAULT_URL );
1817                    doc = WMSCapabilitiesDocumentFactory.getWMSCapabilitiesDocument( doc.getRootElement() );
1818                } else if ( "OGC:WFS".equals( service ) ) {
1819                    doc = new WFSCapabilitiesDocument();
1820                    doc.load( reader, XMLFragment.DEFAULT_URL );
1821                } else if ( "OGC:WCS".equals( service ) ) {
1822                    doc = new WCSCapabilitiesDocument();
1823                    doc.load( reader, XMLFragment.DEFAULT_URL );
1824                } else {
1825                    throw new XMLParsingException( "not supported service type: " + service );
1826                }
1827    
1828                capa = doc.parseCapabilities();
1829            } catch ( Exception e ) {
1830                LOG.logWarning( "could not read capabilities: " + href );
1831                // LOG.logError( e.getMessage(), e );
1832                return null;
1833            }
1834            return capa;
1835        }
1836    
1837        // /**
1838        // * @param mapServer
1839        // * @param layer
1840        // * @return ScaleHint
1841        // */
1842        // private static double[] getScaleHintFromCapabilities( Server mapServer, String layer ) {
1843        //
1844        // double[] sc = new double[] { 0, 9999999 };
1845        // WMSCapabilities capa = (WMSCapabilities) mapServer.getCapabilities();
1846        // if ( capa != null ) {
1847        // org.deegree.ogcwebservices.wms.capabilities.Layer lay = capa.getLayer( layer );
1848        // if ( lay != null ) {
1849        // sc[0] = lay.getScaleHint().getMin();
1850        // sc[1] = lay.getScaleHint().getMax();
1851        // }
1852        // }
1853        // return sc;
1854        // }
1855    
1856        /**
1857         * creates a list (String[]) containing the name of the JavaScript files used by the moudle
1858         * 
1859         * @param element
1860         *            <Module>
1861         * 
1862         * @return instance of <tt>String[]</tt>
1863         * 
1864         */
1865        private static String[] createModuleJSList( Element element ) {
1866            String[] moduleJS = null;
1867            if ( element != null ) {
1868                ElementList el = XMLTools.getChildElements( "ModuleJS", CommonNamespaces.DGCNTXTNS, element );
1869                moduleJS = new String[el.getLength()];
1870                for ( int i = 0; i < el.getLength(); i++ ) {
1871                    moduleJS[i] = ( (Text) el.item( i ).getFirstChild() ).getData();
1872                }
1873            }
1874    
1875            return moduleJS;
1876        }
1877    }