    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/wpvs/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.ogcwebservices.wpvs;
    038
    039    import java.io.IOException;
    040    import java.net.URI;
    041    import java.net.URL;
    042
    043    import org.deegree.datatypes.values.TypedLiteral;
    044    import org.deegree.datatypes.values.ValueRange;
    045    import org.deegree.framework.xml.XMLTools;
    046    import org.deegree.model.crs.CoordinateSystem;
    047    import org.deegree.model.spatialschema.Envelope;
    048    import org.deegree.ogcbase.BaseURL;
    049    import org.deegree.ogcbase.CommonNamespaces;
    050    import org.deegree.ogcbase.ImageURL;
    051    import org.deegree.ogcwebservices.getcapabilities.DCPType;
    052    import org.deegree.ogcwebservices.getcapabilities.OperationsMetadata;
    053    import org.deegree.ogcwebservices.getcapabilities.ServiceIdentification;
    054    import org.deegree.ogcwebservices.getcapabilities.ServiceProvider;
    055    import org.deegree.ogcwebservices.wpvs.capabilities.DataProvider;
    056    import org.deegree.ogcwebservices.wpvs.capabilities.Dataset;
    057    import org.deegree.ogcwebservices.wpvs.capabilities.Dimension;
    058    import org.deegree.ogcwebservices.wpvs.capabilities.Identifier;
    059    import org.deegree.ogcwebservices.wpvs.capabilities.MetaData;
    060    import org.deegree.ogcwebservices.wpvs.capabilities.Style;
    061    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilities;
    062    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilitiesDocument;
    063    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSOperationsMetadata;
    064    import org.deegree.owscommon.OWSMetadata;
    065    import org.deegree.owscommon.com110.HTTP110;
    066    import org.deegree.owscommon.com110.OWSAllowedValues;
    067    import org.deegree.owscommon.com110.OWSDomainType110;
    068    import org.deegree.owscommon.com110.OWSRequestMethod;
    069    import org.deegree.owscommon.com110.Operation110;
    070    import org.w3c.dom.Element;
    071    import org.w3c.dom.Text;
    072    import org.xml.sax.SAXException;
    073
    074    /**
    075     * TODO class description
    076     *
    077     * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
    078     * @author last edited by: $Author: mschneider $
    079     *
    080     * $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    081     */
    082    public class XMLFactory extends org.deegree.owscommon.XMLFactory {
    083
    084        private static final URI WPVSNS = CommonNamespaces.WPVSNS;
    085
    086        private static final String PRE_OWS = CommonNamespaces.OWS_PREFIX + ':';
    087
    088        private static final String PRE_WPVS = CommonNamespaces.WPVS_PREFIX + ':';
    089
    090        private XMLFactory() {
    091            // not instantiable.
    092        }
    093
    094        /**
    095         * This method exporst a wpvs capabilitiesDocument with following information taken from the
    096         * given WPVSCapabilities
    097         * <ul>
    098         * <li>ServiceIdentification</li>
    099         * <li>ServiceProvide</li>
    100         * <li>operationMetadata</li>
    101         * <li>the root dataset</li>
    102         * </ul>
    103         *
    104         * @param wpvsCapabilities
    105         * @return the WPVSCapabilitiesDocument of this wpvs
    106         * @throws IOException
    107         *             if wpvsCapabilitiesDocument cannot be instantiated
    108         */
    109        public static WPVSCapabilitiesDocument export( WPVSCapabilities wpvsCapabilities )
    110                                throws IOException {
    111            XMLFactory factory = new XMLFactory();
    112            return factory.createCapabilitiesDocument( wpvsCapabilities );
    113        }
    114
    115        private WPVSCapabilitiesDocument createCapabilitiesDocument( WPVSCapabilities wpvsCapabilities )
    116                                throws IOException {
    117            WPVSCapabilitiesDocument wpvsCapabilitiesDocument = new WPVSCapabilitiesDocument();
    118            try {
    119                wpvsCapabilitiesDocument.createEmptyDocument();
    120                Element root = wpvsCapabilitiesDocument.getRootElement();
    121
    122                ServiceIdentification serviceIdentification = wpvsCapabilities.getServiceIdentification();
    123                if ( serviceIdentification != null ) {
    124                    appendServiceIdentification( root, serviceIdentification );
    125                }
    126
    127                ServiceProvider serviceProvider = wpvsCapabilities.getServiceProvider();
    128                if ( serviceProvider != null ) {
    129                    appendServiceProvider( root, serviceProvider );
    130                }
    131
    132                OperationsMetadata operationMetadata = wpvsCapabilities.getOperationsMetadata();
    133                if ( operationMetadata != null && operationMetadata instanceof WPVSOperationsMetadata ) {
    134                    appendWPVSOperationsMetadata( root, (WPVSOperationsMetadata) operationMetadata );
    135                }
    136
    137                Dataset dataset = wpvsCapabilities.getDataset();
    138                if ( dataset != null ) {
    139                    appendDataset( root, dataset );
    140                }
    141
    142            } catch ( SAXException e ) {
    143                e.printStackTrace();
    144                LOG.logError( e.getMessage(), e );
    145            }
    146
    147            return wpvsCapabilitiesDocument;
    148        }
    149
    150        /**
    151         * Appends the DOM representation of an <code>WPVSOperationsMetadata</code> to the passed
    152         * <code>Element</code>.
    153         *
    154         * @param root
    155         * @param operationsMetadata
    156         */
    157        private void appendWPVSOperationsMetadata( Element root, WPVSOperationsMetadata operationsMetadata ) {
    158            // 'ows:OperationsMetadata'-element
    159            Element operationsMetadataNode = XMLTools.appendElement( root, OWSNS, PRE_OWS + "OperationsMetadata" );
    160
    161            // append all Operations
    162            Operation110[] operations = (Operation110[]) operationsMetadata.getAllOperations();
    163            for ( int i = 0; i < operations.length; i++ ) {
    164                Operation110 operation = operations[i];
    165
    166                // 'ows:Operation' - element
    167                Element operationElement = XMLTools.appendElement( operationsMetadataNode, OWSNS, PRE_OWS + "Operation" );
    168                operationElement.setAttribute( "name", operation.getName() );
    169
    170                // 'ows:DCP' - elements
    171                DCPType[] dcps = operation.getDCPs();
    172                for ( int j = 0; j < dcps.length; j++ ) {
    173                    appendDCPValue( operationElement, dcps[j] );
    174                }
    175
    176                // 'ows:Parameter' - elements
    177                OWSDomainType110[] parameters = operation.getParameters110();
    178                for ( int j = 0; j < parameters.length; j++ ) {
    179                    appendDomainType( operationElement, parameters[j], PRE_OWS + "Parameter" );
    180                }
    181
    182                // 'ows:Constraint' - elements
    183                OWSDomainType110[] constraints = operation.getConstraints110();
    184                for ( int j = 0; j < constraints.length; j++ ) {
    185                    appendDomainType( operationElement, constraints[j], PRE_OWS + "Constraint" );
    186                }
    187
    188                // 'ows:Metadata' - elements
    189                OWSMetadata[] metadata = operation.getMetadata110();
    190                for ( int j = 0; j < metadata.length; j++ ) {
    191                    appendOWSMetadata( operationElement, metadata[j], PRE_OWS + "Metadata" );
    192                }
    193            }
    194
    195            // append general parameters
    196            OWSDomainType110[] parameters = operationsMetadata.getParameters110();
    197            for ( int i = 0; i < parameters.length; i++ ) {
    198                appendDomainType( operationsMetadataNode, parameters[i], PRE_OWS + "Parameter" );
    199            }
    200
    201            // append general constraints
    202            OWSDomainType110[] constraints = operationsMetadata.getConstraints110();
    203            for ( int i = 0; i < constraints.length; i++ ) {
    204                appendDomainType( operationsMetadataNode, constraints[i], PRE_OWS + "Constraint" );
    205            }
    206
    207            // append 'ows:ExtendedCapabilities'
    208            // TODO when needed.
    209
    210        }
    211
    212        /**
    213         * Appends the DOM representation of an <code>OWSMetadata</code> to the passed
    214         * <code>Element</code>. The given <code>String</code> is used to distinguish between the
    215         * different Metadata types.
    216         *
    217         * @param element
    218         * @param metadata
    219         * @param tagName
    220         */
    221        private void appendOWSMetadata( Element element, OWSMetadata metadata, String tagName ) {
    222
    223            if ( metadata != null ) {
    224
    225                Element metadataElement = XMLTools.appendElement( element, OWSNS, tagName );
    226
    227                appendSimpleLinkAttributes( metadataElement, metadata.getLink() );
    228
    229                Element nameElement = XMLTools.appendElement( metadataElement, OWSNS, CommonNamespaces.OWS_PREFIX + ":Name" );
    230                metadataElement.appendChild( nameElement );
    231                nameElement.setNodeValue( metadata.getName() );
    232            }
    233
    234        }
    235
    236        /**
    237         * Appends the DOM representation of an <code>OWSDomainType</code> to the passed
    238         * <code>Element</code>. The given <code>String</code> is used to distinguish between
    239         * <code>Parameter</code> and <code>Constraint</code>.
    240         *
    241         * @param element
    242         * @param domainType
    243         * @param tagName
    244         */
    245        private void appendDomainType( Element element, OWSDomainType110 domainType, String tagName ) {
    246
    247            Element domainElement = XMLTools.appendElement( element, OWSNS, tagName );
    248
    249            // attribute
    250            domainElement.setAttribute( "name", domainType.getName() );
    251
    252            // elements
    253            OWSAllowedValues allowedValues = domainType.getAllowedValues();
    254            OWSMetadata valuesListReference = domainType.getValuesListReference();
    255            if ( allowedValues != null ) {
    256                appendAllowedValues( domainElement, allowedValues );
    257            }
    258            // else if ( domainType.isAnyValue() ) {
    259            // Element anyElement = XMLTools.appendElement( domainElement, OWSNS,
    260            // CommonNamespaces.OWS_PREFIX+":AnyValue" );
    261            // // TODO content of this tag!
    262            // } else if ( domainType.hasNoValues() ) {
    263            // Element noValuesElement = XMLTools.appendElement( domainElement, OWSNS,
    264            // CommonNamespaces.OWS_PREFIX+":NoValues" );
    265            // // TODO content of this tag!
    266            // }
    267            else if ( valuesListReference != null ) {
    268                appendOWSMetadata( domainElement, valuesListReference, CommonNamespaces.OWS_PREFIX + ":ValuesListReference" );
    269            } else {
    270                // TODO "domainType object is invalid!"
    271            }
    272
    273            appendTypedLiteral( domainElement, domainType.getDefaultValue(), PRE_OWS + "DefaultValue", OWSNS );
    274
    275            appendOWSMetadata( domainElement, domainType.getMeaning(), PRE_OWS + "Meaning" );
    276
    277            appendOWSMetadata( domainElement, domainType.getOwsDataType(), PRE_OWS + "DataType" );
    278
    279            String measurement = domainType.getMeasurementType();
    280            if ( OWSDomainType110.REFERENCE_SYSTEM.equals( measurement ) ) {
    281                appendOWSMetadata( domainElement, domainType.getMeasurement(), PRE_OWS + "ReferenceSystem" );
    282            } else if ( OWSDomainType110.UOM.equals( measurement ) ) {
    283                appendOWSMetadata( domainElement, domainType.getMeasurement(), PRE_OWS + "UOM" );
    284            }
    285
    286            OWSMetadata[] metadata = domainType.getMetadata();
    287            for ( int i = 0; i < metadata.length; i++ ) {
    288                appendOWSMetadata( domainElement, metadata[i], PRE_OWS + "Metadata" );
    289            }
    290
    291        }
    292
    293        /**
    294         * Appends the DOM representation of an <code>OWSAllowedValues</code> object to the passed
    295         * <code>Element</code>.
    296         *
    297         * @param element
    298         * @param allowedValues
    299         */
    300        private void appendAllowedValues( Element element, OWSAllowedValues allowedValues ) {
    301
    302            Element allowedElement = XMLTools.appendElement( element, OWSNS, PRE_OWS + "AllowedValues" );
    303
    304            TypedLiteral[] literals = allowedValues.getOwsValues();
    305            for ( int i = 0; i < literals.length; i++ ) {
    306                appendTypedLiteral( allowedElement, literals[i], PRE_OWS + "Value", OWSNS );
    307            }
    308
    309            ValueRange[] range = allowedValues.getValueRanges();
    310            for ( int i = 0; i < range.length; i++ ) {
    311                Element rangeElement = XMLTools.appendElement( allowedElement, OWSNS, PRE_OWS + "Range" );
    312
    313                appendTypedLiteral( rangeElement, range[i].getMin(), PRE_OWS + "MinimumValue", OWSNS );
    314                appendTypedLiteral( rangeElement, range[i].getMax(), PRE_OWS + "MaximumValue", OWSNS );
    315                appendTypedLiteral( rangeElement, range[i].getSpacing(), PRE_OWS + "Spacing", OWSNS );
    316            }
    317
    318        }
    319
    320        /*
    321         * (non-Javadoc)
    322         *
    323         * @see org.deegree.owscommon.XMLFactory#appendDCP(org.w3c.dom.Element,
    324         *      org.deegree.ogcwebservices.getcapabilities.DCPType)
    325         */
    326        private void appendDCPValue( Element operationElement, DCPType dcp ) {
    327
    328            // 'ows:DCP'-element
    329            Element dcpNode = XMLTools.appendElement( operationElement, OWSNS, PRE_OWS + "DCP" );
    330
    331            // currently, the only supported DCP are HTTP and HTTP110!
    332            if ( dcp.getProtocol() instanceof HTTP110 ) {
    333                HTTP110 http = (HTTP110) dcp.getProtocol();
    334
    335                // 'ows:HTTP'-element
    336                Element httpNode = XMLTools.appendElement( dcpNode, OWSNS, PRE_OWS + "HTTP" );
    337
    338                // 'ows:Get'-elements
    339                OWSRequestMethod[] getRequest = http.getGetRequests();
    340                for ( int i = 0; i < getRequest.length; i++ ) {
    341                    appendRequest( httpNode, PRE_OWS + "Get", getRequest[i] );
    342                }
    343
    344                // 'ows:Post'-elements
    345                OWSRequestMethod[] postRequest = http.getPostRequests();
    346                for ( int i = 0; i < postRequest.length; i++ ) {
    347                    appendRequest( httpNode, PRE_OWS + "Post", postRequest[i] );
    348                }
    349            }
    350
    351        }
    352
    353        /**
    354         * Appends the DOM representation of an <code>OWSRequestMethod</code> to the passed
    355         * <code>Element</code>. The given <code>String</code> is used to distinguish between
    356         * <code>ows:Get</code> and <code>ows:Post</code> requests.
    357         *
    358         * @param httpNode
    359         * @param type
    360         * @param request
    361         */
    362        private void appendRequest( Element httpNode, String type, OWSRequestMethod request ) {
    363
    364            Element owsElement = XMLTools.appendElement( httpNode, OWSNS, type );
    365
    366            appendSimpleLinkAttributes( owsElement, request.getLink() );
    367
    368            OWSDomainType110[] constraint = request.getConstraints();
    369            for ( int i = 0; i < constraint.length; i++ ) {
    370                appendDomainType( owsElement, constraint[i], PRE_OWS + "Constraint" );
    371            }
    372
    373        }
    374
    375        /**
    376         * Appends the DOM representation of a <code>Dataset</code> to the passed <code>Element</code>.
    377         *
    378         * @param root
    379         * @param dataset
    380         */
    381        private void appendDataset( Element root, Dataset dataset ) {
    382
    383            // 'wpvs:Dataset'-element (parent)
    384            Element datasetNode = XMLTools.appendElement( root, WPVSNS, PRE_WPVS + "Dataset" );
    385
    386            // attributes
    387            datasetNode.setAttribute( "queryable", ( ( dataset.getQueryable() ) ? "1" : "0" ) );
    388            datasetNode.setAttribute( "opaque", ( ( dataset.getOpaque() ) ? "1" : "0" ) );
    389            datasetNode.setAttribute( "noSubsets", ( ( dataset.getNoSubset() ) ? "1" : "0" ) );
    390            datasetNode.setAttribute( "fixedWidth", String.valueOf( dataset.getFixedWidth() ) );
    391            datasetNode.setAttribute( "fixedHeight", String.valueOf( dataset.getFixedHeight() ) );
    392
    393            // optional 'wpvs:Name'-element
    394            appendName( datasetNode, dataset );
    395
    396            // mandatory 'wpvs:Title'-element
    397            appendTitle( datasetNode, dataset );
    398
    399            // optional 'wpvs:Abstract'-element
    400            appendAbstract( datasetNode, dataset );
    401
    402            // optional 'ows:Keywords'-elements
    403            appendOWSKeywords( datasetNode, dataset.getKeywords() );
    404
    405            // optional 'wpvs:CRS'-elements
    406            appendCRSNodes( datasetNode, dataset.getCrs() );
    407
    408            // optional 'wpvs:Format'-elements
    409            appendFormats( datasetNode, dataset.getMimeTypeFormat() );
    410
    411            // mandatory 'ows:WGS84BoundingBox
    412            appendBoundingBox( datasetNode, dataset.getWgs84BoundingBox(), PRE_OWS + "WGS84BoundingBox",
    413                               "urn:ogc:def:crs:OGC:2:84", "2" );
    414
    415            // optional 'ows:BoundingBox'-elements
    416            Envelope[] boundingBoxes = dataset.getBoundingBoxes();
    417
    418            for ( int i = 0; i < boundingBoxes.length; i++ ) {
    419
    420                if ( boundingBoxes[i] != null ) {
    421                    String crsName = boundingBoxes[i].getCoordinateSystem().getIdentifier();
    422
    423                    appendBoundingBox( datasetNode, boundingBoxes[i], PRE_OWS + "BoundingBox", crsName, "2" );
    424                }
    425            }
    426
    427            // optional 'wpvs:Dimension'-elements
    428            appendDimensions( datasetNode, dataset.getDimensions() );
    429
    430            // optional 'wpvs:DataProvider'-element
    431            appendDataProvider( datasetNode, dataset.getDataProvider() );
    432
    433            // mandatory 'wpvs:Identifier'-element
    434            appendIdentifier( datasetNode, dataset.getIdentifier() );
    435
    436            // 'wpvs:MetaData'-elements
    437            appendURLs( datasetNode, dataset.getMetadata(), WPVSNS, PRE_WPVS + "MetaData" );
    438
    439            // 'wpvs:DatasetReference'-elements
    440            appendURLs( datasetNode, dataset.getDatasetReferences(), WPVSNS, PRE_WPVS + "DatasetReference" );
    441
    442            // 'wpvs:FeatureListReference'-elements
    443            appendURLs( datasetNode, dataset.getFeatureListReferences(), WPVSNS, PRE_WPVS + "FeatureListReference" );
    444
    445            // 'wpvs:Style'-elements
    446            appendStyles( datasetNode, dataset.getStyles() );
    447
    448            // 'wpvs:MinimumScaleDenominator'-element
    449            appendScaleDenominator( datasetNode, dataset.getMinimumScaleDenominator(), "MIN" );
    450
    451            // 'wpvs:MaximumScaleDenominator'-element
    452            appendScaleDenominator( datasetNode, dataset.getMaximumScaleDenominator(), "MAX" );
    453
    454            // 'wpvs:Dataset'-elements (children)
    455            Dataset[] datasets = dataset.getDatasets();
    456            for ( int i = 0; i < datasets.length; i++ ) {
    457                appendDataset( datasetNode, datasets[i] );
    458            }
    459
    460            // 'ElevationModel'-element (the simple ogc-ElevationModel)
    461            String emName = dataset.getElevationModel().getName();
    462            if ( emName != null ) {
    463                appendElevationModel( datasetNode, emName );
    464            }
    465        }
    466
    467        /**
    468         * Appends the DOM representation of an OGC <code>ElevationModel</code> to the passed
    469         * <code>Element</code>.
    470         *
    471         * @param datasetNode
    472         * @param elevationModelName
    473         */
    474        private void appendElevationModel( Element datasetNode, String elevationModelName ) {
    475
    476            Element elevation = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "ElevationModel" );
    477            Text elevationText = elevation.getOwnerDocument().createTextNode( elevationModelName );
    478            elevation.appendChild( elevationText );
    479
    480            elevation.appendChild( elevationText );
    481
    482        }
    483
    484        /**
    485         * Appends the DOM representations of the given <code>ScaleDenominator</code> to the passed
    486         * <code>Element</code>. The given <code>String</code> is used to distinguish between
    487         * MinimumsScaleDenominator and MaximumScaleDenominator.
    488         *
    489         * @param datasetNode
    490         * @param scaleDenominator
    491         * @param extremum
    492         *            must be either 'MIN' or 'MAX'.
    493         */
    494        private void appendScaleDenominator( Element datasetNode, double scaleDenominator, String extremum ) {
    495            Element scaleElement = null;
    496
    497            if ( "MIN".equalsIgnoreCase( extremum ) ) {
    498                scaleElement = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "MinimumScaleDenominator" );
    499            } else if ( "MAX".equalsIgnoreCase( extremum ) ) {
    500                scaleElement = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "MaximumScaleDenominator" );
    501            } else {
    502                throw new IllegalArgumentException( "The extremum must be either 'MIN' or 'MAX'." );
    503            }
    504
    505            String value = String.valueOf( scaleDenominator );
    506            Text scaleText = scaleElement.getOwnerDocument().createTextNode( value );
    507            scaleElement.appendChild( scaleText );
    508
    509        }
    510
    511        /**
    512         * Appends the DOM representations of the <code>Abstract</code> Element from the given
    513         * <code>Object</code> to the passed <code>Element</code>.
    514         *
    515         * @param root
    516         * @param obj
    517         *            may be of the following types: Style, Dataset.
    518         */
    519        private void appendAbstract( Element root, Object obj ) {
    520
    521            String abstractString = null;
    522            if ( obj instanceof Style ) {
    523                abstractString = ( (Style) obj ).getAbstract();
    524            } else if ( obj instanceof Dataset ) {
    525                abstractString = ( (Dataset) obj ).getAbstract();
    526            }
    527            if ( abstractString != null ) {
    528                Element abstractElement = XMLTools.appendElement( root, WPVSNS, PRE_WPVS + "Abstract" );
    529                Text abstractText = abstractElement.getOwnerDocument().createTextNode( abstractString );
    530                abstractElement.appendChild( abstractText );
    531            }
    532
    533        }
    534
    535        /**
    536         * Appends the DOM representations of the <code>Title</code> Element from the given
    537         * <code>Object</code> to the passed <code>Element</code>.
    538         *
    539         * @param root
    540         * @param obj
    541         *            may be of the following types: Style, Dataset.
    542         */
    543        private void appendTitle( Element root, Object obj ) {
    544
    545            String title = null;
    546            if ( obj instanceof Style ) {
    547                title = ( (Style) obj ).getTitle();
    548            } else if ( obj instanceof Dataset ) {
    549                title = ( (Dataset) obj ).getTitle();
    550            }
    551            Element titleElement = XMLTools.appendElement( root, WPVSNS, PRE_WPVS + "Title" );
    552            Text titleText = titleElement.getOwnerDocument().createTextNode( title );
    553            titleElement.appendChild( titleText );
    554        }
    555
    556        /**
    557         * Appends the DOM representations of the <code>Name</code> Element from the given
    558         * <code>Object</code> to the passed <code>Element</code>.
    559         *
    560         * @param root
    561         * @param obj
    562         *            may be of the following types: Style, Dataset.
    563         */
    564        private void appendName( Element root, Object obj ) {
    565
    566            String name = null;
    567            if ( obj instanceof Style ) {
    568                name = ( (Style) obj ).getName();
    569            } else if ( obj instanceof Dataset ) {
    570                name = ( (Dataset) obj ).getName();
    571            }
    572
    573            if ( name != null ) {
    574                Element nameElement = XMLTools.appendElement( root, WPVSNS, PRE_WPVS + "Name" );
    575                Text nameText = nameElement.getOwnerDocument().createTextNode( name );
    576                nameElement.appendChild( nameText );
    577            }
    578
    579        }
    580
    581        /**
    582         * Appends the DOM representations of the given array of <code>Style</code> to the passed
    583         * <code>Element</code>.
    584         *
    585         * @param datasetNode
    586         * @param styles
    587         */
    588        private void appendStyles( Element datasetNode, Style[] styles ) {
    589
    590            if ( styles != null ) {
    591                for ( int i = 0; i < styles.length; i++ ) {
    592
    593                    Element styleElement = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "Style" );
    594
    595                    appendName( styleElement, styles[i] );
    596                    appendTitle( styleElement, styles[i] );
    597                    appendAbstract( styleElement, styles[i] );
    598
    599                    appendOWSKeywords( styleElement, styles[i].getKeywords() );
    600
    601                    if ( styles[i].getIdentifier() != null ) {
    602                        appendIdentifier( styleElement, styles[i].getIdentifier() );
    603                    }
    604
    605                    appendURLs( styleElement, styles[i].getLegendURLs(), WPVSNS, PRE_WPVS + "LegendURL" );
    606
    607                    Element styleSheetURLElement = XMLTools.appendElement( styleElement, WPVSNS, PRE_WPVS + "StyleSheetURL" );
    608                    appendURL( styleSheetURLElement, styles[i].getStyleSheetURL(), WPVSNS );
    609
    610                    Element styleURLElement = XMLTools.appendElement( styleElement, WPVSNS, PRE_WPVS + "StyleURL" );
    611                    appendURL( styleURLElement, styles[i].getStyleURL(), WPVSNS );
    612
    613                }
    614            }
    615        }
    616
    617        /**
    618         * Appends the DOM representations of the given array of <code>BaseURL</code> under the given
    619         * name to the passed <code>Element</code>.
    620         *
    621         * @param root
    622         * @param baseURL
    623         * @param uri
    624         * @param newNode
    625         */
    626        private void appendURLs( Element root, BaseURL[] baseURL, URI uri, String newNode ) {
    627            if ( baseURL != null ) {
    628                for ( int i = 0; i < baseURL.length; i++ ) {
    629                    Element urlElement = XMLTools.appendElement( root, uri, newNode );
    630                    appendURL( urlElement, baseURL[i], uri );
    631                }
    632            }
    633        }
    634
    635        /**
    636         * Appends the contents of the given <code>BaseURL</code> within the given <code>URI</code>
    637         * as DOM representation to the passed URL <code>Element</code>.
    638         *
    639         * @param urlElement
    640         *            example: logoURLElement
    641         * @param baseURL
    642         *            example: dataProvider.getLogoURL()
    643         * @param uri
    644         *            example: "WPVSNS"
    645         */
    646        private void appendURL( Element urlElement, BaseURL baseURL, URI uri ) {
    647
    648            // child elements of urlElement
    649            Element formatElement = XMLTools.appendElement( urlElement, uri, PRE_WPVS + "Format" );
    650            String format = baseURL != null ? baseURL.getFormat() : "";
    651            Text formatText = formatElement.getOwnerDocument().createTextNode( format );
    652            formatElement.appendChild( formatText );
    653
    654            Element onlineElement = XMLTools.appendElement( urlElement, uri, PRE_WPVS + "OnlineResource" );
    655            String url = ( baseURL != null && baseURL.getOnlineResource() != null ) ? baseURL.getOnlineResource().toString()
    656                                                                                   : "";
    657            onlineElement.setAttribute( "xlink:href", url );
    658
    659            // attributes of urlElement
    660            if ( baseURL instanceof ImageURL ) {
    661                String width = String.valueOf( ( (ImageURL) baseURL ).getWidth() );
    662                String height = String.valueOf( ( (ImageURL) baseURL ).getHeight() );
    663                urlElement.setAttribute( "width", width );
    664                urlElement.setAttribute( "height", height );
    665
    666            } else if ( baseURL instanceof MetaData ) {
    667
    668                urlElement.setAttribute( "type", ( (MetaData) baseURL ).getType() );
    669            }
    670
    671        }
    672
    673        /**
    674         * Appends the DOM representation of the given <code>Identifier</code> to the passed
    675         * <code>Element</code>.
    676         *
    677         * @param root
    678         * @param identifier
    679         */
    680        private void appendIdentifier( Element root, Identifier identifier ) {
    681
    682            Element idElement = XMLTools.appendElement( root, WPVSNS, PRE_WPVS + "Identifier" );
    683
    684            if ( identifier.getCodeSpace() != null ) {
    685                idElement.setAttribute( "codeSpace", identifier.getCodeSpace().toASCIIString() );
    686            }
    687
    688            Text idText = idElement.getOwnerDocument().createTextNode( identifier.getValue() );
    689            idElement.appendChild( idText );
    690
    691        }
    692
    693        /**
    694         * Appends the DOM representation of the given <code>DataProvider</code> to the passed
    695         * <code>Element</code>.
    696         *
    697         * @param datasetNode
    698         * @param dataProvider
    699         */
    700        private void appendDataProvider( Element datasetNode, DataProvider dataProvider ) {
    701            if ( dataProvider != null ) {
    702                Element provider = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "DataProvider" );
    703
    704                String provName = dataProvider.getProviderName();
    705                if ( provName != null ) {
    706                    Element providerName = XMLTools.appendElement( provider, WPVSNS, PRE_WPVS + "ProviderName" );
    707                    Text providerNameText = providerName.getOwnerDocument().createTextNode( provName );
    708                    providerName.appendChild( providerNameText );
    709
    710                }
    711
    712                Element providerSite = XMLTools.appendElement( provider, WPVSNS, PRE_WPVS + "ProviderSite" );
    713                URL siteURL = dataProvider.getProviderSite();
    714                String site = "";
    715                if ( siteURL != null ) {
    716                    site = siteURL.toString();
    717                }
    718                providerSite.setAttribute( "xlink:href", site );
    719
    720                Element logoURLElement = XMLTools.appendElement( provider, WPVSNS, PRE_WPVS + "LogoURL" );
    721                appendURL( logoURLElement, dataProvider.getLogoURL(), WPVSNS );
    722            }
    723        }
    724
    725        /**
    726         * Appends the DOM representations of the given array of <code>Dimension</code> to the passed
    727         * <code>Element</code>.
    728         *
    729         * @param datasetNode
    730         * @param dimensions
    731         */
    732        private void appendDimensions( Element datasetNode, Dimension[] dimensions ) {
    733            if ( dimensions != null ) {
    734                for ( Dimension dimension : dimensions ) {
    735                    if ( dimension != null ) {
    736                        Element dimensionElement = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "Dimension" );
    737                        dimensionElement.setAttribute( "name", dimension.getName() );
    738                        dimensionElement.setAttribute( "units", dimension.getUnits() );
    739                        dimensionElement.setAttribute( "unitSymbol", dimension.getUnitSymbol() );
    740                        dimensionElement.setAttribute( "default", dimension.getDefault() );
    741                        dimensionElement.setAttribute( "multipleValues",
    742                                                       ( ( dimension.getMultipleValues().booleanValue() ) ? "1" : "0" ) );
    743                        dimensionElement.setAttribute( "nearestValue",
    744                                                       ( ( dimension.getNearestValue().booleanValue() ) ? "1" : "0" ) );
    745                        dimensionElement.setAttribute( "current", ( ( dimension.getCurrent().booleanValue() ) ? "1" : "0" ) );
    746
    747                        Text dimensionText = dimensionElement.getOwnerDocument().createTextNode( dimension.getValue() );
    748                        dimensionElement.appendChild( dimensionText );
    749                    }
    750                }
    751            }
    752        }
    753
    754        /**
    755         * Appends the DOM representations of the given array of <code>Format</code> to the passed
    756         * <code>Element</code>.
    757         *
    758         * @param datasetNode
    759         * @param mimeTypeFormat
    760         */
    761        private void appendFormats( Element datasetNode, String[] mimeTypeFormat ) {
    762
    763            if ( mimeTypeFormat != null ) {
    764
    765                for ( int i = 0; i < mimeTypeFormat.length; i++ ) {
    766                    Element format = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "Format" );
    767                    Text formatText = format.getOwnerDocument().createTextNode( mimeTypeFormat[i] );
    768                    format.appendChild( formatText );
    769                }
    770            }
    771        }
    772
    773        /**
    774         * Appends the DOM representations of the given array of <code>CRS</code> to the passed
    775         * <code>Element</code>.
    776         *
    777         * @param datasetNode
    778         * @param coordinateSystems
    779         */
    780        private void appendCRSNodes( Element datasetNode, CoordinateSystem[] coordinateSystems ) {
    781
    782            if ( coordinateSystems != null ) {
    783                for ( CoordinateSystem crs : coordinateSystems ) {
    784                    Element crsElement = XMLTools.appendElement( datasetNode, WPVSNS, PRE_WPVS + "CRS" );
    785                    Text crsText = crsElement.getOwnerDocument().createTextNode( crs.getFormattedString() );
    786                    crsElement.appendChild( crsText );
    787                }
    788            }
    789        }
    790
    791        /**
    792         * Appends the DOM representation of the given parameters <code>Envelope, elementName, crsName,
    793         * dimension</code>
    794         * to the passed <code>Element</code>.
    795         *
    796         * elementName should be of the kind ows:WGS84BoundingBox" or "ows:BoundingBox". crsName should
    797         * be of the kind "urn:ogc:def:crs:OGC:2:84" or "...TODO...". dimension should be "2".
    798         *
    799         * @param root
    800         * @param envelope
    801         * @param elementName
    802         * @param crsName
    803         * @param dimension
    804         */
    805        private void appendBoundingBox( Element root, Envelope envelope, String elementName, String crsName,
    806                                        String dimension ) {
    807
    808            Element boundingBoxElement = XMLTools.appendElement( root, OWSNS, elementName );
    809            boundingBoxElement.setAttribute( "crs", crsName );
    810            boundingBoxElement.setAttribute( "dimensions", dimension );
    811
    812            Element lowerCornerElement = XMLTools.appendElement( boundingBoxElement, OWSNS, PRE_OWS + "LowerCorner" );
    813            Text lowerCornerText = lowerCornerElement.getOwnerDocument().createTextNode(
    814                                                                                         envelope.getMin().getX()
    815                                                                                                                 + " "
    816                                                                                                                 + envelope.getMin().getY() );
    817            lowerCornerElement.appendChild( lowerCornerText );
    818
    819            Element upperCornerElement = XMLTools.appendElement( boundingBoxElement, OWSNS, PRE_OWS + "UpperCorner" );
    820            Text upperCornerText = upperCornerElement.getOwnerDocument().createTextNode(
    821                                                                                         envelope.getMax().getX()
    822                                                                                                                 + " "
    823                                                                                                                 + envelope.getMax().getY() );
    824            upperCornerElement.appendChild( upperCornerText );
    825
    826        }
    827
    828    }