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 }