    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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    }