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