001    //$HeadURL: $
002    /*----------------    FILE HEADER  ------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2008 by:
005     Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009    
010     This library is free software; you can redistribute it and/or
011     modify it under the terms of the GNU Lesser General Public
012     License as published by the Free Software Foundation; either
013     version 2.1 of the License, or (at your option) any later version.
014     This library is distributed in the hope that it will be useful,
015     but WITHOUT ANY WARRANTY; without even the implied warranty of
016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     Lesser General Public License for more details.
018     You should have received a copy of the GNU Lesser General Public
019     License along with this library; if not, write to the Free Software
020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021     Contact:
022    
023     Andreas Poth
024     lat/lon GmbH
025     Aennchenstr. 19
026     53177 Bonn
027     Germany
028     E-Mail: poth@lat-lon.de
029    
030     Prof. Dr. Klaus Greve
031     Department of Geography
032     University of Bonn
033     Meckenheimer Allee 166
034     53115 Bonn
035     Germany
036     E-Mail: greve@giub.uni-bonn.de
037     ---------------------------------------------------------------------------*/
038    
039    package org.deegree.owscommon_1_1_0;
040    
041    import static org.deegree.ogcbase.CommonNamespaces.*;
042    import static org.deegree.framework.xml.XMLTools.*;
043    
044    import java.util.List;
045    
046    import org.deegree.framework.util.Pair;
047    import org.w3c.dom.Element;
048    import org.w3c.dom.Node;
049    
050    /**
051     * The <code>XMLFactory</code> is a convenience class, which exports ows-common 1.1.0 beans to their xml
052     * representation. representation.
053     * 
054     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
055     * 
056     * @author last edited by: $Author:$
057     * 
058     * @version $Revision:$, $Date:$
059     * 
060     */
061    
062    public class XMLFactory extends org.deegree.ogcbase.XMLFactory {
063    
064        private static String PRE = OWS_1_1_0PREFIX + ":";
065    
066        /**
067         * make an xml representation of given capabilities bean.
068         * 
069         * @param root
070         *            to export to.
071         * @param capabilities
072         *            to export
073         */
074        public void exportCapabilities( Element root, OWSCommonCapabilities capabilities ) {
075            if ( root != null && capabilities != null ) {
076                root.setAttribute( "version", capabilities.getVersion() );
077                root.setAttribute( "updateSequence", capabilities.getUpdateSequence() );
078                appendServiceIdentification( root, capabilities.getServiceIdentification() );
079                appendServiceProvider( root, capabilities.getServiceProvider() );
080                appendOperationsMetadata( root, capabilities.getOperationsMetadata() );
081            }
082        }
083    
084        /**
085         * @param capabilitiesElement
086         *            to export to if <code>null</code> nothing will be done.
087         * @param serviceIdentification
088         *            to append if <code>null</code> nothing will be done (optional).
089         */
090        protected void appendServiceIdentification( Element capabilitiesElement, ServiceIdentification serviceIdentification ) {
091            if ( capabilitiesElement == null || serviceIdentification == null ) {
092                return;
093            }
094            Element sid = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "ServiceIdentification" );
095            List<String> strings = serviceIdentification.getTitles();
096            if ( strings != null ) {
097                for ( String title : strings ) {
098                    if ( title != null && !"".equals( title.trim() ) ) {
099                        appendElement( sid, OWSNS_1_1_0, PRE + "Title", title );
100                    }
101                }
102            }
103    
104            strings = serviceIdentification.getAbstracts();
105            if ( strings != null ) {
106                for ( String s : strings ) {
107                    if ( s != null && !"".equals( s.trim() ) ) {
108                        appendElement( sid, OWSNS_1_1_0, PRE + "Abstract", s );
109                    }
110                }
111            }
112    
113            List<Keywords> keywords = serviceIdentification.getKeywords();
114            if ( keywords != null ) {
115                for ( Keywords kw : keywords ) {
116                    if ( kw != null ) {
117                        Element keywordsElement = appendElement( sid, OWSNS_1_1_0, PRE + "Keywords" );
118                        List<String> kws = kw.getkeywords();
119                        if ( kws != null ) {
120                            for ( String s : kws ) {
121                                appendElement( keywordsElement, OWSNS_1_1_0, PRE + "Keyword", s );
122                            }
123                        }
124                        Pair<String, String> type = kw.getType();
125                        if ( type != null ) {
126                            Element t = appendElement( keywordsElement, OWSNS_1_1_0, PRE + "Type", type.first );
127                            if( type.second != null){
128                                t.setAttribute( "codeSpace", type.second );
129                            }
130                        }
131                    }
132                }
133            }
134    
135            // ServiceType mandatory
136            Pair<String, String> serviceType = serviceIdentification.getServicetype();
137            Element ste = appendElement( sid, OWSNS_1_1_0, PRE + "ServiceType", serviceType.first );
138            if( serviceType.second != null ){
139                ste.setAttribute( "codeSpace", serviceType.second );
140            }
141    
142            // ServiceTypeVersion(s) mandatory.
143            List<String> serviceTypeVersions = serviceIdentification.getServiceTypeVersions();
144            for ( String serviceTypeVersion : serviceTypeVersions ) {
145                appendElement( sid, OWSNS_1_1_0, PRE + "ServiceTypeVersion", serviceTypeVersion );
146            }
147    
148            List<String> profiles = serviceIdentification.getProfiles();
149            for ( String profile : profiles ) {
150                appendElement( sid, OWSNS_1_1_0, PRE + "Profile", profile );
151            }
152    
153            String fee = serviceIdentification.getFees();
154            if ( fee != null && !"".equals( fee.trim() ) ) {
155                appendElement( sid, OWSNS_1_1_0, PRE + "Fees", fee );
156            }
157    
158            List<String> accessConst = serviceIdentification.getAccessConstraints();
159            if ( accessConst != null ) {
160                for ( String constraint : accessConst ) {
161                    appendElement( sid, OWSNS_1_1_0, PRE + "AccessConstraints", constraint );
162                }
163            }
164    
165        }
166    
167        /**
168         * 
169         * @param capabilitiesElement
170         *            to export to if <code>null</code> nothing will be done.
171         * @param serviceProvider
172         *            to append if <code>null</code> nothing will be done (optional).
173         */
174        protected void appendServiceProvider( Element capabilitiesElement, ServiceProvider serviceProvider ) {
175            if ( capabilitiesElement == null || serviceProvider == null ) {
176                return;
177            }
178            Element sp = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "ServiceProvider" );
179            appendElement( sp, OWSNS_1_1_0, PRE + "ProviderName", serviceProvider.getProviderName() );
180            if ( serviceProvider.getProviderSite() != null && !"".equals( serviceProvider.getProviderSite() ) ) {
181                Element provSite = appendElement( sp, OWSNS_1_1_0, PRE + "ProviderSite");
182                provSite.setAttributeNS( XLNNS.toASCIIString(), XLINK_PREFIX +":href", serviceProvider.getProviderSite() );
183            }
184    
185            appendServiceContact( sp, serviceProvider.getServiceContact() );
186    
187        }
188    
189        /**
190         * @param root
191         *            to export to if <code>null</code> nothing will be done.
192         * @param serviceContact
193         *            to append if <code>null</code> nothing will be done (optional).
194         */
195        protected void appendServiceContact( Element root, ServiceContact serviceContact ) {
196            if ( root == null || serviceContact == null ) {
197                return;
198            }
199            Element sc = appendElement( root, OWSNS_1_1_0, PRE + "ServiceContact" );
200            // optional IndividualName
201            if ( serviceContact.getIndividualName() != null && !"".equals( serviceContact.getIndividualName() ) ) {
202                appendElement( sc, OWSNS_1_1_0, PRE + "IndividualName", serviceContact.getIndividualName() );
203            }
204            // optional PositionName
205            if ( serviceContact.getPositionName() != null && !"".equals( serviceContact.getPositionName() ) ) {
206                appendElement( sc, OWSNS_1_1_0, PRE + "PositionName", serviceContact.getPositionName() );
207            }
208            // optional ContactInfo
209            appendContactInfo( sc, serviceContact.getContactInfo() );
210    
211            // optional Role.
212            if ( serviceContact.getRole() != null ) {
213                Element r = appendElement( sc, OWSNS_1_1_0, PRE + "Role", serviceContact.getRole().first );
214                if( serviceContact.getRole().second != null ){
215                    r.setAttribute( "codeSpace", serviceContact.getRole().second );
216                }
217            }
218    
219        }
220    
221        /**
222         * @param root
223         *            (usually a serviceContact) to export to if <code>null</code> nothing will be done.
224         * @param contactInfo
225         *            to append if <code>null</code> nothing will be done (optional).
226         */
227        protected void appendContactInfo( Element root, ContactInfo contactInfo ) {
228            if ( root == null || contactInfo == null ) {
229                return;
230            }
231            Element ci = appendElement( root, OWSNS_1_1_0, PRE + "ContactInfo" );
232            if ( contactInfo.getPhone() != null ) {
233                Pair<List<String>, List<String>> phone = contactInfo.getPhone();
234                Element phoneE = appendElement( ci, OWSNS_1_1_0, PRE + "Phone" );
235                if ( phone.first != null && phone.first.size() != 0 ) {
236                    for ( String t : phone.first ) {
237                        appendElement( phoneE, OWSNS_1_1_0, PRE + "Voice", t );
238                    }
239                }
240                if ( phone.second != null && phone.second.size() != 0 ) {
241                    for ( String t : phone.second ) {
242                        appendElement( phoneE, OWSNS_1_1_0, PRE + "Facsimile", t );
243                    }
244                }
245            }
246    
247            if ( contactInfo.hasAdress() ) {
248                Element addr = appendElement( ci, OWSNS_1_1_0, PRE + "Address" );
249                if ( contactInfo.getDeliveryPoint() != null ) {
250                    for ( String s : contactInfo.getDeliveryPoint() ) {
251                        appendElement( addr, OWSNS_1_1_0, PRE + "DeliveryPoint", s );
252                    }
253                }
254                if ( contactInfo.getCity() != null && !"".equals( contactInfo.getCity().trim() ) ) {
255                    appendElement( addr, OWSNS_1_1_0, PRE + "City", contactInfo.getCity().trim() );
256                }
257                if ( contactInfo.getAdministrativeArea() != null && !"".equals( contactInfo.getAdministrativeArea().trim() ) ) {
258                    appendElement( addr, OWSNS_1_1_0, PRE + "AdministrativeArea", contactInfo.getAdministrativeArea()
259                                                                                             .trim() );
260                }
261                if ( contactInfo.getPostalCode() != null && !"".equals( contactInfo.getPostalCode().trim() ) ) {
262                    appendElement( addr, OWSNS_1_1_0, PRE + "PostalCode", contactInfo.getPostalCode().trim() );
263                }
264                if ( contactInfo.getCountry() != null && !"".equals( contactInfo.getCountry().trim() ) ) {
265                    appendElement( addr, OWSNS_1_1_0, PRE + "Country", contactInfo.getCountry().trim() );
266                }
267                if ( contactInfo.getElectronicMailAddress() != null ) {
268                    for ( String s : contactInfo.getElectronicMailAddress() ) {
269                        appendElement( addr, OWSNS_1_1_0, PRE + "ElectronicMailAddress", s );
270                    }
271                }
272            }
273            if ( contactInfo.getOnlineResource() != null && !"".equals( contactInfo.getOnlineResource().trim() ) ) {
274                Element onlineResource = appendElement( ci, OWSNS_1_1_0, PRE + "OnlineResource" );
275                onlineResource.setAttributeNS( XLNNS.toASCIIString() , XLINK_PREFIX + ":href", contactInfo.getOnlineResource().trim() );
276            }
277    
278            if ( contactInfo.getHoursOfService() != null && !"".equals( contactInfo.getHoursOfService().trim() ) ) {
279                appendElement( ci, OWSNS_1_1_0, PRE + "HoursOfService", contactInfo.getHoursOfService().trim() );
280            }
281    
282            if ( contactInfo.getContactInstructions() != null && !"".equals( contactInfo.getContactInstructions().trim() ) ) {
283                appendElement( ci, OWSNS_1_1_0, PRE + "ContactInstructions", contactInfo.getContactInstructions().trim() );
284            }
285        }
286    
287        /**
288         * @param capabilitiesElement
289         *            to export to if <code>null</code> nothing will be done.
290         * @param operationsMetadata
291         *            to append if <code>null</code> nothing will be done (optional).
292         */
293        protected void appendOperationsMetadata( Element capabilitiesElement, OperationsMetadata operationsMetadata ) {
294            if ( capabilitiesElement == null || operationsMetadata == null ) {
295                return;
296            }
297            Element omd = appendElement( capabilitiesElement, OWSNS_1_1_0, PRE + "OperationsMetadata" );
298            appendOperations( omd, operationsMetadata.getOperations() );
299            if ( operationsMetadata.getParameters() != null ) {
300                for ( DomainType domainType : operationsMetadata.getParameters() ) {
301                    Element parameter = appendElement( omd, OWSNS_1_1_0, PRE + "Parameter" );
302                    appendDomainType( parameter, domainType );
303                }
304            }
305    
306            if ( operationsMetadata.getConstraints() != null ) {
307                for ( DomainType domainType : operationsMetadata.getConstraints() ) {
308                    Element constraint = appendElement( omd, OWSNS_1_1_0, PRE + "Constraint" );
309                    appendDomainType( constraint, domainType );
310                }
311            }
312            if ( operationsMetadata.getExtendedCapabilities() != null ) {
313                Node tmp = omd.getOwnerDocument().importNode( operationsMetadata.getExtendedCapabilities(), true );
314                omd.appendChild( tmp );
315            }
316        }
317    
318        /**
319         * @param root
320         *            to append to.
321         * @param operations
322         *            may not be <code>null</code>
323         * @throws IllegalArgumentException
324         *             if the list of operations &lt; 2 or <code>null</code>.
325         */
326        protected void appendOperations( Element root, List<Operation> operations ) {
327            if ( root == null ) {
328                return;
329            }
330            if ( operations == null || operations.size() < 2 ) {
331                throw new IllegalArgumentException( "The list of operations must at least contain 2 operations." );
332            }
333            for ( Operation operation : operations ) {
334                Element opElement = appendElement( root, OWSNS_1_1_0, PRE + "Operation" );
335                List<Pair<String, List<DomainType>>> getURLs = operation.getGetURLs();
336                List<Pair<String, List<DomainType>>> postURLs = operation.getPostURLs();
337                Element dcp = appendElement( opElement, OWSNS_1_1_0, PRE + "DCP" );
338                Element httpElement = appendElement( dcp, OWSNS_1_1_0, PRE + "HTTP" );
339                if ( getURLs != null ) {
340                    for ( Pair<String, List<DomainType>> getURL : getURLs ) {
341                        Element get = appendElement( httpElement, OWSNS_1_1_0, PRE + "Get" );
342                        if( getURL.first != null ){
343                            get.setAttributeNS( XLNNS.toASCIIString() , XLINK_PREFIX + ":href", getURL.first );
344                        }
345                        if ( getURL.second != null && getURL.second.size() > 0 ) {
346                            Element constraint = appendElement( get, OWSNS_1_1_0, PRE + "Constraint" );
347                            for ( DomainType domainType : getURL.second ) {
348                                appendDomainType( constraint, domainType );
349                            }
350                        }
351                    }
352                }
353                if ( postURLs != null ) {
354                    for ( Pair<String, List<DomainType>> postURL : postURLs ) {
355                        Element post = appendElement( httpElement, OWSNS_1_1_0, PRE + "Post" );
356                        if( postURL.first != null ){
357                            post.setAttributeNS( XLNNS.toASCIIString() , XLINK_PREFIX + ":href", postURL.first );
358                        }
359                        if ( postURL.second != null && postURL.second.size() > 0 ) {
360                            Element constraint = appendElement( post, OWSNS_1_1_0, PRE + "Constraint" );
361                            for ( DomainType domainType : postURL.second ) {
362                                appendDomainType( constraint, domainType );
363                            }
364                        }
365                    }
366                }
367    
368                if ( operation.getParameters() != null ) {
369                    for ( DomainType domainType : operation.getParameters() ) {
370                        Element parameter = appendElement( opElement, OWSNS_1_1_0, PRE + "Parameter" );
371                        appendDomainType( parameter, domainType );
372                    }
373                }
374    
375                if ( operation.getConstraints() != null ) {
376                    for ( DomainType domainType : operation.getConstraints() ) {
377                        Element constraint = appendElement( opElement, OWSNS_1_1_0, PRE + "Constraint" );
378                        appendDomainType( constraint, domainType );
379                    }
380                }
381                if ( operation.getMetadataAttribs() != null && operation.getMetadataAttribs().size() > 0 ) {
382                    for ( Pair<String, String> attrib : operation.getMetadataAttribs() ) {
383                        if ( attrib != null ) {
384                            Element metadata = appendElement( opElement, OWSNS_1_1_0, PRE + "Metadata" );
385                            if( attrib.first != null ){
386                                metadata.setAttributeNS( XLNNS.toASCIIString() , XLINK_PREFIX + ":href", attrib.first );
387                            }
388                            if( attrib.second != null ){
389                                metadata.setAttribute( "about", attrib.second );
390                            }
391                        }
392                    }
393                }
394                opElement.setAttribute( "name", operation.getName() );
395            }
396    
397        }
398    
399        /**
400         * @param domainTypeElement
401         *            to append the domainttype element to.
402         * @param domainType
403         *            to append.
404         */
405        protected void appendDomainType( Element domainTypeElement, DomainType domainType ) {
406            if ( domainTypeElement == null || domainType == null ) {
407                return;
408            }
409            domainTypeElement.setAttribute( "name", domainType.getName() );
410            if ( domainType.hasAllowedValues() ) {
411                Element allowedValuesElem = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "AllowedValues" );
412                List<String> values = domainType.getValues();
413                if ( values != null ) {
414                    for ( String value : values ) {
415                        appendElement( allowedValuesElem, OWSNS_1_1_0, PRE + "Value", value );
416                    }
417                }
418                List<Range> ranges = domainType.getRanges();
419                if ( ranges != null ) {
420                    for ( Range r : ranges ) {
421                        Element re = appendElement( allowedValuesElem, OWSNS_1_1_0, PRE + "Range" );
422                        if ( r.getMinimumValue() != null && !"".equals( r.getMinimumValue().trim() ) ) {
423                            appendElement( re, OWSNS_1_1_0, PRE + "MinimumValue", r.getMinimumValue() );
424                        }
425                        if ( r.getMaximumValue() != null && !"".equals( r.getMaximumValue().trim() ) ) {
426                            appendElement( re, OWSNS_1_1_0, PRE + "MaximumValue", r.getMaximumValue() );
427                        }
428                        if ( r.getSpacing() != null && !"".equals( r.getSpacing().trim() ) ) {
429                            appendElement( re, OWSNS_1_1_0, PRE + "Spacing", r.getSpacing() );
430                        }
431                        re.setAttribute( "rangeClosure", r.getRangeClosure() );
432                    }
433                }
434            } else if ( domainType.hasAnyValue() ) {
435                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "AnyValue" );
436            } else if ( domainType.hasNoValues() ) {
437                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "NoValues" );
438            } else { // a choice therefore this must be.
439                Element vref = appendElement( domainTypeElement,
440                                              OWSNS_1_1_0,
441                                              PRE + "ValuesReference",
442                                              domainType.getValuesReference().first );
443                if ( domainType.getValuesReference().second != null ) {
444                    vref.setAttribute( "reference", domainType.getValuesReference().second );
445                }
446            }
447            if ( domainType.getDefaultValue() != null && !"".equals( domainType.getDefaultValue() ) ) {
448                appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "DefaultValue", domainType.getDefaultValue().trim() );
449            }
450            if ( domainType.getMeaning() != null ) {
451                Element tmp = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "Meaning", domainType.getMeaning().first );
452                if( domainType.getMeaning().second != null ){
453                    tmp.setAttribute( "reference", domainType.getMeaning().second );
454                }
455            }
456            if ( domainType.getDataType() != null ) {
457                Element tmp = appendElement( domainTypeElement,
458                                             OWSNS_1_1_0,
459                                             PRE + "DataType",
460                                             domainType.getDataType().first );
461                if( domainType.getDataType().second != null ){
462                    tmp.setAttribute( "reference", domainType.getDataType().second );
463                }
464            }
465            if ( domainType.hasValuesUnit() ) {
466                Element valuesUnit = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "ValuesUnit" );
467                if ( domainType.getUom() != null ) {
468                    Element tmp = appendElement( valuesUnit, OWSNS_1_1_0, PRE + "UOM", domainType.getUom().first );
469                    if( domainType.getUom().second != null ){
470                        tmp.setAttribute( "reference", domainType.getUom().second );
471                    }
472                } else {
473                    Element tmp = appendElement( valuesUnit,
474                                                 OWSNS_1_1_0,
475                                                 PRE + "ReferenceSystem",
476                                                 domainType.getReferenceSystem().first );
477                    if( domainType.getReferenceSystem().second != null ){
478                        tmp.setAttribute( "reference", domainType.getReferenceSystem().second );
479                    }
480                }
481            }
482            if ( domainType.getMetadataAttribs() != null && domainType.getMetadataAttribs().size() > 0 ) {
483                for ( Pair<String, String> attrib : domainType.getMetadataAttribs() ) {
484                    if ( attrib != null ) {
485                        Element metadata = appendElement( domainTypeElement, OWSNS_1_1_0, PRE + "Metadata" );
486                        if( attrib.first != null ){
487                            metadata.setAttributeNS( XLNNS.toASCIIString() , XLINK_PREFIX + ":href", attrib.first );
488                        }
489                        if( attrib.second != null ){
490                            metadata.setAttribute( "about", attrib.second );
491                        }
492                    }
493                }
494            }
495        }
496    
497    }