001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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    }