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