    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/sos/describesensor/SensorDescriptionDocument.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.ogcwebservices.sos.describesensor;
    037
    038    import java.io.IOException;
    039    import java.net.URI;
    040    import java.net.URL;
    041    import java.util.ArrayList;
    042    import java.util.Hashtable;
    043    import java.util.Iterator;
    044    import java.util.List;
    045
    046    import javax.xml.transform.TransformerException;
    047
    048    import org.deegree.datatypes.QualifiedName;
    049    import org.deegree.framework.log.ILogger;
    050    import org.deegree.framework.log.LoggerFactory;
    051    import org.deegree.framework.xml.XMLParsingException;
    052    import org.deegree.framework.xml.XMLTools;
    053    import org.deegree.ogcwebservices.OGCWebService;
    054    import org.deegree.ogcwebservices.OGCWebServiceException;
    055    import org.deegree.ogcwebservices.sos.ComponentDescriptionDocument;
    056    import org.deegree.ogcwebservices.sos.WFSRequestGenerator;
    057    import org.deegree.ogcwebservices.sos.WFSRequester;
    058    import org.deegree.ogcwebservices.sos.XMLFactory;
    059    import org.deegree.ogcwebservices.sos.XSLTransformer;
    060    import org.deegree.ogcwebservices.sos.configuration.MeasurementConfiguration;
    061    import org.deegree.ogcwebservices.sos.configuration.SOSDeegreeParams;
    062    import org.deegree.ogcwebservices.sos.configuration.SensorConfiguration;
    063    import org.deegree.ogcwebservices.sos.sensorml.BasicResponse;
    064    import org.deegree.ogcwebservices.sos.sensorml.Classifier;
    065    import org.deegree.ogcwebservices.sos.sensorml.ComponentDescription;
    066    import org.deegree.ogcwebservices.sos.sensorml.EngineeringCRS;
    067    import org.deegree.ogcwebservices.sos.sensorml.Identifier;
    068    import org.deegree.ogcwebservices.sos.sensorml.LocationModel;
    069    import org.deegree.ogcwebservices.sos.sensorml.Phenomenon;
    070    import org.deegree.ogcwebservices.sos.sensorml.Product;
    071    import org.deegree.ogcwebservices.sos.sensorml.ResponseModel;
    072    import org.deegree.ogcwebservices.sos.sensorml.TypedQuantity;
    073    import org.w3c.dom.Document;
    074    import org.w3c.dom.Node;
    075    import org.xml.sax.SAXException;
    076
    077    /**
    078     * reads the metadata of a sensor from the xsl transformed result from a wfs
    079     *
    080     * @author <a href="mailto:mkulbe@lat-lon.de">Matthias Kulbe </a>
    081     *
    082     */
    083    public class SensorDescriptionDocument extends ComponentDescriptionDocument {
    084
    085        /**
    086         *
    087         */
    088        private static final long serialVersionUID = -6126811730624541654L;
    089
    090        private static final ILogger LOG = LoggerFactory.getLogger( XMLFactory.class );
    091
    092        private static final String XML_TEMPLATE = "DescribeSensorTemplate.xml";
    093
    094        /*
    095         * (non-Javadoc)
    096         *
    097         * @see org.deegree.ogcwebservices.sos.ComponentDescriptionDocument#createEmptyDocument()
    098         */
    099        @Override
    100        public void createEmptyDocument()
    101                                throws IOException, SAXException {
    102            URL url = SensorDescriptionDocument.class.getResource( XML_TEMPLATE );
    103            if ( url == null ) {
    104                throw new IOException( "The resource '" + XML_TEMPLATE + " could not be found." );
    105            }
    106            load( url );
    107        }
    108
    109        /**
    110         *
    111         * @param deegreeParams
    112         * @param typNames
    113         * @return the sensot metadata
    114         * @throws OGCWebServiceException
    115         */
    116        public SensorMetadata[] getSensor( SOSDeegreeParams deegreeParams, String[] typNames )
    117                                throws OGCWebServiceException {
    118            try {
    119
    120                // gets the documents from wfs server
    121                Document[] docs = getSourceServerDocuments( deegreeParams, typNames );
    122
    123                ArrayList<SensorMetadata> sensorMetadata = new ArrayList<SensorMetadata>( docs.length );
    124                for ( int d = 0; d < docs.length; d++ ) {
    125
    126                    if ( docs[d] != null ) {
    127
    128                        List<Node> nl = XMLTools.getNodes( docs[d], "sml:Sensors/sml:Sensor", nsContext );
    129
    130                        if ( nl.size() < 1 ) {
    131                            LOG.logError( "no sensors found in wfs result document" );
    132                        }
    133
    134                        // process all sensors in document
    135                        for ( int y = 0; y < nl.size(); y++ ) {
    136
    137                            Node sensorNode = nl.get( y );
    138
    139                            String actIdPropertyValue = XMLTools.getRequiredNodeAsString( sensorNode, "@id", nsContext );
    140
    141                            // get identifiedAs
    142                            ArrayList<Identifier> identifiers = new ArrayList<Identifier>();
    143                            List<Node> identifierList = XMLTools.getNodes( sensorNode, "sml:identifiedAs", nsContext );
    144                            if ( ( identifierList == null ) || ( identifierList.size() <= 0 ) ) {
    145                                throw new XMLParsingException( "at least one identifiedAs required" );
    146
    147                            }
    148                            for ( int i = 0; i < identifierList.size(); i++ ) {
    149                                identifiers.add( getIdentifiedAs( identifierList.get( i ) ) );
    150                            }
    151
    152                            // get ClassifiedAs
    153                            List<Node> classifierList = XMLTools.getNodes( sensorNode, "sml:classifiedAs", nsContext );
    154                            ArrayList<Classifier> classifiers = new ArrayList<Classifier>( classifierList.size() );
    155                            for ( int i = 0; i < classifierList.size(); i++ ) {
    156                                classifiers.add( getClassifiedAs( classifierList.get( i ) ) );
    157                            }
    158
    159                            // get attachedTo
    160                            String attachedTo = getAttachedTo( XMLTools.getNode( sensorNode, "sml:attachedTo", nsContext ) );
    161
    162                            // get hasCRS
    163                            EngineeringCRS hasCRS = getHasCRS( XMLTools.getNode( sensorNode, "sml:hasCRS", nsContext ) );
    164
    165                            // get locatedUsing
    166                            List<Node> locationModelList = XMLTools.getNodes( sensorNode, "sml:locatedUsing", nsContext );
    167                            ArrayList<LocationModel> locationModels = new ArrayList<LocationModel>(
    168                                                                                                    locationModelList.size() );
    169                            for ( int i = 0; i < locationModelList.size(); i++ ) {
    170                                locationModels.add( getLocatedUsing( locationModelList.get( i ) ) );
    171                            }
    172
    173                            // getdescribedBy
    174                            ComponentDescription describedBy = getDescribedBy( XMLTools.getNode( sensorNode,
    175                                                                                                 "sml:describedBy",
    176                                                                                                 nsContext ) );
    177
    178                            // TODO---------add the products from Configuration
    179                            SensorConfiguration temp = deegreeParams.getSensorConfigurationByIdPropertyValue( actIdPropertyValue );
    180
    181                            MeasurementConfiguration[] measurements = temp.getMeasurementConfigurations();
    182
    183                            if ( ( measurements == null ) || ( measurements.length < 1 ) ) {
    184                                throw new XMLParsingException( "at least one measures needed" );
    185                            }
    186
    187                            // get measures
    188                            ArrayList<Product> measures = new ArrayList<Product>( measurements.length );
    189                            for ( int i = 0; i < measurements.length; i++ ) {
    190
    191                                // Identifier anlegen
    192                                Identifier[] ti = new Identifier[] { new Identifier( measurements[i].getId() ) };
    193
    194                                // observable anlegen
    195                                Phenomenon phen = new Phenomenon( measurements[i].getPhenomenon(), null, null );
    196
    197                                ResponseModel[] resm = null;
    198                                if ( measurements[i].getTimeResolution() != null ) {
    199                                    // derivedfrom anlegen
    200                                    double dd = Double.parseDouble( measurements[i].getTimeResolution() );
    201                                    URI uri = new URI( measurements[i].getTimeResolutionType() );
    202                                    TypedQuantity typedQan = new TypedQuantity( dd, uri );
    203
    204                                    Object[] o = new Object[] { new BasicResponse( typedQan ) };
    205                                    resm = new ResponseModel[] { new ResponseModel( null, null, null, null, o ) };
    206                                }
    207                                // product anlegen und zur liste hinzuf�gen
    208                                Product product = new Product( ti, null, null, null, resm, null, phen, null );
    209                                measures.add( product );
    210                            }
    211
    212                            // --end of measurments
    213
    214                            // add act Metadata to ArrayList
    215                            Identifier[] i1 = identifiers.toArray( new Identifier[identifiers.size()] );
    216                            Classifier[] c1 = classifiers.toArray( new Classifier[classifiers.size()] );
    217                            LocationModel[] l1 = new LocationModel[locationModels.size()];
    218                            l1 = locationModels.toArray( l1 );
    219                            Product[] p1 = measures.toArray( new Product[measures.size()] );
    220                            sensorMetadata.add( new SensorMetadata( i1, c1, hasCRS, l1, describedBy, attachedTo, p1 ) );
    221                        }
    222                    }
    223                }
    224
    225                // return the Array with Sensormetadata
    226                return sensorMetadata.toArray( new SensorMetadata[sensorMetadata.size()] );
    227
    228            } catch ( Exception e ) {
    229                e.printStackTrace();
    230                throw new OGCWebServiceException( "scs webservice failure" );
    231            }
    232        }
    233
    234        /**
    235         *
    236         * @param dp
    237         * @param typNames
    238         * @return the documents
    239         * @throws IOException
    240         * @throws IOException
    241         * @throws SAXException
    242         * @throws XMLParsingException
    243         * @throws TransformerException
    244         */
    245        @SuppressWarnings("deprecation")
    246        private Document[] getSourceServerDocuments( SOSDeegreeParams dp, String[] typNames )
    247                                throws IOException, SAXException, XMLParsingException, TransformerException,
    248                                OGCWebServiceException {
    249
    250            ArrayList<Document> transformedDocuments = new ArrayList<Document>();
    251
    252            Hashtable<String, ArrayList<String>> servers = new Hashtable<String, ArrayList<String>>();
    253
    254            for ( int t = 0; t < typNames.length; t++ ) {
    255                String sourceServerId = dp.getSensorConfiguration( typNames[t] ).getSourceServerId();
    256
    257                // server schon in liste; nur sensor hinzuf�gen
    258                if ( servers.containsKey( sourceServerId ) ) {
    259                    servers.get( sourceServerId ).add( typNames[t] );
    260                }
    261                // server nicht in liste; server hinzuf�gen und sensor hinzuf�gen
    262                else {
    263                    ArrayList<String> temp = new ArrayList<String>();
    264                    temp.add( typNames[t] );
    265                    servers.put( sourceServerId, temp );
    266                }
    267
    268            }
    269
    270            // request all servers from servers hashtable
    271            Iterator<String> iter = servers.keySet().iterator();
    272            while ( iter.hasNext() ) {
    273
    274                String key = iter.next();
    275                List<String> sensorIds = servers.get( key );
    276
    277                String[] idProps = new String[sensorIds.size()];
    278                for ( int a = 0; a < sensorIds.size(); a++ ) {
    279                    idProps[a] = sensorIds.get( a );
    280                }
    281
    282                QualifiedName sdft = dp.getSourceServerConfiguration( key ).getSensorDescriptionFeatureType();
    283                QualifiedName sdid = dp.getSourceServerConfiguration( key ).getSensorDescriptionIdPropertyName();
    284                Document request = WFSRequestGenerator.createIsLikeOperationWFSRequest( idProps, sdft, sdid );
    285
    286                OGCWebService ows = dp.getSourceServerConfiguration( key ).getDataService();
    287                Document result = null;
    288                try {
    289                    result = WFSRequester.sendWFSrequest( request, ows );
    290                } catch ( Exception e ) {
    291                    LOG.logError( "could not sensor data from DataService", e );
    292                    throw new OGCWebServiceException( this.getClass().getName(), "could not sensor"
    293                                                                                 + " data from DataService"
    294                                                                                 + e.getMessage() );
    295                }
    296                if ( result != null ) {
    297                    transformedDocuments.add( XSLTransformer.transformDocument(
    298                                                                                result,
    299                                                                                dp.getSourceServerConfiguration( key ).getSensorDescriptionXSLTScriptSource() ) );
    300                }
    301
    302            }
    303
    304            return transformedDocuments.toArray( new Document[transformedDocuments.size()] );
    305        }
    306    }