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