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 }