001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/context/XMLFactory.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    
037    package org.deegree.portal.context;
038    
039    import java.awt.Rectangle;
040    import java.net.MalformedURLException;
041    import java.net.URI;
042    import java.net.URISyntaxException;
043    import java.net.URL;
044    import java.util.List;
045    
046    import javax.xml.parsers.ParserConfigurationException;
047    
048    import org.deegree.framework.util.Parameter;
049    import org.deegree.framework.util.ParameterList;
050    import org.deegree.framework.xml.XMLFragment;
051    import org.deegree.framework.xml.XMLTools;
052    import org.deegree.model.metadata.iso19115.CitedResponsibleParty;
053    import org.deegree.model.metadata.iso19115.ContactInfo;
054    import org.deegree.model.spatialschema.Point;
055    import org.deegree.ogcbase.BaseURL;
056    import org.deegree.ogcbase.CommonNamespaces;
057    import org.deegree.ogcbase.ImageURL;
058    import org.deegree.ogcwebservices.OWSUtils;
059    import org.w3c.dom.Attr;
060    import org.w3c.dom.DOMException;
061    import org.w3c.dom.Document;
062    import org.w3c.dom.Element;
063    import org.w3c.dom.Node;
064    import org.w3c.dom.Text;
065    
066    /**
067     * This is a factory class to export a <code>ViewContext</code> and a <code>ViewContextCollection</code> as an xml
068     * <code>org.w3c.dom.Document</code>.
069     * 
070     * 
071     * @version $Revision: 23790 $
072     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
073     * @author last edited by: $Author: jmays $
074     * 
075     * @version $Revision: 23790 $, $Date: 2010-04-23 14:22:04 +0200 (Fr, 23 Apr 2010) $
076     */
077    public class XMLFactory {
078    
079        // Import and define constants
080        private static URI OGC_CONTEXT_NS = CommonNamespaces.CNTXTNS;
081    
082        private static URI D_CONTEXT_NS = CommonNamespaces.DGCNTXTNS;
083    
084        private static URI SLD_NS = CommonNamespaces.SLDNS;
085    
086        private static URI XSI_NS = CommonNamespaces.buildNSURI( "http://www.w3.org/2001/XMLSchema-instance" );
087    
088        private static URI XLINK_NS = CommonNamespaces.buildNSURI( "http://www.w3.org/1999/xlink" );
089    
090        // Common objects
091        protected static javax.xml.parsers.DocumentBuilderFactory factory = null;
092    
093        protected static javax.xml.parsers.DocumentBuilder builder = null;
094    
095        protected static Document document = null;
096    
097        private XMLFactory() {
098            // Forbid instantiation
099        }
100    
101        /**
102         * Convenience method for creating a common document builder. Implementation copied from XmlDocument (by tf and ap).
103         * 
104         * @throws ParserConfigurationException
105         */
106        protected static void initDocBuilder()
107                                throws ParserConfigurationException {
108    
109            if ( builder == null ) {
110                if ( factory == null ) {
111                    factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
112                    factory.setIgnoringElementContentWhitespace( true );
113                    factory.setNamespaceAware( false );
114                    factory.setExpandEntityReferences( false );
115                }
116                builder = factory.newDocumentBuilder();
117            }
118    
119        }
120    
121        /**
122         * Creates a new <code>org.w3c.dom.Document</code> using the internal document builder.
123         * 
124         * @return new <code>Document</code> instance
125         * @throws ParserConfigurationException
126         */
127        protected static Document createDocument()
128                                throws ParserConfigurationException {
129    
130            initDocBuilder();
131    
132            return builder.newDocument();
133        }
134    
135        /**
136         * Creates a new <code>org.w3c.dom.Element</code>.
137         * 
138         * @param namespace
139         *            the element namespace
140         * @param elemName
141         *            the element name
142         * @return new <code>Element</code> instance
143         */
144        private static Element createElement( URI namespace, String elemName ) {
145    
146            return document.createElementNS( namespace == null ? null : namespace.toString(), elemName );
147        }
148    
149        /**
150         * Creates a new <code>org.w3c.dom.Attr</code>.
151         * 
152         * @param attName
153         *            the attribute name
154         * @param value
155         *            the attribute value
156         * @return new <code>Attr</code> instance
157         */
158        private static Attr createAttribute( String attName, String value ) {
159    
160            Attr attr = document.createAttribute( attName );
161            attr.setValue( value );
162    
163            return attr;
164        }
165    
166        /**
167         * Creates a new <code>org.w3c.dom.Text</code>. This is the textual content of an element.
168         * 
169         * @param text
170         *            the attribute name (if <code>null</code>, then context stays empty)
171         * @return new <code>Text</code> instance
172         */
173        private static Text createTextNode( String text ) {
174    
175            String t = "";
176            if ( text != null ) {
177                t = text;
178            }
179    
180            return document.createTextNode( t );
181        }
182    
183        /**
184         * Creates a new <code>org.w3c.dom.Document</code> describing a <code>ViewContext</code>.
185         * 
186         * @param viewContext
187         *            the <code>ViewContext</code> to be exported
188         * @return the xml dom-representation of the given viewContext.
189         * @throws ParserConfigurationException
190         *             if an XML parser couldn't be found
191         */
192        public static XMLFragment export( ViewContext viewContext )
193                                throws ParserConfigurationException {
194    
195            document = createDocument();
196            // start appending nodes...
197            try {
198                appendViewContext( document, viewContext );
199            } catch ( Exception e ) {
200                e.printStackTrace();
201                throw new ParserConfigurationException( e.getMessage() );
202            }
203    
204            XMLFragment xml = null;
205            try {
206                xml = new XMLFragment( document, XMLFragment.DEFAULT_URL );
207            } catch ( MalformedURLException neverHappens ) {
208                neverHappens.printStackTrace();
209            }
210    
211            return xml;
212        }
213    
214        /**
215         * Creates a new <code>org.w3c.dom.Document</code> describing a <code>ViewContextCollection</code>.
216         * 
217         * @param viewContCollec
218         *            the <code>ViewContextCollection</code> to be exported
219         * @return the xml dom-representation of the given viewContextCollection.
220         * @throws ParserConfigurationException
221         *             if an XML parser couldn't be found
222         * 
223         */
224        public static Document export( ViewContextCollection viewContCollec )
225                                throws ParserConfigurationException {
226    
227            document = createDocument();
228            // start appending nodes...
229            appendViewContextCollection( document, viewContCollec );
230    
231            return document;
232        }
233    
234        /**
235         * Appends the XML representation of a <code>ViewContext</code> to a <code>Node</code> using the
236         * <code>namespace</code>.
237         * 
238         * @param toNode
239         *            the <code>Node</code> to append the new element to
240         * @param viewContxt
241         *            the <code>ViewContext</code> to be appended as new element
242         * @throws URISyntaxException
243         * @throws DOMException
244         * 
245         * 
246         */
247        protected static void appendViewContext( Node toNode, ViewContext viewContxt )
248                                throws DOMException, URISyntaxException {
249    
250            if ( viewContxt != null ) {
251                Element e = createElement( OGC_CONTEXT_NS, "ViewContext" );
252                Element rootNode = (Element) toNode.appendChild( e );
253                XMLTools.appendNSBinding( rootNode, "sld", SLD_NS );
254                XMLTools.appendNSBinding( rootNode, "xlink", XLINK_NS );
255                XMLTools.appendNSBinding( rootNode, "deegree", D_CONTEXT_NS );
256                XMLTools.appendNSBinding( rootNode, "xsi", XSI_NS );
257                // XMLTools.appendNSBinding( rootNode, "", OGC_CONTEXT_NS );
258                XMLTools.appendNSDefaultBinding( rootNode, OGC_CONTEXT_NS );
259    
260                // e.setAttributeNode( createAttribute( "xmlns", OGC_CONTEXT_NS.toString() ) );
261                // e.setAttributeNode( createAttribute( "xmlns:sld", ) );
262                // e.setAttributeNode( createAttribute( "xmlns:xlink", .toString() ) );
263                // e.setAttributeNode( createAttribute( "xmlns:deegree", D_CONTEXT_NS.toString() ) );
264                // e.setAttributeNode( createAttribute( "xmlns:", XSI_NS.toString() ) );
265                rootNode.setAttribute( "version", "1.0.0" );
266                rootNode.setAttribute( "id", "viewContext_id" );
267    
268                appendGeneral( rootNode, viewContxt.getGeneral() );
269                appendLayerList( rootNode, viewContxt.getLayerList() );
270    
271                // toNode.appendChild( e );
272            }
273    
274        }
275    
276        /**
277         * Appends the XML representation of a <code>General</code> to a <code>Node</code> using the <code>namespace</code>.
278         * 
279         * @param toNode
280         *            the <code>Node</code> to append the new element to
281         * @param gen
282         *            the <code>General</code> to be appended as new element
283         * 
284         *            contains illegal characters
285         * @throws URISyntaxException
286         * @throws DOMException
287         */
288        protected static void appendGeneral( Node toNode, General gen )
289                                throws DOMException, URISyntaxException {
290    
291            if ( gen != null ) {
292                Element e = createElement( OGC_CONTEXT_NS, "General" );
293                appendWindow( e, gen.getWindow() );
294                appendBoundingBox( e, gen.getBoundingBox() );
295                appendTitle( e, gen.getTitle() );
296                appendAbstract( e, gen.getAbstract() );
297                appendKeywords( e, gen.getKeywords() );
298                appendDescriptionURL( e, gen.getDescriptionURL() );
299                appendLogoURL( e, gen.getLogoURL() );
300                appendContactInformation( e, gen.getContactInformation() );
301                // append deegree-specific extension
302                appendGeneralExtension( e, gen.getExtension() );
303    
304                toNode.appendChild( e );
305            }
306    
307        }
308    
309        /**
310         * Appends the XML representation of a <code>Rectangle</code> to a <code>Node</code> using the
311         * <code>namespace</code>.
312         * <p/>
313         * Note that the XML representation of a <code>Rectangle</code> is given by a <code>&lt;Window&gt;</code> element.
314         * 
315         * @param toNode
316         *            the <code>Node</code> to append the new element to
317         * @param r
318         *            the <code>Rectangle</code> to be appended as new element
319         * 
320         *            contains illegal characters
321         */
322        protected static void appendWindow( Node toNode, Rectangle r ) {
323    
324            if ( r != null ) {
325                Element window = createElement( OGC_CONTEXT_NS, "Window" );
326    
327                window.setAttribute( "width", String.valueOf( r.width ) );
328                window.setAttribute( "height", String.valueOf( r.height ) );
329    
330                toNode.appendChild( window );
331            }
332    
333        }
334    
335        /**
336         * Appends the XML representation of a <code>GM_Point[]</code> to a <code>Node</code> using the
337         * <code>namespace</code>.
338         * <p/>
339         * Note that the XML representation of a <code>GM_Point[]</code> is given by a <code>&lt;BoundingBox&gt;</code>
340         * element.
341         * 
342         * @param toNode
343         *            the <code>Node</code> to append the new element to
344         * @param points
345         *            the <code>GM_Point[]</code> to be appended as new element
346         * 
347         *            contains illegal characters
348         */
349        protected static void appendBoundingBox( Node toNode, Point[] points ) {
350    
351            if ( points != null && points.length == 2 ) {
352                Element bbox = createElement( OGC_CONTEXT_NS, "BoundingBox" );
353                String srs = "UNKNOWN_SRS";
354                try {
355                    srs = points[0].getCoordinateSystem().getIdentifier();
356                } catch ( Exception e ) {
357                    e.printStackTrace();
358                }
359    
360                bbox.setAttributeNode( createAttribute( "SRS", srs ) );
361    
362                bbox.setAttribute( "minx", String.valueOf( points[0].getX() ) );
363                bbox.setAttribute( "miny", String.valueOf( points[0].getY() ) );
364                bbox.setAttribute( "maxx", String.valueOf( points[1].getX() ) );
365                bbox.setAttribute( "maxy", String.valueOf( points[1].getY() ) );
366    
367                toNode.appendChild( bbox );
368    
369            }
370    
371        }
372    
373        /**
374         * Appends the XML representation of a <code>Title</code> to a <code>Node</code> using the <code>namespace</code>.
375         * 
376         * @param toNode
377         *            the <code>Node</code> to append the new element to
378         * @param title
379         *            the <code>String</code> to be appended as new element
380         * 
381         *            contains illegal characters
382         */
383        protected static void appendTitle( Node toNode, String title ) {
384    
385            String t = "";
386            if ( title != null ) {
387                t = title;
388            }
389            Element te = createElement( OGC_CONTEXT_NS, "Title" );
390            te.appendChild( createTextNode( t ) );
391            toNode.appendChild( te );
392    
393        }
394    
395        /**
396         * Appends the XML representation of an <code>Abstract</code> to a <code>Node</code> using the
397         * <code>namespace</code>.
398         * 
399         * @param toNode
400         *            the <code>Node</code> to append the new element to
401         * @param abstr
402         *            the <code>String</code> to be appended as new element
403         * 
404         */
405        protected static void appendAbstract( Node toNode, String abstr ) {
406    
407            if ( abstr != null ) {
408                Element te = createElement( OGC_CONTEXT_NS, "Abstract" );
409                te.appendChild( createTextNode( abstr ) );
410                toNode.appendChild( te );
411            }
412    
413        }
414    
415        /**
416         * Appends the XML representation of an <code>ImageURL</code> to a <code>Node</code> using the
417         * <code>namespace</code>.
418         * 
419         * @param toNode
420         *            the <code>Node</code> to append the new element to
421         * @param logoURL
422         *            the <code>ImageURL</code> to be appended as new element
423         * 
424         *            contains illegal characters
425         */
426        protected static void appendLogoURL( Node toNode, ImageURL logoURL ) {
427    
428            if ( logoURL != null && logoURL.getOnlineResource() != null ) {
429                Element e = createElement( OGC_CONTEXT_NS, "LogoURL" );
430                appendOnlineResource( e, logoURL.getOnlineResource() );
431                toNode.appendChild( e );
432            }
433    
434        }
435    
436        /**
437         * Appends the XML representation of a keyword list as a <code>String[]</code> to a <code>Node</code> using the
438         * <code>namespace</code>.
439         * <p/>
440         * Note that the keywords are appended to a <code>&lt;KeywordList&gt;</code> element.
441         * 
442         * @param toNode
443         *            the <code>Node</code> to append the new element to
444         * @param keywords
445         *            the <code>ImageURL</code> to be appended as new element
446         * 
447         *            contains illegal characters
448         */
449        protected static void appendKeywords( Node toNode, String[] keywords ) {
450    
451            if ( keywords != null ) {
452                Element kWordList = createElement( OGC_CONTEXT_NS, "KeywordList" );
453                for ( int i = 0; i < keywords.length; i++ ) {
454                    Element kw = createElement( OGC_CONTEXT_NS, "Keyword" );
455                    kw.appendChild( createTextNode( keywords[i] ) );
456                    kWordList.appendChild( kw );
457                }
458                toNode.appendChild( kWordList );
459            }
460    
461        }
462    
463        /**
464         * Appends the XML representation of a <code>BaseURL</code>, the <code>DescriptionURL</code>, to a <code>Node</code>
465         * using the <code>namespace</code>.
466         * 
467         * @param toNode
468         *            the <code>Node</code> to append the new element to
469         * @param bURL
470         *            the <code>BaseURL</code> to be appended as new element
471         * 
472         *            contains illegal characters
473         */
474        protected static void appendDescriptionURL( Node toNode, BaseURL bURL ) {
475    
476            if ( bURL != null ) {
477                Element du = createElement( OGC_CONTEXT_NS, "DescriptionURL" );
478                String f = bURL.getFormat();
479                if ( f != null ) {
480                    du.setAttribute( "format", f );
481                }
482    
483                URL onlineRes = bURL.getOnlineResource();
484                appendOnlineResource( du, onlineRes );
485    
486                toNode.appendChild( du );
487            }
488    
489        }
490    
491        /**
492         * Appends the XML representation of a <code>URL</code> to a <code>Node</code> as a
493         * <code>&lt;OnlineResource&gt;</code> using the <code>namespace</code>.
494         * 
495         * @param toNode
496         *            the <code>Node</code> to append the new element to
497         * @param onlineRes
498         *            the <code>URL</code> to be appended as new element
499         * 
500         *            contains illegal characters
501         */
502        protected static void appendOnlineResource( Node toNode, URL onlineRes ) {
503    
504            if ( onlineRes != null ) {
505                Element or = createElement( OGC_CONTEXT_NS, "OnlineResource" );
506                or.setAttributeNS( XLINK_NS.toASCIIString(), "xlink:type", "simple" );
507    
508                String href = onlineRes.toExternalForm();
509                if ( href != null ) {
510                    // according to OGC WMS 1.3 Testsuite a URL to a service operation
511                    // via HTTPGet must end with '?' or '&'
512                    if ( href.indexOf( '.' ) < 0 ) {
513                        href = OWSUtils.validateHTTPGetBaseURL( href );
514                    }
515                    or.setAttributeNS( XLINK_NS.toASCIIString(), "xlink:href", href );
516                }
517                toNode.appendChild( or );
518            }
519    
520        }
521    
522        /**
523         * Appends the XML representation of a <code>ContactInformation</code> to a <code>Node</code> using the
524         * <code>namespace</code>.
525         * 
526         * @param toNode
527         *            the <code>Node</code> to append the new element to
528         * @param respParty
529         */
530        protected static void appendContactInformation( Node toNode, CitedResponsibleParty respParty ) {
531    
532            if ( respParty != null ) {
533                Element ci = createElement( OGC_CONTEXT_NS, "ContactInformation" );
534    
535                appendContactPersonPrimary( ci, respParty );
536    
537                Element pos = createElement( OGC_CONTEXT_NS, "ContactPosition" );
538                pos.appendChild( createTextNode( respParty.getPositionName()[0] ) );
539                ci.appendChild( pos );
540                ContactInfo[] conInf = respParty.getContactInfo();
541    
542                if ( conInf != null && conInf.length > 0 ) {
543                    appendContactAddress( ci, conInf[0] );
544                    if ( conInf[0].getPhone().getVoice() != null && conInf[0].getPhone().getVoice().length > 0 ) {
545                        Element e = createElement( OGC_CONTEXT_NS, "ContactVoiceTelephone" );
546                        e.appendChild( createTextNode( conInf[0].getPhone().getVoice()[0] ) );
547                        ci.appendChild( e );
548                    }
549                    if ( conInf[0].getAddress().getElectronicMailAddress() != null
550                         && conInf[0].getAddress().getElectronicMailAddress().length > 0 ) {
551                        Element e = createElement( OGC_CONTEXT_NS, "ContactElectronicMailAddress" );
552                        e.appendChild( createTextNode( conInf[0].getAddress().getElectronicMailAddress()[0] ) );
553                        ci.appendChild( e );
554                    }
555                }
556    
557                toNode.appendChild( ci );
558            }
559    
560        }
561    
562        /**
563         * Appends the XML representation of a <code>ContactPersonPrimary</code> to a <code>Node</code> using the
564         * <code>namespace</code>.
565         * 
566         * @param toNode
567         *            the <code>Node</code> to append the new element to
568         * @param respParty
569         */
570        protected static void appendContactPersonPrimary( Node toNode, CitedResponsibleParty respParty ) {
571    
572            if ( respParty.getIndividualName() != null && respParty.getIndividualName().length > 0 ) {
573                Element cpp = createElement( OGC_CONTEXT_NS, "ContactPersonPrimary" );
574    
575                Element p = createElement( OGC_CONTEXT_NS, "ContactPerson" );
576    
577                p.appendChild( createTextNode( respParty.getIndividualName()[0] ) );
578                cpp.appendChild( p );
579    
580                Element org = createElement( OGC_CONTEXT_NS, "ContactOrganization" );
581                org.appendChild( createTextNode( respParty.getOrganisationName()[0] ) );
582                cpp.appendChild( org );
583    
584                toNode.appendChild( cpp );
585            }
586    
587        }
588    
589        /**
590         * Appends the XML representation of a <code>ContactAddress</code> to a <code>Node</code> using the
591         * <code>namespace</code>.
592         * 
593         * @param toNode
594         *            the <code>Node</code> to append the new element to
595         * @param ci
596         *            the <code>ContactAddress</code> to be appended as new element
597         * 
598         */
599        protected static void appendContactAddress( Node toNode, ContactInfo ci ) {
600    
601            if ( ci != null ) {
602                Element ca = createElement( OGC_CONTEXT_NS, "ContactAddress" );
603    
604                Element e = createElement( OGC_CONTEXT_NS, "AddressType" );
605                e.appendChild( createTextNode( "postal" ) );
606                ca.appendChild( e );
607    
608                e = createElement( OGC_CONTEXT_NS, "Address" );
609                e.appendChild( createTextNode( ci.getAddress().getDeliveryPoint()[0] ) );
610                ca.appendChild( e );
611    
612                e = createElement( OGC_CONTEXT_NS, "City" );
613                e.appendChild( createTextNode( ci.getAddress().getCity() ) );
614                ca.appendChild( e );
615    
616                e = createElement( OGC_CONTEXT_NS, "StateOrProvince" );
617                e.appendChild( createTextNode( ci.getAddress().getAdministrativeArea() ) );
618                ca.appendChild( e );
619    
620                e = createElement( OGC_CONTEXT_NS, "PostCode" );
621                e.appendChild( createTextNode( ci.getAddress().getPostalCode() ) );
622                ca.appendChild( e );
623    
624                e = createElement( OGC_CONTEXT_NS, "Country" );
625                e.appendChild( createTextNode( ci.getAddress().getCountry() ) );
626                ca.appendChild( e );
627    
628                toNode.appendChild( ca );
629            }
630    
631        }
632    
633        /**
634         * Appends the XML representation of a <code>LayerList</code> to a <code>Node</code> using the
635         * <code>namespace</code>.
636         * 
637         * @param toNode
638         *            the <code>Node</code> to append the new element to
639         * @param lList
640         *            the <code>LayerList</code> to be appended as new element
641         * 
642         */
643        protected static void appendLayerList( Node toNode, LayerList lList ) {
644    
645            if ( lList != null ) {
646                Element list = createElement( OGC_CONTEXT_NS, "LayerList" );
647    
648                Layer[] ls = lList.getLayers();
649                if ( ls != null ) {
650                    for ( int i = 0; i < ls.length; i++ ) {
651                        appendLayer( list, ls[i] );
652                    }
653                }
654                toNode.appendChild( list );
655            }
656    
657        }
658    
659        /**
660         * Appends the XML representation of a <code>Layer</code> to a <code>Node</code> using the <code>namespace</code>.
661         * 
662         * @param toNode
663         *            the <code>Node</code> to append the new element to
664         * @param layer
665         *            the <code>Layer</code> to be appended as new element
666         * 
667         */
668        protected static void appendLayer( Node toNode, Layer layer ) {
669    
670            if ( layer != null ) {
671                Element le = createElement( OGC_CONTEXT_NS, "Layer" );
672    
673                le.setAttribute( "queryable", stringValue01( layer.isQueryable() ) );
674                le.setAttribute( "hidden", stringValue01( layer.isHidden() ) );
675    
676                appendServer( le, layer.getServer() );
677    
678                Element n = createElement( OGC_CONTEXT_NS, "Name" );
679                n.appendChild( createTextNode( layer.getName() ) );
680                le.appendChild( n );
681    
682                if ( layer.getAbstract() != null ) {
683                    n = createElement( OGC_CONTEXT_NS, "Abstract" );
684                    n.appendChild( createTextNode( layer.getAbstract() ) );
685                    le.appendChild( n );
686                }
687    
688                n = createElement( OGC_CONTEXT_NS, "Title" );
689                n.appendChild( createTextNode( layer.getTitle() ) );
690                le.appendChild( n );
691    
692                if ( layer.getMetadataURL() != null ) {
693                    n = createElement( OGC_CONTEXT_NS, "MetadataURL" );
694                    le.appendChild( n );
695                    appendOnlineResource( n, layer.getMetadataURL().getOnlineResource() );
696                }
697    
698                appendSrs( le, layer.getSrs() );
699                appendFormatList( le, layer.getFormatList() );
700                appendStyleList( le, layer.getStyleList() );
701    
702                appendLayerExtension( le, layer.getExtension() );
703    
704                toNode.appendChild( le );
705            }
706    
707        }
708    
709        /**
710         * Appends the XML representation of a <code>Server</code> to a <code>Node</code> using the <code>namespace</code>.
711         * 
712         * @param toNode
713         *            the <code>Node</code> to append the new element to
714         * @param server
715         *            the <code>Server</code> to be appended as new element
716         * 
717         */
718        protected static void appendServer( Node toNode, Server server ) {
719    
720            if ( server != null ) {
721                Element serv = createElement( OGC_CONTEXT_NS, "Server" );
722    
723                if ( server.getService() != null ) {
724                    serv.setAttribute( "service", server.getService() );
725                }
726                if ( server.getService() != null ) {
727                    serv.setAttribute( "version", server.getVersion() );
728                }
729                if ( server.getService() != null ) {
730                    serv.setAttribute( "title", server.getTitle() );
731                }
732    
733                appendOnlineResource( serv, server.getOnlineResource() );
734    
735                toNode.appendChild( serv );
736            }
737    
738        }
739    
740        /**
741         * Appends the XML representation of a list of SRSs as a <code>String[]</code> to a <code>Node</code> using the
742         * <code>namespace</code>.
743         * 
744         * @param toNode
745         *            the <code>Node</code> to append the new element to
746         * @param srsList
747         *            the <code>String[]</code> to be appended as new element
748         * 
749         */
750        protected static void appendSrs( Node toNode, String[] srsList ) {
751    
752            if ( srsList != null ) {
753                StringBuffer sBuf = new StringBuffer( 100 );
754                for ( int i = 0; i < srsList.length; i++ ) {
755                    sBuf.append( srsList[i] );
756                    if ( i < srsList.length - 1 )
757                        sBuf.append( ";" );
758    
759                }
760                Element e = createElement( OGC_CONTEXT_NS, "SRS" );
761                e.appendChild( createTextNode( sBuf.toString() ) );
762                toNode.appendChild( e );
763            }
764    
765        }
766    
767        /**
768         * Appends the XML representation of a list of a <code>FormatList</code> to a <code>Node</code> using the
769         * <code>namespace</code>.
770         * 
771         * @param toNode
772         *            the <code>Node</code> to append the new element to
773         * @param formatList
774         *            the <code>FormatList</code> to be appended as new element
775         * 
776         *            contains illegal characters
777         */
778        protected static void appendFormatList( Node toNode, FormatList formatList ) {
779    
780            if ( formatList != null ) {
781    
782                Format[] formats = formatList.getFormats();
783                if ( formats != null ) {
784                    Element e = createElement( OGC_CONTEXT_NS, "FormatList" );
785    
786                    for ( int i = 0; i < formats.length; i++ ) {
787                        if ( formats[i] != null ) {
788                            Element f = createElement( OGC_CONTEXT_NS, "Format" );
789                            f.setAttribute( "current", stringValue01( formats[i].isCurrent() ) );
790                            if ( formats[i].getName() != null )
791                                f.appendChild( createTextNode( formats[i].getName() ) );
792                            e.appendChild( f );
793                        }
794                    }
795                    toNode.appendChild( e );
796                }
797            }
798    
799        }
800    
801        /**
802         * Appends the XML representation of a list of a <code>StyleList</code> to a <code>Node</code> using the
803         * <code>namespace</code>.
804         * 
805         * @param toNode
806         *            the <code>Node</code> to append the new element to
807         * @param styleList
808         *            the <code>StyleList</code> to be appended as new element
809         * 
810         */
811        protected static void appendStyleList( Node toNode, StyleList styleList ) {
812    
813            if ( styleList != null ) {
814    
815                Style[] styles = styleList.getStyles();
816                if ( styles != null ) {
817                    Element e = createElement( OGC_CONTEXT_NS, "StyleList" );
818    
819                    for ( int i = 0; i < styles.length; i++ ) {
820                        if ( styles[i] != null ) {
821                            Element s = createElement( OGC_CONTEXT_NS, "Style" );
822                            s.setAttribute( "current", stringValue01( styles[i].isCurrent() ) );
823    
824                            if ( styles[i].getName() != null ) {
825                                Element ne = createElement( OGC_CONTEXT_NS, "Name" );
826                                ne.appendChild( createTextNode( styles[i].getName() ) );
827                                s.appendChild( ne );
828                            }
829                            if ( styles[i].getTitle() != null ) {
830                                Element ne = createElement( OGC_CONTEXT_NS, "Title" );
831                                ne.appendChild( createTextNode( styles[i].getTitle() ) );
832                                s.appendChild( ne );
833                            }
834                            if ( styles[i].getAbstract() != null ) {
835                                Element ne = createElement( OGC_CONTEXT_NS, "Abstract" );
836                                ne.appendChild( createTextNode( styles[i].getAbstract() ) );
837                                s.appendChild( ne );
838                            }
839                            if ( styles[i].getLegendURL() != null && styles[i].getLegendURL().getOnlineResource() != null ) {
840                                Element ne = createElement( OGC_CONTEXT_NS, "LegendURL" );
841                                ne.setAttribute( "width", String.valueOf( styles[i].getLegendURL().getWidth() ) );
842                                ne.setAttribute( "height", String.valueOf( styles[i].getLegendURL().getHeight() ) );
843                                ne.setAttribute( "width", String.valueOf( styles[i].getLegendURL().getWidth() ) );
844                                appendOnlineResource( ne, styles[i].getLegendURL().getOnlineResource() );
845                                s.appendChild( ne );
846                            }
847                            e.appendChild( s );
848    
849                        }
850                    }
851                    toNode.appendChild( e );
852                }
853            }
854    
855        }
856    
857        /**
858         * Appends the XML representation of a list of a <code>ViewContextCollection</code> to a <code>Node</code> using the
859         * <code>namespace</code>.
860         * 
861         * @param toNode
862         *            the <code>Node</code> to append the new element to
863         * @param vcc
864         *            the <code>ViewContextCollection</code> to be appended as new element
865         * 
866         */
867        protected static void appendViewContextCollection( Node toNode, ViewContextCollection vcc ) {
868    
869            if ( vcc != null ) {
870                Element e = createElement( OGC_CONTEXT_NS, "ViewContextCollection" );
871                e.setAttributeNode( createAttribute( "xmlns", OGC_CONTEXT_NS.toString() ) );
872                e.setAttributeNode( createAttribute( "xmlns:sld", SLD_NS.toString() ) );
873                e.setAttributeNode( createAttribute( "xmlns:xlink", XLINK_NS.toString() ) );
874                e.setAttributeNode( createAttribute( "xmlns:deegree", D_CONTEXT_NS.toString() ) );
875                e.setAttributeNode( createAttribute( "xmlns:xsi", XSI_NS.toString() ) );
876                e.setAttributeNode( createAttribute( "version", "1.0.0" ) );
877    
878                ViewContextReference[] vcrs = vcc.getViewContextReferences();
879                if ( vcrs != null && vcrs.length > 0 ) {
880                    for ( int i = 0; i < vcrs.length; i++ ) {
881                        if ( vcrs[i] != null ) {
882                            appendContextReference( e, vcrs[i] );
883                        }
884                    }
885                }
886                toNode.appendChild( e );
887            }
888    
889        }
890    
891        /**
892         * Appends the XML representation of a list of a <code>ViewContextReference</code> to a <code>Node</code> using the
893         * <code>namespace</code>.
894         * <p/>
895         * // TODO implement ID in VCR
896         * 
897         * @param toNode
898         *            the <code>Node</code> to append the new element to
899         * @param vcr
900         *            the <code>ViewContextReference</code> to be appended as new element
901         */
902        protected static void appendContextReference( Node toNode, ViewContextReference vcr ) {
903    
904            if ( vcr != null ) {
905                Element e = createElement( OGC_CONTEXT_NS, "ViewContextReference" );
906    
907                e.setAttributeNode( createAttribute( "version", "1.0.0" ) );
908    
909                String id = vcr.getTitle().replace( ' ', '_' ).toLowerCase();
910                e.setAttributeNode( createAttribute( "id", id ) );
911    
912                Element t = createElement( OGC_CONTEXT_NS, "Title" );
913                t.appendChild( createTextNode( vcr.getTitle() ) );
914                e.appendChild( t );
915    
916                if ( vcr.getContextURL() != null ) {
917                    Element c = createElement( OGC_CONTEXT_NS, "ViewContextURL" );
918                    appendOnlineResource( c, vcr.getContextURL() );
919                    e.appendChild( c );
920                }
921                toNode.appendChild( e );
922            }
923    
924        }
925    
926        /**
927         * Creates a String representation ("0" or "1") of a boolean value.
928         * 
929         * @param value
930         *            the input value
931         * @return "0" or "1" if value is true or false, respectively
932         */
933        private static final String stringValue01( boolean value ) {
934            return value ? "1" : "0";
935        }
936    
937        // ***********************************************************************
938        // BEGIN Deegree specific methods
939        // ***********************************************************************
940    
941        /**
942         * Appends the XML representation of a list of a <code>GeneralExtension</code> to a <code>Node</code> using the
943         * <code>namespace</code>.
944         * 
945         * @param toNode
946         *            the <code>Node</code> to append the new element to
947         * @param genExt
948         *            the <code>GeneralExtension</code> to be appended as new element
949         * @throws URISyntaxException
950         * @throws DOMException
951         * 
952         */
953        protected static void appendGeneralExtension( Node toNode, GeneralExtension genExt )
954                                throws DOMException, URISyntaxException {
955    
956            if ( genExt != null ) {
957                Element e = createElement( OGC_CONTEXT_NS, "Extension" );
958                Element a = createElement( D_CONTEXT_NS, "deegree:Mode" );
959                a.appendChild( createTextNode( genExt.getMode() ) );
960                e.appendChild( a );
961    
962                appendAuthentificationSettings( e, genExt.getAuthentificationSettings() );
963                appendIOSettings( e, genExt.getIOSettings() );
964                appendFrontend( e, genExt.getFrontend() );
965                appendMapParameter( e, genExt.getMapParameter() );
966    
967                appendLayerTree( e, genExt.getLayerTreeRoot() );
968    
969                appendMapModel( e, genExt.getMapModel() );
970    
971                a = createElement( D_CONTEXT_NS, "deegree:XSLT" );
972                // TODO
973                // we should evaluate if it would be a better solution just to store local file name ...
974                a.appendChild( createTextNode( genExt.getXslt().toURI().toASCIIString() ) );
975                e.appendChild( a );
976    
977                toNode.appendChild( e );
978            }
979    
980        }
981    
982        /**
983         * @param e
984         * @param mapModel
985         */
986        private static void appendMapModel( Element e, MapModel mapModel ) {
987            if ( mapModel != null ) {
988                Element mm = createElement( D_CONTEXT_NS, "deegree:MapModel" );
989                e.appendChild( mm );
990                List<LayerGroup> layerGroups = mapModel.getLayerGroups();
991                for ( LayerGroup layerGroup : layerGroups ) {
992                    appendLayerGroup( mm, layerGroup );
993                }
994            }
995        }
996    
997        /**
998         * @param mm
999         * @param layerGroup
1000         */
1001        private static void appendLayerGroup( Element mm, LayerGroup layerGroup ) {
1002            Element lg = createElement( D_CONTEXT_NS, "deegree:LayerGroup" );
1003            mm.appendChild( lg );
1004            lg.setAttribute( "title", layerGroup.getTitle() );
1005            lg.setAttribute( "identifier", layerGroup.getTitle() );
1006            lg.setAttribute( "hidden", Boolean.toString( layerGroup.isHidden() ) );
1007            lg.setAttribute( "expanded", Boolean.toString( layerGroup.isExpanded() ) );
1008            List<MapModelEntry> mmes = layerGroup.getMapModelEntries();
1009            for ( MapModelEntry mapModelEntry : mmes ) {
1010                if ( mapModelEntry instanceof LayerGroup ) {
1011                    appendLayerGroup( lg, (LayerGroup) mapModelEntry );
1012                } else {
1013                    appendLayer( lg, (MMLayer) mapModelEntry );
1014                }
1015            }
1016        }
1017    
1018        /**
1019         * @param lg
1020         * @param layer
1021         */
1022        private static void appendLayer( Element lg, MMLayer layer ) {
1023            Element lay = createElement( D_CONTEXT_NS, "deegree:Layer" );
1024            lg.appendChild( lay );
1025            lay.setAttribute( "layerId", layer.getIdentifier() );
1026        }
1027    
1028        /**
1029         * Appends the XML representation of a <code>LayerTree</code>.
1030         * 
1031         * @param e
1032         *            the <code>Element</code> to append the new element to
1033         * @param layerTreeRoot
1034         *            the root <code>Node</code> of the LayerTree
1035         * 
1036         */
1037        protected static void appendLayerTree( Element e, org.deegree.portal.context.Node layerTreeRoot ) {
1038            Element layerTree = createElement( D_CONTEXT_NS, "deegree:LayerTree" );
1039            layerTree.appendChild( getLayerTreeNode( layerTreeRoot ) );
1040            e.appendChild( layerTree );
1041        }
1042    
1043        // create LayerTree elements
1044        private static Element getLayerTreeNode( org.deegree.portal.context.Node node ) {
1045            Element n = createElement( D_CONTEXT_NS, "deegree:Node" );
1046            n.setAttributeNode( createAttribute( "id", String.valueOf( node.getId() ) ) );
1047            n.setAttributeNode( createAttribute( "title", node.getTitle() ) );
1048    
1049            org.deegree.portal.context.Node[] nodes = node.getNodes();
1050            for ( org.deegree.portal.context.Node childNode : nodes ) {
1051                // ( tree -> recursion )
1052                n.appendChild( getLayerTreeNode( childNode ) );
1053            }
1054            return n;
1055        }
1056    
1057        /**
1058         * @param toNode
1059         * @param settings
1060         */
1061        protected static void appendAuthentificationSettings( Node toNode, AuthentificationSettings settings ) {
1062    
1063            if ( settings != null ) {
1064                Element e = createElement( D_CONTEXT_NS, "deegree:AuthentificationSettings" );
1065                Element ee = createElement( D_CONTEXT_NS, "deegree:AuthentificationService" );
1066                appendOnlineResource( ee, settings.getAuthentificationURL().getOnlineResource() );
1067                e.appendChild( ee );
1068                toNode.appendChild( e );
1069            }
1070    
1071        }
1072    
1073        /**
1074         * Appends the XML representation of a list of a <code>IOSettings</code> to a <code>Node</code> using the
1075         * <code>namespace</code>.
1076         * 
1077         * @param toNode
1078         *            the <code>Node</code> to append the new element to
1079         * @param ioSetts
1080         *            the <code>IOSettings</code> to be appended as new element
1081         */
1082        protected static void appendIOSettings( Node toNode, IOSettings ioSetts ) {
1083    
1084            if ( ioSetts != null ) {
1085                Element e = createElement( D_CONTEXT_NS, "deegree:IOSettings" );
1086    
1087                // TODO: ioSetts.getTempDirectory() , inexistent till now
1088                /*
1089                 * if(ioSetts.getRootDirectory() != null ){ Element rd = createElement(namespace,"deegree:TempDirectory");
1090                 * rd.appendChild( createTextNode( ioSetts.getRootDirectory() + "temp")); e.appendChild(rd); }
1091                 */
1092    
1093                appendDirectoryAccess( e, ioSetts.getTempDirectory(), "deegree:TempDirectory" );
1094                // appendDirectoryAccess( e, ioSetts.getDownloadDirectory(), "deegree:TempDirectory" );
1095                appendDirectoryAccess( e, ioSetts.getDownloadDirectory(), "deegree:DownloadDirectory" );
1096                appendDirectoryAccess( e, ioSetts.getSLDDirectory(), "deegree:SLDDirectory" );
1097                appendDirectoryAccess( e, ioSetts.getPrintDirectory(), "deegree:PrintDirectory" );
1098    
1099                toNode.appendChild( e );
1100            }
1101    
1102        }
1103    
1104        /**
1105         * Appends the XML representation of a list of a <code>DirectoryAccess</code> to a <code>Node</code> using the
1106         * <code>namespace</code>.
1107         * 
1108         * @param toNode
1109         *            the <code>Node</code> to append the new element to
1110         * @param dirAcc
1111         *            the <code>DirectoryAccess</code> to be appended as new element
1112         * @param dirName
1113         * 
1114         */
1115        protected static void appendDirectoryAccess( Node toNode, DirectoryAccess dirAcc, String dirName ) {
1116    
1117            if ( dirAcc != null ) {
1118                Element d = createElement( D_CONTEXT_NS, dirName );
1119                if ( dirAcc.getDirectoryName() != null ) {
1120                    Element a = createElement( D_CONTEXT_NS, "deegree:Name" );
1121                    a.appendChild( createTextNode( dirAcc.getDirectoryName() ) );
1122                    d.appendChild( a );
1123    
1124                }
1125                if ( dirAcc.getOnlineResource() != null ) {
1126                    Element a = createElement( D_CONTEXT_NS, "deegree:Access" );
1127                    appendOnlineResource( a, dirAcc.getOnlineResource() );
1128                    d.appendChild( a );
1129                }
1130                toNode.appendChild( d );
1131            }
1132    
1133        }
1134    
1135        /**
1136         * Appends the XML representation of a list of a <code>Frontend</code> to a <code>Node</code> using the
1137         * <code>namespace</code>.
1138         * 
1139         * @param toNode
1140         *            the <code>Node</code> to append the new element to
1141         * @param fEnd
1142         *            the <code>Frontend</code> to be appended as new element
1143         * 
1144         */
1145        protected static void appendFrontend( Node toNode, Frontend fEnd ) {
1146    
1147            if ( fEnd != null ) {
1148                Element e = createElement( D_CONTEXT_NS, "deegree:Frontend" );
1149    
1150                e.setAttribute( "scope", "JSP" );
1151                if ( fEnd.getController() != null ) {
1152                    Element c = createElement( D_CONTEXT_NS, "deegree:Controller" );
1153                    c.appendChild( createTextNode( fEnd.getController() ) );
1154                    e.appendChild( c );
1155                }
1156                if ( ( (JSPFrontend) fEnd ).getStyle() != null ) {
1157                    Element c = createElement( D_CONTEXT_NS, "deegree:Style" );
1158                    c.appendChild( createTextNode( ( (JSPFrontend) fEnd ).getStyle() ) );
1159                    e.appendChild( c );
1160                }
1161                if ( ( (JSPFrontend) fEnd ).getHeader() != null ) {
1162                    Element c = createElement( D_CONTEXT_NS, "deegree:Header" );
1163                    c.appendChild( createTextNode( ( (JSPFrontend) fEnd ).getHeader() ) );
1164                    e.appendChild( c );
1165                }
1166                if ( ( (JSPFrontend) fEnd ).getFooter() != null ) {
1167                    Element c = createElement( D_CONTEXT_NS, "deegree:Footer" );
1168                    c.appendChild( createTextNode( ( (JSPFrontend) fEnd ).getFooter() ) );
1169                    e.appendChild( c );
1170                }
1171    
1172                appendCommonJS( e, ( (JSPFrontend) fEnd ).getCommonJS() );
1173    
1174                appendButtons( e, ( (JSPFrontend) fEnd ).getButtons() );
1175    
1176                appendGUIArea( e, fEnd.getNorth(), "deegree:North" );
1177                appendGUIArea( e, fEnd.getWest(), "deegree:West" );
1178                appendGUIArea( e, fEnd.getCenter(), "deegree:Center" );
1179                appendGUIArea( e, fEnd.getEast(), "deegree:East" );
1180                appendGUIArea( e, fEnd.getSouth(), "deegree:South" );
1181    
1182                toNode.appendChild( e );
1183            }
1184    
1185        }
1186    
1187        /**
1188         * Appends the XML representation of a list of a <code>String[]</code> to a <code>Node</code> using the
1189         * <code>namespace</code>.
1190         * 
1191         * @param toNode
1192         *            the <code>Node</code> to append the new element to
1193         * @param commonJS
1194         *            the <code>String[]</code> to be appended as new element
1195         * 
1196         */
1197        protected static void appendCommonJS( Node toNode, String[] commonJS ) {
1198    
1199            if ( commonJS != null ) {
1200                Element c = createElement( D_CONTEXT_NS, "deegree:CommonJS" );
1201    
1202                for ( int i = 0; i < commonJS.length; i++ ) {
1203                    if ( commonJS[i] != null ) {
1204                        Element n = createElement( D_CONTEXT_NS, "deegree:Name" );
1205                        n.appendChild( createTextNode( commonJS[i] ) );
1206                        c.appendChild( n );
1207                    }
1208                }
1209                toNode.appendChild( c );
1210            }
1211    
1212        }
1213    
1214        /**
1215         * Appends the XML representation of a list of a <code>String</code> to a <code>Node</code> using the
1216         * <code>namespace</code>. // TODO
1217         * 
1218         * @param toNode
1219         *            the <code>Node</code> to append the new element to
1220         * @param buttons
1221         *            the <code>String</code> to be appended as new element
1222         * 
1223         */
1224        protected static void appendButtons( Node toNode, String buttons ) {
1225    
1226            if ( buttons != null ) {
1227                Element b = createElement( D_CONTEXT_NS, "deegree:Buttons" );
1228                b.appendChild( createTextNode( buttons ) );
1229    
1230                toNode.appendChild( b );
1231            }
1232    
1233        }
1234    
1235        /**
1236         * Appends the XML representation of a list of a <code>GUIArea</code> to a <code>Node</code> using the
1237         * <code>namespace</code>.
1238         * 
1239         * @param toNode
1240         *            the <code>Node</code> to append the new element to
1241         * @param guiArea
1242         *            the <code>GUIArea</code> to be appended as new element
1243         * @param name
1244         * 
1245         */
1246        protected static void appendGUIArea( Node toNode, GUIArea guiArea, String name ) {
1247    
1248            if ( guiArea != null ) {
1249                Element e = createElement( D_CONTEXT_NS, name );
1250                e.setAttribute( "hidden", String.valueOf( guiArea.isHidden() ) );
1251                if ( guiArea.getWidth() > 0 ) {
1252                    e.setAttribute( "width", String.valueOf( guiArea.getWidth() ) );
1253                }
1254                if ( guiArea.getHeight() > 0 ) {
1255                    e.setAttribute( "height", String.valueOf( guiArea.getHeight() ) );
1256                }
1257                if ( guiArea.getTop() > -1 ) {
1258                    e.setAttribute( "top", String.valueOf( guiArea.getTop() ) );
1259                }
1260                if ( guiArea.getRight() > 0 ) {
1261                    e.setAttribute( "right", String.valueOf( guiArea.getRight() ) );
1262                }
1263                if ( guiArea.getLeft() > -1 ) {
1264                    e.setAttribute( "left", String.valueOf( guiArea.getLeft() ) );
1265                }
1266                if ( guiArea.getBottom() > 0 ) {
1267                    e.setAttribute( "bottom", String.valueOf( guiArea.getBottom() ) );
1268                }
1269                e.setAttribute( "closable", String.valueOf( guiArea.isClosable() ).toLowerCase() );
1270                e.setAttribute( "header", String.valueOf( guiArea.hasHeader() ).toLowerCase() );
1271                e.setAttribute( "overlay", String.valueOf( guiArea.isOverlay() ).toLowerCase() );
1272    
1273                Module[] mods = guiArea.getModules();
1274                if ( mods != null ) {
1275                    for ( int i = 0; i < mods.length; i++ ) {
1276                        if ( mods[i] != null ) {
1277                            appendModule( e, mods[i] );
1278                        }
1279                    }
1280                }
1281    
1282                toNode.appendChild( e );
1283            }
1284    
1285        }
1286    
1287        /**
1288         * Appends the XML representation of a list of a <code>GUIArea</code> to a <code>Node</code> using the
1289         * <code>namespace</code>.
1290         * 
1291         * @param toNode
1292         *            the <code>Node</code> to append the new element to
1293         * @param mod
1294         * 
1295         */
1296        protected static void appendModule( Node toNode, Module mod ) {
1297    
1298            if ( mod != null ) {
1299                Element m = createElement( D_CONTEXT_NS, "deegree:Module" );
1300                m.setAttribute( "hidden", String.valueOf( mod.isHidden() ) );
1301    
1302                m.setAttribute( "type", mod.getType() );
1303                m.setAttribute( "scrolling", String.valueOf( mod.getScrolling() ) );
1304                if ( mod.getWidth() > 0 ) {
1305                    m.setAttribute( "width", String.valueOf( mod.getWidth() ) );
1306                }
1307                if ( mod.getHeight() > 0 ) {
1308                    m.setAttribute( "height", String.valueOf( mod.getHeight() ) );
1309                }
1310                if ( mod.getTop() > -1 ) {
1311                    m.setAttribute( "top", String.valueOf( mod.getTop() ) );
1312                }
1313                if ( mod.getRight() > 0 ) {
1314                    m.setAttribute( "right", String.valueOf( mod.getRight() ) );
1315                }
1316                if ( mod.getLeft() > -1 ) {
1317                    m.setAttribute( "left", String.valueOf( mod.getLeft() ) );
1318                }
1319                if ( mod.getBottom() > 0 ) {
1320                    m.setAttribute( "bottom", String.valueOf( mod.getBottom() ) );
1321                }
1322                m.setAttribute( "closeable", String.valueOf( mod.isClosable() ).toLowerCase() );
1323                m.setAttribute( "header", String.valueOf( mod.hasHeader() ).toLowerCase() );
1324                m.setAttribute( "overlay", String.valueOf( mod.isOverlay() ).toLowerCase() );
1325                m.setAttribute( "collapsed", String.valueOf( mod.isCollapsed() ).toLowerCase() );
1326    
1327                Element n = createElement( D_CONTEXT_NS, "deegree:Name" );
1328                n.appendChild( createTextNode( mod.getName() ) );
1329                m.appendChild( n );
1330    
1331                n = createElement( D_CONTEXT_NS, "deegree:Title" );
1332                n.appendChild( createTextNode( mod.getTitle() ) );
1333                m.appendChild( n );
1334    
1335                n = createElement( D_CONTEXT_NS, "deegree:Content" );
1336                n.appendChild( createTextNode( mod.getContent() ) );
1337                m.appendChild( n );
1338    
1339                appendModuleJSList( m, mod.getModuleJSList() );
1340                appendModuleConfiguration( m, mod.getModuleConfiguration() );
1341                appendParameterList( m, mod.getParameter() );
1342    
1343                toNode.appendChild( m );
1344            }
1345    
1346        }
1347    
1348        /**
1349         * Appends the XML representation of a list of a <code>ModuleConfiguration</code> to a <code>Node</code> using the
1350         * <code>namespace</code>.
1351         * 
1352         * @param toNode
1353         *            the <code>Node</code> to append the new element to
1354         * @param modConf
1355         *            the <code>ModuleConfiguration</code> to be appended as new element
1356         * 
1357         */
1358        protected static void appendModuleConfiguration( Node toNode, ModuleConfiguration modConf ) {
1359    
1360            if ( modConf != null && modConf.getOnlineResource() != null ) {
1361                Element e = createElement( D_CONTEXT_NS, "deegree:ModuleConfiguration" );
1362                appendOnlineResource( e, modConf.getOnlineResource() );
1363                toNode.appendChild( e );
1364            }
1365    
1366        }
1367    
1368        /**
1369         * Appends the XML representation of a list of a <code>ParameterList</code> to a <code>Node</code> using the
1370         * <code>namespace</code>.
1371         * 
1372         * @param toNode
1373         *            the <code>Node</code> to append the new element to
1374         * @param parList
1375         *            the <code>ParameterList</code> to be appended as new element
1376         * 
1377         */
1378        protected static void appendParameterList( Node toNode, ParameterList parList ) {
1379    
1380            if ( parList != null && parList.getParameters().length > 0 ) {
1381    
1382                Element e = createElement( D_CONTEXT_NS, "deegree:ParameterList" );
1383    
1384                Parameter[] pars = parList.getParameters();
1385                for ( int i = 0; i < pars.length; i++ ) {
1386                    if ( pars[i] != null ) {
1387                        Element p = createElement( D_CONTEXT_NS, "deegree:Parameter" );
1388    
1389                        Element n = createElement( D_CONTEXT_NS, "deegree:Name" );
1390                        String name = pars[i].getName();
1391                        // name = name.substring(0,name.indexOf(':'));
1392                        n.appendChild( createTextNode( name ) );
1393                        p.appendChild( n );
1394    
1395                        n = createElement( D_CONTEXT_NS, "deegree:Value" );
1396                        n.appendChild( createTextNode( pars[i].getValue().toString() ) );
1397                        p.appendChild( n );
1398    
1399                        e.appendChild( p );
1400                    }
1401                }
1402                toNode.appendChild( e );
1403            }
1404    
1405        }
1406    
1407        /**
1408         * Appends the XML representation of a list of a <code>MapParameter</code> to a <code>Node</code> using the
1409         * <code>namespace</code>.
1410         * 
1411         * @param toNode
1412         *            the <code>Node</code> to append the new element to
1413         * @param mapPar
1414         *            the <code>MapParameter</code> to be appended as new element
1415         * 
1416         */
1417        protected static void appendMapParameter( Node toNode, MapParameter mapPar ) {
1418    
1419            if ( mapPar != null ) {
1420                Element e = createElement( D_CONTEXT_NS, "deegree:MapParameter" );
1421    
1422                Element f = createElement( D_CONTEXT_NS, "deegree:OfferedInfoFormats" );
1423                appendFormats( f, mapPar.getOfferedInfoFormats() );
1424                e.appendChild( f );
1425    
1426                appendMapOperationFactors( e, mapPar.getOfferedZoomFactors(), "deegree:OfferedZoomFactor" );
1427                appendMapOperationFactors( e, mapPar.getOfferedPanFactors(), "deegree:OfferedPanFactor" );
1428    
1429                Element minScale = createElement( D_CONTEXT_NS, "deegree:MinScale" );
1430                minScale.appendChild( createTextNode( String.valueOf( mapPar.getMinScale() ) ) );
1431                e.appendChild( minScale );
1432    
1433                Element maxScale = createElement( D_CONTEXT_NS, "deegree:MaxScale" );
1434                maxScale.appendChild( createTextNode( String.valueOf( mapPar.getMaxScale() ) ) );
1435                e.appendChild( maxScale );
1436    
1437                toNode.appendChild( e );
1438            }
1439    
1440        }
1441    
1442        /**
1443         * Appends the XML representation of a list of a <code>Format[]</code> to a <code>Node</code> using the
1444         * <code>namespace</code>.
1445         * 
1446         * @param toNode
1447         *            the <code>Node</code> to append the new element to
1448         * @param formats
1449         *            the <code>Format[]</code> to be appended as new element
1450         * 
1451         */
1452        protected static void appendFormats( Node toNode, Format[] formats ) {
1453    
1454            if ( formats != null ) {
1455                for ( int i = 0; i < formats.length; i++ ) {
1456                    if ( formats[i] != null ) {
1457                        Element f = createElement( D_CONTEXT_NS, "deegree:Format" );
1458    
1459                        // TODO is current or selected?
1460                        if ( formats[i].isCurrent() ) {
1461                            f.setAttribute( "selected", String.valueOf( formats[i].isCurrent() ) );
1462                        }
1463    
1464                        f.appendChild( createTextNode( formats[i].getName() ) );
1465                        toNode.appendChild( f );
1466                    }
1467                }
1468            }
1469    
1470        }
1471    
1472        /**
1473         * Appends the XML representation of a list of a <code>MapOperationFactor</code> to a <code>Node</code> using the
1474         * <code>namespace</code>.
1475         * 
1476         * @param toNode
1477         *            the <code>Node</code> to append the new element to
1478         * @param mapOpFac
1479         *            the <code>MapOperationFactor</code> to be appended as new element
1480         * @param opName
1481         * 
1482         */
1483        protected static void appendMapOperationFactors( Node toNode, MapOperationFactor[] mapOpFac, String opName ) {
1484    
1485            if ( mapOpFac != null ) {
1486                for ( int i = 0; i < mapOpFac.length; i++ ) {
1487                    if ( mapOpFac[i] != null ) {
1488    
1489                        Element mof = createElement( D_CONTEXT_NS, opName );
1490                        Element f = createElement( D_CONTEXT_NS, "deegree:Factor" );
1491                        f.appendChild( createTextNode( String.valueOf( mapOpFac[i].getFactor() ) ) );
1492    
1493                        if ( mapOpFac[i].isSelected() ) {
1494                            f.setAttribute( "selected", String.valueOf( mapOpFac[i].isSelected() ) );
1495                        }
1496    
1497                        // TODO isFree ???
1498    
1499                        mof.appendChild( f );
1500                        toNode.appendChild( mof );
1501                    }
1502                }
1503            }
1504    
1505        }
1506    
1507        /**
1508         * Appends the XML representation of a list of a <code>LayerExtension</code> to a <code>Node</code> using the
1509         * <code>namespace</code>.
1510         * 
1511         * @param toNode
1512         *            the <code>Node</code> to append the new element to
1513         * @param layExt
1514         *            the <code>LayerExtension</code> to be appended as new element
1515         * 
1516         */
1517        protected static void appendLayerExtension( Node toNode, LayerExtension layExt ) {
1518    
1519            if ( layExt != null ) {
1520                Element e = createElement( OGC_CONTEXT_NS, "Extension" );
1521    
1522                appendDataService( e, layExt.getDataService() );
1523    
1524                Element g = createElement( D_CONTEXT_NS, "deegree:MasterLayer" );
1525                g.appendChild( createTextNode( String.valueOf( layExt.isMasterLayer() ) ) );
1526                e.appendChild( g );
1527    
1528                g = createElement( D_CONTEXT_NS, "deegree:ScaleHint" );
1529                g.setAttribute( "min", "" + layExt.getMinScaleHint() );
1530                g.setAttribute( "max", "" + layExt.getMaxScaleHint() );
1531                e.appendChild( g );
1532    
1533                g = createElement( D_CONTEXT_NS, "deegree:parentNodeId" );
1534                g.appendChild( createTextNode( String.valueOf( layExt.getParentNodeId() ) ) );
1535                e.appendChild( g );
1536    
1537                g = createElement( D_CONTEXT_NS, "deegree:SelectedForQuery" );
1538                g.appendChild( createTextNode( String.valueOf( layExt.isSelectedForQuery() ) ) );
1539                e.appendChild( g );
1540    
1541                if ( layExt.getIdentifier() != null ) {
1542                    g = createElement( D_CONTEXT_NS, "deegree:identifier" );
1543                    g.appendChild( createTextNode( String.valueOf( layExt.getIdentifier() ) ) );
1544                    e.appendChild( g );
1545                }
1546    
1547                g = createElement( D_CONTEXT_NS, "deegree:UseAuthentication" );
1548                // System.out.println(layExt.getAuthentication());
1549                if ( layExt.getAuthentication() == LayerExtension.SESSIONID ) {
1550                    g.appendChild( createTextNode( "sessionID" ) );
1551                } else if ( layExt.getAuthentication() == LayerExtension.USERPASSWORD ) {
1552                    g.appendChild( createTextNode( "user/password" ) );
1553                } else if ( layExt.getAuthentication() == LayerExtension.NONE ) {
1554                    g.appendChild( createTextNode( "none" ) );
1555                }
1556                e.appendChild( g );
1557    
1558                toNode.appendChild( e );
1559            }
1560    
1561        }
1562    
1563        /**
1564         * Appends the XML representation of a list of a <code>DataService</code> to a <code>Node</code> using the
1565         * <code>namespace</code>.
1566         * 
1567         * @param toNode
1568         *            the <code>Node</code> to append the new element to
1569         * @param dataServ
1570         *            the <code>DataService</code> to be appended as new element
1571         * 
1572         */
1573        protected static void appendDataService( Node toNode, DataService dataServ ) {
1574    
1575            if ( dataServ != null ) {
1576                Element e = createElement( D_CONTEXT_NS, "deegree:DataService" );
1577    
1578                if ( dataServ.getServer() != null ) {
1579                    appendServer( e, dataServ.getServer() );
1580                }
1581                String geoType = dataServ.getGeometryType();
1582                if ( geoType != null ) {
1583                    Element g = createElement( D_CONTEXT_NS, "deegree:GeometryType" );
1584                    g.appendChild( createTextNode( dataServ.getGeometryType() ) );
1585                    e.appendChild( g );
1586                }
1587                String featType = dataServ.getFeatureType();
1588                if ( featType != null ) {
1589                    Element g = createElement( D_CONTEXT_NS, "deegree:FeatureType" );
1590                    g.appendChild( createTextNode( featType ) );
1591                    e.appendChild( g );
1592                }
1593    
1594                toNode.appendChild( e );
1595            }
1596    
1597        }
1598    
1599        /**
1600         * Appends the XML representation of a list of a <code>ParameterList</code> to a <code>Node</code> using the
1601         * <code>namespace</code>.
1602         * 
1603         * @param toNode
1604         *            the <code>Node</code> to append the new element to
1605         * @param modJSList
1606         *            the <code>modJSList</code> to be appended as new element
1607         * 
1608         */
1609        protected static void appendModuleJSList( Node toNode, String[] modJSList ) {
1610    
1611            if ( modJSList != null && modJSList.length > 0 ) {
1612    
1613                for ( int i = 0; i < modJSList.length; i++ ) {
1614                    if ( modJSList[i] != null ) {
1615                        Element p = createElement( D_CONTEXT_NS, "deegree:ModuleJS" );
1616                        p.appendChild( createTextNode( modJSList[i] ) );
1617    
1618                        toNode.appendChild( p );
1619                    }
1620                }
1621            }
1622    
1623        }
1624    
1625    }