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 }