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 }