001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }