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 }