001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/owscommon_1_1_0/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.owscommon_1_1_0;
038    
039    import static org.deegree.framework.xml.XMLTools.appendElement;
040    import static org.deegree.framework.xml.XMLTools.create;
041    import static org.deegree.ogcbase.CommonNamespaces.OWSNS;
042    import static org.deegree.ogcbase.CommonNamespaces.OWSNS_1_1_0;
043    import static org.deegree.ogcbase.CommonNamespaces.OWS_1_1_0PREFIX;
044    import static org.deegree.ogcbase.CommonNamespaces.XLINK_PREFIX;
045    
046    import java.io.UnsupportedEncodingException;
047    import java.net.URLEncoder;
048    import java.util.List;
049    
050    import org.deegree.framework.util.CharsetUtils;
051    import org.deegree.framework.util.Pair;
052    import org.deegree.framework.xml.XMLFragment;
053    import org.deegree.framework.xml.XMLTools;
054    import org.deegree.ogcbase.ExceptionCode;
055    import org.deegree.ogcwebservices.OGCWebServiceException;
056    import org.w3c.dom.Document;
057    import org.w3c.dom.Element;
058    import org.w3c.dom.Node;
059    
060    /**
061     * The <code>XMLFactory</code> is a convenience class, which exports ows-common 1.1.0 beans to their xml
062     * representation.
063     *
064     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
065     *
066     * @author last edited by: $Author: mschneider $
067     *
068     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
069     *
070     */
071    
072    public class XMLFactory extends org.deegree.ogcbase.XMLFactory {
073    
074        private static String PRE = OWS_1_1_0PREFIX + ":";
075    
076        /**
077         * make an xml representation of given capabilities bean.
078         *
079         * @param root
080         *            to export to.
081         * @param capabilities
082         *            to export
083         */
084        public void exportCapabilities( Element root, OWSCommonCapabilities capabilities ) {
085            if ( root != null && capabilities != null ) {
086                root.setAttribute( "version", capabilities.getVersion() );
087                root.setAttribute( "updateSequence", capabilities.getUpdateSequence() );
088                appendServiceIdentification( root, capabilities.getServiceIdentification() );
089                appendServiceProvider( root, capabilities.getServiceProvider() );
090                appendOperationsMetadata( root, capabilities.getOperationsMetadata() );
091            }
092        }
093    
094        /**
095         * Will create an XMLFragment which holds the ows:OperationResponse as the root element, values from the given
096         * manifest will be appended.
097         *
098         * @param operationResponse
099         *            to create the dom-xml representation from.
100         * @return the xmlFragment as defined in ows 1.1.0 or <code>null</code> if the given parameter is
101         *         <code>null</code>.
102         */
103        public XMLFragment createOperationResponse( Manifest operationResponse ) {
104            if ( operationResponse == null ) {
105                return null;
106            }
107            Document doc = create();
108            Element root = doc.createElementNS( OWSNS_1_1_0.toASCIIString(), PRE + "OperationResponse" );
109            appendManifest( root, operationResponse );
110            return new XMLFragment( root );
111        }
112    
113        /**
114         * Exports the manifest type to its dom-xml representation. If either one of the params is <code>null</code>
115         * nothing is done.
116         *
117         * @param root
118         *            to append the manifest values to.
119         * @param manifestType
120         *            to export.
121         */
122        public void appendManifest( Element root, Manifest manifestType ) {
123            if ( root != null && manifestType != null ) {
124                BasicIdentification basicIdentification = manifestType.getBasicManifestIdentification();
125                appendBasicIdentification( root, basicIdentification );
126                List<ReferenceGroup> referenceGroups = manifestType.getReferenceGroups();
127                if ( referenceGroups != null && referenceGroups.size() > 0 ) {
128                    for ( ReferenceGroup referenceGroup : referenceGroups ) {
129                        if ( referenceGroup != null ) {
130                            Element rgElement = appendElement( root, OWSNS_1_1_0, PRE + "ReferenceGroup" );
131                            appendBasicIdentification( rgElement, referenceGroup.getBasicRGId() );
132                            List<Reference> references = referenceGroup.getReferences();
133                            if ( references.size() > 0 ) {
134                                for ( Reference reference : references ) {
135                                    appendReference( rgElement, reference );
136                                }
137                            }
138                        }
139                    }
140                }
141            }
142    
143        }
144    
145        /**
146         * Appends the given reference to the given root. If either one of the params is <code>null</code> nothing is
147         * done.
148         *
149         * @param root
150         *            to append too.
151         * @param reference
152         *            to append.
153         */
154        protected void appendReference( Element root, Reference reference ) {
155            if ( root != null && reference != null ) {
156                Element refElement = appendElement( root, OWSNS_1_1_0, PRE + "Reference" );
157                String attrib = reference.getHrefAttribute();
158                if ( attrib != null && !"".equals( attrib.trim() ) ) {
159                    refElement.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", attrib );
160                }
161                attrib = reference.getRoleAttribute();
162                if ( attrib != null && !"".equals( attrib.trim() ) ) {
163                    refElement.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":role", attrib );
164                }
165                attrib = reference.getTypeAttribute();
166                if ( attrib != null && !"".equals( attrib.trim() ) ) {
167                    refElement.setAttributeNS( OWSNS_1_1_0.toASCIIString(), PRE + "type", attrib );
168                }
169                Pair<String, String> identifier = reference.getIdentifier();
170                if ( identifier != null ) {
171                    Element t = appendElement( refElement, OWSNS_1_1_0, PRE + "Identifier", identifier.first );
172                    if ( identifier.second != null ) {
173                        t.setAttribute( "codeSpace", identifier.second );
174                    }
175                }
176                appendAbstracts( refElement, reference.getAbstracts() );
177                String format = reference.getFormat();
178                if ( format != null && !"".equals( format.trim() ) ) {
179                    appendElement( refElement, OWSNS_1_1_0, PRE + "Format", format );
180                }
181                appendMetadataAttribs( refElement, reference.getMetadatas() );
182            }
183    
184        }
185    
186        /**
187         * Appends the given basicIdentification to the given root. If either one of the params is <code>null</code>
188         * nothing is done.
189         *
190         * @param root
191         *            to append too.
192         * @param basicIdentification
193         *            to append.
194         */
195        protected void appendBasicIdentification( Element root, BasicIdentification basicIdentification ) {
196            if ( root != null && basicIdentification != null ) {
197                appendTitles( root, basicIdentification.getTitles() );
198                appendAbstracts( root, basicIdentification.getAbstracts() );
199                appendKeywords( root, basicIdentification.getKeywords() );
200    
201                Pair<String, String> identifier = basicIdentification.getIdentifier();
202                if ( identifier != null ) {
203                    Element t = appendElement( root, OWSNS_1_1_0, PRE + "Identifier", identifier.first );
204                    if ( identifier.second != null ) {
205                        t.setAttribute( "codeSpace", identifier.second );
206                    }
207                }
208    
209                appendMetadataAttribs( root, basicIdentification.getMetadatas() );
210            }
211        }
212    
213        /**
214         * @param capabilitiesElement
215         *            to export to if <code>null</code> nothing will be done.
216         * @param serviceIdentification
217         *            to append if <code>null</code> nothing will be done (optional).
218         */
219        protected void appendServiceIdentification( Element capabilitiesElement, ServiceIdentification serviceIdentification ) {
220            if ( capabilitiesElement == null || serviceIdentification == null ) {
221                return;
222            }
223            Element sid = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "ServiceIdentification" );
224            List<String> strings = serviceIdentification.getTitles();
225            if ( strings != null ) {
226                appendTitles( sid, strings );
227            }
228    
229            strings = serviceIdentification.getAbstracts();
230            if ( strings != null ) {
231                appendAbstracts( sid, strings );
232            }
233    
234            List<Keywords> keywords = serviceIdentification.getKeywords();
235            if ( keywords != null ) {
236                appendKeywords( sid, keywords );
237            }
238    
239            // ServiceType mandatory
240            Pair<String, String> serviceType = serviceIdentification.getServicetype();
241            Element ste = appendElement( sid, OWSNS_1_1_0, PRE + "ServiceType", serviceType.first );
242            if ( serviceType.second != null ) {
243                ste.setAttribute( "codeSpace", serviceType.second );
244            }
245    
246            // ServiceTypeVersion(s) mandatory.
247            List<String> serviceTypeVersions = serviceIdentification.getServiceTypeVersions();
248            for ( String serviceTypeVersion : serviceTypeVersions ) {
249                appendElement( sid, OWSNS_1_1_0, PRE + "ServiceTypeVersion", serviceTypeVersion );
250            }
251    
252            List<String> profiles = serviceIdentification.getProfiles();
253            for ( String profile : profiles ) {
254                appendElement( sid, OWSNS_1_1_0, PRE + "Profile", profile );
255            }
256    
257            String fee = serviceIdentification.getFees();
258            if ( fee != null && !"".equals( fee.trim() ) ) {
259                appendElement( sid, OWSNS_1_1_0, PRE + "Fees", fee );
260            }
261    
262            List<String> accessConst = serviceIdentification.getAccessConstraints();
263            if ( accessConst != null ) {
264                for ( String constraint : accessConst ) {
265                    appendElement( sid, OWSNS_1_1_0, PRE + "AccessConstraints", constraint );
266                }
267            }
268    
269        }
270    
271        /**
272         * Appends the given titles to the given root. If either one of the params is <code>null</code> nothing is done.
273         *
274         * @param root
275         *            to append too.
276         * @param titles
277         *            to append.
278         */
279        protected void appendTitles( Element root, List<String> titles ) {
280            if ( root != null && titles != null ) {
281                for ( String title : titles ) {
282                    if ( title != null && !"".equals( title.trim() ) ) {
283                        appendElement( root, OWSNS_1_1_0, PRE + "Title", title );
284                    }
285                }
286            }
287        }
288    
289        /**
290         * Appends the given abstracts to the given root. If either one of the params is <code>null</code> nothing is
291         * done.
292         *
293         * @param root
294         *            to append too.
295         * @param abstracts
296         *            to append.
297         */
298        protected void appendAbstracts( Element root, List<String> abstracts ) {
299            if ( root != null && abstracts != null ) {
300                for ( String string : abstracts ) {
301                    if ( string != null && !"".equals( string.trim() ) ) {
302                        appendElement( root, OWSNS_1_1_0, PRE + "Abstract", string );
303                    }
304                }
305            }
306        }
307    
308        /**
309         * Appends the given keywords to the given root. If either one of the params is <code>null</code> nothing is done.
310         *
311         * @param root
312         *            to append too.
313         * @param keywords
314         *            to append.
315         */
316        protected void appendKeywords( Element root, List<Keywords> keywords ) {
317            if ( root != null && keywords != null ) {
318                for ( Keywords kw : keywords ) {
319                    if ( kw != null ) {
320                        Element keywordsElement = appendElement( root, OWSNS_1_1_0, PRE + "Keywords" );
321                        List<String> kws = kw.getkeywords();
322                        if ( kws != null ) {
323                            for ( String s : kws ) {
324                                appendElement( keywordsElement, OWSNS_1_1_0, PRE + "Keyword", s );
325                            }
326                        }
327                        Pair<String, String> type = kw.getType();
328                        if ( type != null ) {
329                            Element t = appendElement( keywordsElement, OWSNS_1_1_0, PRE + "Type", type.first );
330                            if ( type.second != null ) {
331                                t.setAttribute( "codeSpace", type.second );
332                            }
333                        }
334                    }
335                }
336            }
337    
338        }
339    
340        /**
341         *
342         * @param capabilitiesElement
343         *            to export to if <code>null</code> nothing will be done.
344         * @param serviceProvider
345         *            to append if <code>null</code> nothing will be done (optional).
346         */
347        protected void appendServiceProvider( Element capabilitiesElement, ServiceProvider serviceProvider ) {
348            if ( capabilitiesElement == null || serviceProvider == null ) {
349                return;
350            }
351            Element sp = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "ServiceProvider" );
352            appendElement( sp, OWSNS_1_1_0, PRE + "ProviderName", serviceProvider.getProviderName() );
353            if ( serviceProvider.getProviderSite() != null && !"".equals( serviceProvider.getProviderSite() ) ) {
354                Element provSite = appendElement( sp, OWSNS_1_1_0, PRE + "ProviderSite" );
355                provSite.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", serviceProvider.getProviderSite() );
356            }
357    
358            appendServiceContact( sp, serviceProvider.getServiceContact() );
359    
360        }
361    
362        /**
363         * @param root
364         *            to export to if <code>null</code> nothing will be done.
365         * @param serviceContact
366         *            to append if <code>null</code> nothing will be done (optional).
367         */
368        protected void appendServiceContact( Element root, ServiceContact serviceContact ) {
369            if ( root == null || serviceContact == null ) {
370                return;
371            }
372            Element sc = appendElement( root, OWSNS_1_1_0, PRE + "ServiceContact" );
373            // optional IndividualName
374            if ( serviceContact.getIndividualName() != null && !"".equals( serviceContact.getIndividualName() ) ) {
375                appendElement( sc, OWSNS_1_1_0, PRE + "IndividualName", serviceContact.getIndividualName() );
376            }
377            // optional PositionName
378            if ( serviceContact.getPositionName() != null && !"".equals( serviceContact.getPositionName() ) ) {
379                appendElement( sc, OWSNS_1_1_0, PRE + "PositionName", serviceContact.getPositionName() );
380            }
381            // optional ContactInfo
382            appendContactInfo( sc, serviceContact.getContactInfo() );
383    
384            // optional Role.
385            if ( serviceContact.getRole() != null ) {
386                Element r = appendElement( sc, OWSNS_1_1_0, PRE + "Role", serviceContact.getRole().first );
387                if ( serviceContact.getRole().second != null ) {
388                    r.setAttribute( "codeSpace", serviceContact.getRole().second );
389                }
390            }
391    
392        }
393    
394        /**
395         * @param root
396         *            (usually a serviceContact) to export to if <code>null</code> nothing will be done.
397         * @param contactInfo
398         *            to append if <code>null</code> nothing will be done (optional).
399         */
400        protected void appendContactInfo( Element root, ContactInfo contactInfo ) {
401            if ( root == null || contactInfo == null ) {
402                return;
403            }
404            Element ci = appendElement( root, OWSNS_1_1_0, PRE + "ContactInfo" );
405            if ( contactInfo.getPhone() != null ) {
406                Pair<List<String>, List<String>> phone = contactInfo.getPhone();
407                Element phoneE = appendElement( ci, OWSNS_1_1_0, PRE + "Phone" );
408                if ( phone.first != null && phone.first.size() != 0 ) {
409                    for ( String t : phone.first ) {
410                        appendElement( phoneE, OWSNS_1_1_0, PRE + "Voice", t );
411                    }
412                }
413                if ( phone.second != null && phone.second.size() != 0 ) {
414                    for ( String t : phone.second ) {
415                        appendElement( phoneE, OWSNS_1_1_0, PRE + "Facsimile", t );
416                    }
417                }
418            }
419    
420            if ( contactInfo.hasAdress() ) {
421                Element addr = appendElement( ci, OWSNS_1_1_0, PRE + "Address" );
422                if ( contactInfo.getDeliveryPoint() != null ) {
423                    for ( String s : contactInfo.getDeliveryPoint() ) {
424                        appendElement( addr, OWSNS_1_1_0, PRE + "DeliveryPoint", s );
425                    }
426                }
427                if ( contactInfo.getCity() != null && !"".equals( contactInfo.getCity().trim() ) ) {
428                    appendElement( addr, OWSNS_1_1_0, PRE + "City", contactInfo.getCity().trim() );
429                }
430                if ( contactInfo.getAdministrativeArea() != null && !"".equals( contactInfo.getAdministrativeArea().trim() ) ) {
431                    appendElement( addr, OWSNS_1_1_0, PRE + "AdministrativeArea",
432                                   contactInfo.getAdministrativeArea().trim() );
433                }
434                if ( contactInfo.getPostalCode() != null && !"".equals( contactInfo.getPostalCode().trim() ) ) {
435                    appendElement( addr, OWSNS_1_1_0, PRE + "PostalCode", contactInfo.getPostalCode().trim() );
436                }
437                if ( contactInfo.getCountry() != null && !"".equals( contactInfo.getCountry().trim() ) ) {
438                    appendElement( addr, OWSNS_1_1_0, PRE + "Country", contactInfo.getCountry().trim() );
439                }
440                if ( contactInfo.getElectronicMailAddress() != null ) {
441                    for ( String s : contactInfo.getElectronicMailAddress() ) {
442                        appendElement( addr, OWSNS_1_1_0, PRE + "ElectronicMailAddress", s );
443                    }
444                }
445            }
446            if ( contactInfo.getOnlineResource() != null && !"".equals( contactInfo.getOnlineResource().trim() ) ) {
447                Element onlineResource = appendElement( ci, OWSNS_1_1_0, PRE + "OnlineResource" );
448                onlineResource.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href",
449                                               contactInfo.getOnlineResource().trim() );
450            }
451    
452            if ( contactInfo.getHoursOfService() != null && !"".equals( contactInfo.getHoursOfService().trim() ) ) {
453                appendElement( ci, OWSNS_1_1_0, PRE + "HoursOfService", contactInfo.getHoursOfService().trim() );
454            }
455    
456            if ( contactInfo.getContactInstructions() != null && !"".equals( contactInfo.getContactInstructions().trim() ) ) {
457                appendElement( ci, OWSNS_1_1_0, PRE + "ContactInstructions", contactInfo.getContactInstructions().trim() );
458            }
459        }
460    
461        /**
462         * @param capabilitiesElement
463         *            to export to if <code>null</code> nothing will be done.
464         * @param operationsMetadata
465         *            to append if <code>null</code> nothing will be done (optional).
466         */
467        public void appendOperationsMetadata( Element capabilitiesElement, OperationsMetadata operationsMetadata ) {
468            if ( capabilitiesElement == null || operationsMetadata == null ) {
469                return;
470            }
471            Element omd = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "OperationsMetadata" );
472            appendOperations( omd, operationsMetadata.getOperations() );
473            if ( operationsMetadata.getParameters() != null ) {
474                for ( DomainType domainType : operationsMetadata.getParameters() ) {
475                    Element parameter = appendElement( omd, OWSNS_1_1_0, PRE + "Parameter" );
476                    appendDomainType( parameter, domainType );
477                }
478            }
479    
480            if ( operationsMetadata.getConstraints() != null ) {
481                for ( DomainType domainType : operationsMetadata.getConstraints() ) {
482                    Element constraint = appendElement( omd, OWSNS_1_1_0, PRE + "Constraint" );
483                    appendDomainType( constraint, domainType );
484                }
485            }
486            if ( operationsMetadata.getExtendedCapabilities() != null ) {
487                Node tmp = omd.getOwnerDocument().importNode( operationsMetadata.getExtendedCapabilities(), true );
488                omd.appendChild( tmp );
489            }
490        }
491    
492        /**
493         * @param root
494         *            to append to.
495         * @param operations
496         *            may not be <code>null</code>
497         * @throws IllegalArgumentException
498         *             if the list of operations &lt; 2 or <code>null</code>.
499         */
500        protected void appendOperations( Element root, List<Operation> operations )
501                                throws IllegalArgumentException {
502            if ( root == null ) {
503                return;
504            }
505            if ( operations == null || operations.size() < 2 ) {
506                throw new IllegalArgumentException( "The list of operations must at least contain 2 operations." );
507            }
508            for ( Operation operation : operations ) {
509                Element opElement = appendElement( root, OWSNS_1_1_0, PRE + "Operation" );
510                List<Pair<String, List<DomainType>>> getURLs = operation.getGetURLs();
511                List<Pair<String, List<DomainType>>> postURLs = operation.getPostURLs();
512                Element dcp = appendElement( opElement, OWSNS_1_1_0, PRE + "DCP" );
513                Element httpElement = appendElement( dcp, OWSNS_1_1_0, PRE + "HTTP" );
514                if ( getURLs != null ) {
515                    for ( Pair<String, List<DomainType>> getURL : getURLs ) {
516                        Element get = appendElement( httpElement, OWSNS_1_1_0, PRE + "Get" );
517                        if ( getURL.first != null ) {
518                            get.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", getURL.first );
519                        }
520                        if ( getURL.second != null && getURL.second.size() > 0 ) {
521                            Element constraint = appendElement( get, OWSNS_1_1_0, PRE + "Constraint" );
522                            for ( DomainType domainType : getURL.second ) {
523                                appendDomainType( constraint, domainType );
524                            }
525                        }
526                    }
527                }
528                if ( postURLs != null ) {
529                    for ( Pair<String, List<DomainType>> postURL : postURLs ) {
530                        Element post = appendElement( httpElement, OWSNS_1_1_0, PRE + "Post" );
531                        if ( postURL.first != null ) {
532                            post.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href", postURL.first );
533                        }
534                        if ( postURL.second != null && postURL.second.size() > 0 ) {
535                            Element constraint = appendElement( post, OWSNS_1_1_0, PRE + "Constraint" );
536                            for ( DomainType domainType : postURL.second ) {
537                                appendDomainType( constraint, domainType );
538                            }
539                        }
540                    }
541                }
542    
543                if ( operation.getParameters() != null ) {
544                    for ( DomainType domainType : operation.getParameters() ) {
545                        Element parameter = appendElement( opElement, OWSNS_1_1_0, PRE + "Parameter" );
546                        appendDomainType( parameter, domainType );
547                    }
548                }
549    
550                if ( operation.getConstraints() != null ) {
551                    for ( DomainType domainType : operation.getConstraints() ) {
552                        Element constraint = appendElement( opElement, OWSNS_1_1_0, PRE + "Constraint" );
553                        appendDomainType( constraint, domainType );
554                    }
555                }
556                if ( operation.getMetadataAttribs() != null && operation.getMetadataAttribs().size() > 0 ) {
557                    appendMetadataAttribs( opElement, operation.getMetadataAttribs() );
558                }
559                opElement.setAttribute( "name", operation.getName() );
560            }
561    
562        }
563    
564        /**
565         * @param domainTypeElement
566         *            to append the domainttype element to.
567         * @param domainType
568         *            to append.
569         */
570        protected void appendDomainType( Element domainTypeElement, DomainType domainType ) {
571            if ( domainTypeElement == null || domainType == null ) {
572                return;
573            }
574            domainTypeElement.setAttribute( "name", domainType.getName() );
575            if ( domainType.hasAllowedValues() ) {
576                Element allowedValuesElem = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "AllowedValues" );
577                List<String> values = domainType.getValues();
578                if ( values != null ) {
579                    for ( String value : values ) {
580                        appendElement( allowedValuesElem, OWSNS_1_1_0, PRE + "Value", value );
581                    }
582                }
583                List<Range> ranges = domainType.getRanges();
584                if ( ranges != null ) {
585                    for ( Range r : ranges ) {
586                        Element re = appendElement( allowedValuesElem, OWSNS_1_1_0, PRE + "Range" );
587                        if ( r.getMinimumValue() != null && !"".equals( r.getMinimumValue().trim() ) ) {
588                            appendElement( re, OWSNS_1_1_0, PRE + "MinimumValue", r.getMinimumValue() );
589                        }
590                        if ( r.getMaximumValue() != null && !"".equals( r.getMaximumValue().trim() ) ) {
591                            appendElement( re, OWSNS_1_1_0, PRE + "MaximumValue", r.getMaximumValue() );
592                        }
593                        if ( r.getSpacing() != null && !"".equals( r.getSpacing().trim() ) ) {
594                            appendElement( re, OWSNS_1_1_0, PRE + "Spacing", r.getSpacing() );
595                        }
596                        re.setAttribute( "rangeClosure", r.getRangeClosure() );
597                    }
598                }
599            } else if ( domainType.hasAnyValue() ) {
600                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "AnyValue" );
601            } else if ( domainType.hasNoValues() ) {
602                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "NoValues" );
603            } else { // a choice therefore this must be.
604                Element vref = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "ValuesReference",
605                                              domainType.getValuesReference().first );
606                if ( domainType.getValuesReference().second != null ) {
607                    vref.setAttribute( "reference", domainType.getValuesReference().second );
608                }
609            }
610            if ( domainType.getDefaultValue() != null && !"".equals( domainType.getDefaultValue() ) ) {
611                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "DefaultValue", domainType.getDefaultValue().trim() );
612            }
613            if ( domainType.getMeaning() != null ) {
614                Element tmp = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "Meaning", domainType.getMeaning().first );
615                if ( domainType.getMeaning().second != null ) {
616                    tmp.setAttribute( "reference", domainType.getMeaning().second );
617                }
618            }
619            if ( domainType.getDataType() != null ) {
620                Element tmp = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "DataType",
621                                             domainType.getDataType().first );
622                if ( domainType.getDataType().second != null ) {
623                    tmp.setAttribute( "reference", domainType.getDataType().second );
624                }
625            }
626            if ( domainType.hasValuesUnit() ) {
627                Element valuesUnit = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "ValuesUnit" );
628                if ( domainType.getUom() != null ) {
629                    Element tmp = appendElement( valuesUnit, OWSNS_1_1_0, PRE + "UOM", domainType.getUom().first );
630                    if ( domainType.getUom().second != null ) {
631                        tmp.setAttribute( "reference", domainType.getUom().second );
632                    }
633                } else {
634                    Element tmp = appendElement( valuesUnit, OWSNS_1_1_0, PRE + "ReferenceSystem",
635                                                 domainType.getReferenceSystem().first );
636                    if ( domainType.getReferenceSystem().second != null ) {
637                        tmp.setAttribute( "reference", domainType.getReferenceSystem().second );
638                    }
639                }
640            }
641            if ( domainType.getMetadataAttribs() != null && domainType.getMetadataAttribs().size() > 0 ) {
642                appendMetadataAttribs( domainTypeElement, domainType.getMetadataAttribs() );
643            }
644        }
645    
646        /**
647         * Appends the given metadata attributes to the given root. If either one of the params is <code>null</code>
648         * nothing is done.
649         *
650         * @param root
651         *            to append too.
652         * @param metadatasAttribs
653         *            to append. a list of &lt;xlink:href, about&gt; pairs.
654         */
655        protected void appendMetadataAttribs( Element root, List<Metadata> metadatasAttribs ) {
656            if ( root != null && metadatasAttribs != null ) {
657                for ( Metadata metadataElement : metadatasAttribs ) {
658                    if ( metadataElement != null ) {
659                        Element metadata = appendElement( root, OWSNS_1_1_0, PRE + "Metadata" );
660                        if ( metadataElement.getMetadataHref() != null ) {
661                            metadata.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX + ":href",
662                                                     metadataElement.getMetadataHref() );
663                        }
664                        if ( metadataElement.getMetadataAbout() != null ) {
665                            metadata.setAttribute( "about", metadataElement.getMetadataAbout() );
666                        }
667                        Element abst = metadataElement.getAbstractElement();
668                        if ( abst != null ) {
669                            Node n = metadata.getOwnerDocument().importNode( abst, true );
670                            metadata.appendChild( n );
671                        }
672                    }
673                }
674            }
675        }
676    
677        /**
678         * Creates an ows 1.1.0 xml-Representation of the given ExceptionReport.
679         *
680         * @param exception
681         *            containing the exceptions.
682         * @return a new ows_1_1_0:ExceptionReport document
683         */
684        public static XMLFragment exportException( OGCWebServiceException exception ) {
685    
686            Document doc = XMLTools.create();
687            Element root = doc.createElementNS( OWSNS_1_1_0.toASCIIString(), PRE + "ExceptionReport" );
688            root.setAttribute( "version", "1.1.0" );
689            XMLFragment result = new XMLFragment( root );
690            appendException( root, exception );
691    
692            return result;
693    
694        }
695    
696        /**
697         * Appends an xml representation of an <code>OGCWebServiceException</code> to the given <code>Element</code>.
698         * If either one is <code>null</code> this method just returns.
699         *
700         * @param root
701         *            the Element to append the exceptions to.
702         * @param exception
703         *            the Exception to append
704         */
705        protected static void appendException( Element root, OGCWebServiceException exception ) {
706            if ( root == null || exception == null ) {
707                return;
708            }
709            Element exceptionNode = XMLTools.appendElement( root, OWSNS_1_1_0, PRE + "Exception" );
710    
711            String exceptionCode = ExceptionCode.NOAPPLICABLECODE.value;
712            if ( exception.getCode() != null && exception.getCode().value != null
713                 && !"".equals( exception.getCode().value.trim() ) ) {
714                exceptionCode = exception.getCode().value;
715            }
716            exceptionNode.setAttribute( "exceptionCode", exceptionCode );
717    
718            String exceptionMessage = exception.getMessage();
719            if ( exceptionMessage != null && !"".equals( exceptionMessage.trim() ) ) {
720                appendElement( exceptionNode, OWSNS, PRE + "ExceptionText", exceptionMessage.trim() );
721            }
722    
723            if ( exception.getLocator() != null && !"unknown".equalsIgnoreCase( exception.getLocator().trim() ) ) {
724                try {
725                    String locator = URLEncoder.encode( exception.getLocator(), CharsetUtils.getSystemCharset() );
726                    exceptionNode.setAttribute( "locator", locator );
727                } catch ( UnsupportedEncodingException e ) {
728                    // nottin
729                }
730            }
731        }
732    
733    }