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