001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wmps/GetMapServiceInvokerForUL.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 Aennchenstr. 19 030 53115 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 ---------------------------------------------------------------------------*/ 043 package org.deegree.ogcwebservices.wmps; 044 045 import java.io.ByteArrayOutputStream; 046 import java.io.InputStreamReader; 047 import java.io.StringReader; 048 import java.net.URL; 049 050 import org.deegree.framework.log.ILogger; 051 import org.deegree.framework.log.LoggerFactory; 052 import org.deegree.framework.util.CharsetUtils; 053 import org.deegree.framework.util.IDGenerator; 054 import org.deegree.framework.util.NetWorker; 055 import org.deegree.framework.util.StringTools; 056 import org.deegree.framework.xml.XMLFragment; 057 import org.deegree.graphics.MapFactory; 058 import org.deegree.graphics.sld.AbstractStyle; 059 import org.deegree.graphics.sld.FeatureTypeConstraint; 060 import org.deegree.graphics.sld.LayerFeatureConstraints; 061 import org.deegree.graphics.sld.RemoteOWS; 062 import org.deegree.graphics.sld.UserLayer; 063 import org.deegree.graphics.sld.UserStyle; 064 import org.deegree.model.feature.FeatureCollection; 065 import org.deegree.model.feature.GMLFeatureCollectionDocument; 066 import org.deegree.model.filterencoding.Filter; 067 import org.deegree.ogcwebservices.OGCWebServiceException; 068 import org.deegree.ogcwebservices.wfs.WFService; 069 import org.deegree.ogcwebservices.wfs.operation.FeatureResult; 070 import org.deegree.ogcwebservices.wfs.operation.GetFeature; 071 import org.deegree.ogcwebservices.wms.capabilities.Layer; 072 import org.deegree.ogcwebservices.wms.configuration.AbstractDataSource; 073 import org.w3c.dom.Element; 074 075 /** 076 * This a copy of the WMS package. 077 * 078 * class for accessing the data of one user layer and creating <tt>DisplayElement</tt>s and a 079 * <tt>Thrme</tt> from it. The class extends <tt>Thread</tt> and implements the run method, so 080 * that a parallel data accessing from several layers is possible. 081 * 082 * @version $Revision: 9348 $ 083 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 084 * @author last edited by: $Author: apoth $ 085 * 086 * @version 1.0. $Revision: 9348 $, $Date: 2007-12-27 17:59:14 +0100 (Do, 27 Dez 2007) $ 087 * 088 * @since 2.0 089 */ 090 class GetMapServiceInvokerForUL extends Thread { 091 092 private static final ILogger LOG = LoggerFactory.getLogger( GetMapServiceInvokerForUL.class ); 093 094 private final DefaultGetMapHandler handler; 095 096 private UserLayer layer = null; 097 098 private UserStyle[] styles = null; 099 100 private int index = 0; 101 102 GetMapServiceInvokerForUL( DefaultGetMapHandler handler, UserLayer layer, int index ) { 103 this.layer = layer; 104 this.handler = handler; 105 AbstractStyle[] tmp = layer.getStyles(); 106 this.styles = new UserStyle[tmp.length]; 107 for ( int i = 0; i < tmp.length; i++ ) { 108 this.styles[i] = (UserStyle) tmp[i]; 109 } 110 111 this.index = index; 112 } 113 114 /** 115 * overrides/implements the run-method of <tt>Thread</tt> 116 */ 117 @Override 118 public void run() { 119 120 121 try { 122 if ( this.layer.getRemoteOWS() == null || this.layer.getRemoteOWS().getService().equals( RemoteOWS.WFS ) ) { 123 handleWFS(); 124 } else if ( this.layer.getRemoteOWS().getService().equals( RemoteOWS.WCS ) ) { 125 handleWCS(); 126 } 127 } catch ( Exception e ) { 128 LOG.logError( "", e ); 129 OGCWebServiceException exce = new OGCWebServiceException( 130 "ServiceInvokerForUL: " + this.layer.getName(), 131 "Couldn't perform query!" 132 + StringTools.stackTraceToString( e ) ); 133 this.handler.putTheme( this.index, exce ); 134 this.handler.increaseCounter(); 135 136 return; 137 } 138 139 140 } 141 142 /** 143 * handles requests against a WFS 144 * 145 * @throws Exception 146 */ 147 private void handleWFS() 148 throws Exception { 149 150 151 152 FeatureCollection fc = null; 153 String request = createGetFeatureRequest(); 154 155 if ( this.layer.getRemoteOWS() != null ) { 156 // handle request against a remote WFS 157 RemoteOWS remoteOWS = this.layer.getRemoteOWS(); 158 URL url = remoteOWS.getOnlineResource(); 159 NetWorker nw = new NetWorker( CharsetUtils.getSystemCharset(), url, request ); 160 InputStreamReader isr = new InputStreamReader( nw.getInputStream(), CharsetUtils.getSystemCharset() ); 161 GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument(); 162 doc.load( isr, url.toString() ); 163 Element root = doc.getRootElement(); 164 165 if ( root.getNodeName().indexOf( "Exception" ) > -1 ) { 166 ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000 ); 167 doc.write( bos ); 168 throw new Exception( new String( bos.toByteArray() ) ); 169 } 170 fc = doc.parse(); 171 } else { 172 // handle request agaist a local WFS; this is bit problematic 173 // because deegree WMS is able to handle more than one 174 // local WFS. At the moment the WFS will be used that will 175 // returned by the WFServiceFactory as default 176 XMLFragment xml = new XMLFragment( new StringReader( request ), XMLFragment.DEFAULT_URL ); 177 Element root = xml.getRootElement(); 178 // create OGCWebServiceEvent object 179 IDGenerator idg = IDGenerator.getInstance(); 180 GetFeature gfr = GetFeature.create( "" + idg.generateUniqueID(), root ); 181 182 // returns the WFS responsible for handling current feature type 183 WFService wfs = getResponsibleService(); 184 FeatureResult fr = (FeatureResult) wfs.doService( gfr ); 185 fc = (FeatureCollection) fr.getResponse(); 186 } 187 org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer( this.layer.getName(), this.handler.reqCRS, fc ); 188 this.handler.putTheme( this.index, MapFactory.createTheme( this.layer.getName(), fl, this.styles ) ); 189 this.handler.increaseCounter(); 190 191 } 192 193 /** 194 * Returns the responsible service. 195 * 196 * @return Exception 197 * @throws OGCWebServiceException 198 */ 199 private WFService getResponsibleService() 200 throws OGCWebServiceException { 201 202 LayerFeatureConstraints lfc = this.layer.getLayerFeatureConstraints(); 203 FeatureTypeConstraint[] ftc = lfc.getFeatureTypeConstraint(); 204 Layer root = this.handler.getConfiguration().getLayer(); 205 WFService wfs = findService( root, ftc[0].getFeatureTypeName().getPrefixedName() ); 206 if ( wfs == null ) { 207 throw new OGCWebServiceException( this.getName(), "feature type: " + ftc[0].getFeatureTypeName() 208 + " is not serverd by this WMS/WFS" ); 209 } 210 return wfs; 211 212 } 213 214 /** 215 * searches/findes the WFService that is resposible for handling the feature types of the 216 * current request. If no WFService instance can be found <code>null</code> will be returned 217 * to indicated that the current feature type is not served by the internal WFS of a WMS 218 * 219 * @param currentlayer 220 * @param featureType 221 * @return WFService 222 * @throws OGCWebServiceException 223 */ 224 private WFService findService( Layer currentlayer, String featureType ) 225 throws OGCWebServiceException { 226 Layer[] layers = currentlayer.getLayer(); 227 for ( int i = 0; i < layers.length; i++ ) { 228 AbstractDataSource[] ad = layers[i].getDataSource(); 229 if ( ad != null ) { 230 for ( int j = 0; j < ad.length; j++ ) { 231 if ( ad[j].getName().getPrefixedName().equals( featureType ) ) { 232 return (WFService) ad[j].getOGCWebService(); 233 } 234 } 235 } 236 // recursion 237 WFService wfs = findService( layers[i], featureType ); 238 if ( wfs != null ) { 239 return wfs; 240 } 241 } 242 243 return null; 244 } 245 246 /** 247 * creates a GetFeature request related to the UserLayer encapsulated in this object 248 * 249 * @return String 250 * @throws Exception 251 */ 252 private String createGetFeatureRequest() 253 throws Exception { 254 255 LayerFeatureConstraints lfc = this.layer.getLayerFeatureConstraints(); 256 FeatureTypeConstraint[] ftc = lfc.getFeatureTypeConstraint(); 257 258 // no filter condition has been defined 259 StringBuffer sb = new StringBuffer( 5000 ); 260 sb.append( "<?xml version='1.0' encoding='UTF-8'?>" ); 261 sb.append( "<GetFeature xmlns='http://www.opengis.net/wfs' " ); 262 sb.append( "xmlns:ogc='http://www.opengis.net/ogc' " ); 263 sb.append( "xmlns:gml='http://www.opengis.net/gml' " ); 264 sb.append( "xmlns:app=\"http://www.deegree.org/app\" " ); 265 sb.append( "service='WFS' version='1.1.0' " ); 266 sb.append( "outputFormat='text/xml; subtype=gml/3.1.1'>" ); 267 for ( int i = 0; i < ftc.length; i++ ) { 268 sb.append( "<Query typeName='" + ftc[i].getFeatureTypeName() + "'>" ); 269 Filter filter = ftc[i].getFilter(); 270 if ( filter != null ) { 271 sb.append( filter.toXML() ); 272 } 273 sb.append( "</Query>" ); 274 } 275 sb.append( "</GetFeature>" ); 276 277 return sb.toString(); 278 } 279 280 /** 281 * handles requests against a WCS 282 * 283 * @throws Exception 284 */ 285 private void handleWCS() 286 throws Exception { 287 throw new UnsupportedOperationException( "The WCS support has not been implemented as of now. " 288 + "Please bear with us." ); 289 /* 290 * TODO RemoteOWS remoteOWS = layer.getRemoteOWS(); URL url = remoteOWS.getOnlineResource(); 291 * 292 * NetWorker nw = new NetWorker( url ); MemoryCacheSeekableStream mcss = new 293 * MemoryCacheSeekableStream( nw.getInputStream() ); 294 * 295 * RenderedOp rop = JAI.create("stream", mcss); 296 * 297 * GC_GridCoverage gc = new ImageGridCoverage(rop.getAsBufferedImage(), 298 * request.getBoundingBox(), reqCRS, false); mcss.close(); 299 * 300 * org.deegree.graphics.Layer rl = MapFactory.createRasterLayer(layer.getName(), gc); 301 * 302 * putTheme(index, MapFactory.createTheme(layer.getName(), rl)); mcss.close(); 303 * increaseCounter(); 304 */ 305 306 } 307 }