001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/portal/standard/wfs/control/WFSClientListener.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
037 package org.deegree.portal.standard.wfs.control;
038
039 import java.io.BufferedReader;
040 import java.io.File;
041 import java.io.FileReader;
042 import java.io.IOException;
043 import java.io.InputStream;
044 import java.io.InputStreamReader;
045 import java.net.URL;
046
047 import javax.servlet.http.HttpServletRequest;
048 import javax.servlet.http.HttpSession;
049
050 import org.apache.commons.httpclient.HttpClient;
051 import org.apache.commons.httpclient.methods.PostMethod;
052 import org.apache.commons.httpclient.methods.StringRequestEntity;
053 import org.deegree.enterprise.WebUtils;
054 import org.deegree.enterprise.control.AbstractListener;
055 import org.deegree.enterprise.control.FormEvent;
056 import org.deegree.enterprise.control.RPCMember;
057 import org.deegree.enterprise.control.RPCParameter;
058 import org.deegree.enterprise.control.RPCStruct;
059 import org.deegree.enterprise.control.RPCWebEvent;
060 import org.deegree.framework.log.ILogger;
061 import org.deegree.framework.log.LoggerFactory;
062 import org.deegree.framework.util.CharsetUtils;
063 import org.deegree.framework.util.StringTools;
064 import org.deegree.framework.xml.XMLFragment;
065 import org.deegree.model.feature.FeatureCollection;
066 import org.deegree.model.feature.GMLFeatureAdapter;
067 import org.deegree.model.feature.GMLFeatureCollectionDocument;
068 import org.deegree.portal.context.AbstractFrontend;
069 import org.deegree.portal.context.GeneralExtension;
070 import org.deegree.portal.context.Module;
071 import org.deegree.portal.context.ViewContext;
072 import org.deegree.portal.standard.wfs.WFSClientException;
073
074 /**
075 * The WFSClientListener 1. receives an RPC request, 2. builds a request to a WFS service using the values given in the
076 * RPC request, 3. sends the request to the specified WFS, 4. receives the result from the WFS and 5. forwards the
077 * result to the WFSClient.
078 *
079 * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
080 * @author last edited by: $Author: mschneider $
081 *
082 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
083 */
084 public class WFSClientListener extends AbstractListener {
085
086 private static final ILogger LOG = LoggerFactory.getLogger( WFSClientListener.class );
087
088 protected static final String INIT_TARGETSRS = "TARGETSRS";
089
090 protected static final String INIT_XSLT = "XSLT";
091
092 /*
093 * (non-Javadoc)
094 *
095 * @see org.deegree.enterprise.control.WebListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
096 */
097 @Override
098 public void actionPerformed( FormEvent event ) {
099
100 RPCWebEvent rpcEvent = (RPCWebEvent) event;
101
102 try {
103 validateRequest( rpcEvent );
104 } catch ( Exception e ) {
105 LOG.logError( e.getMessage(), e );
106 gotoErrorPage( "Invalid rpc request: \n" + e.getMessage() );
107
108 return;
109 }
110
111 try {
112 doGetFeature( rpcEvent );
113 } catch ( Exception e ) {
114 LOG.logError( e.getMessage(), e );
115 gotoErrorPage( "doGetFeature not successful: \n" + e.getMessage() );
116
117 return;
118 }
119
120 }
121
122 /**
123 * TODO check validation: are all elements checked? which elements are mandatory? ...?
124 *
125 * @param rpcEvent
126 * @throws WFSClientException
127 */
128 private void validateRequest( RPCWebEvent rpcEvent )
129 throws WFSClientException {
130
131 RPCParameter[] params = rpcEvent.getRPCMethodCall().getParameters();
132 if ( params.length != 1 ) {
133
134 throw new WFSClientException( "Request/Method Call must contain one parameter, not: " + params.length );
135 }
136
137 RPCStruct rpcStruct = (RPCStruct) params[0].getValue();
138
139 if ( rpcStruct.getMember( "MODULE" ) == null ) {
140
141 throw new WFSClientException( "Request does not contain mandatory element MODULE." );
142 }
143
144 String tmp = (String) rpcStruct.getMember( "MODULE" ).getValue();
145 if ( tmp == null || tmp.length() < 1 ) {
146
147 throw new WFSClientException( "Mandatory element MODULE must be set." );
148 }
149 try {
150 if ( rpcStruct.getMember( "FEATURETYPES" ) != null ) {
151 tmp = (String) rpcStruct.getMember( "FEATURETYPES" ).getValue();
152 // LOG.logDebug( "FEATURETYPES: " + tmp );
153 }
154 if ( rpcStruct.getMember( "QUERYTEMPLATE" ) != null ) {
155 tmp = (String) rpcStruct.getMember( "QUERYTEMPLATE" ).getValue();
156 // LOG.logDebug( "QUERYTEMPLATE: " + tmp );
157 }
158 if ( rpcStruct.getMember( "FILTER" ) != null ) {
159 tmp = (String) rpcStruct.getMember( "FILTER" ).getValue();
160 // LOG.logDebug( "FILTER: " + tmp );
161 }
162 if ( rpcStruct.getMember( "FILTERPROPERTIES" ) != null ) {
163 tmp = (String) rpcStruct.getMember( "FILTERPROPERTIES" ).getValue();
164 // LOG.logDebug( "FILTERPROPERTIES: " + tmp );
165 }
166 if ( rpcStruct.getMember( "RESULTFORMAT" ) != null ) {
167 tmp = (String) rpcStruct.getMember( "RESULTFORMAT" ).getValue();
168 // LOG.logDebug( "RESULTFORMAT: " + tmp );
169 }
170 if ( rpcStruct.getMember( "XMLNS" ) != null ) {
171 tmp = (String) rpcStruct.getMember( "XMLNS" ).getValue();
172 // LOG.logDebug( "XMLNS: " + tmp );
173 }
174 if ( rpcStruct.getMember( "NORMALIZE" ) != null ) {
175 Boolean shouldNormalize = (Boolean) rpcStruct.getMember( "NORMALIZE" ).getValue();
176 LOG.logDebug( "NORMALIZE: " + shouldNormalize );
177 }
178 if ( rpcStruct.getMember( "LOCALE" ) != null ) {
179 tmp = (String) rpcStruct.getMember( "LOCALE" ).getValue();
180 // LOG.logDebug( "LOCALE: " + tmp );
181 }
182 if ( rpcStruct.getMember( "SESSIONID" ) != null ) {
183 tmp = (String) rpcStruct.getMember( "SESSIONID" ).getValue();
184 // LOG.logDebug( "SESSIONID: " + tmp );
185 }
186 } catch ( Exception e ) {
187 LOG.logError( e.getMessage(), e );
188
189 throw new WFSClientException( "Member of rpc request must not be null or empty: ", e );
190 }
191
192 }
193
194 /**
195 *
196 * @param rpcEvent
197 * @throws WFSClientException
198 */
199 protected void doGetFeature( RPCWebEvent rpcEvent )
200 throws WFSClientException {
201
202 RPCParameter[] params = rpcEvent.getRPCMethodCall().getParameters();
203 RPCStruct rpcStruct = (RPCStruct) params[0].getValue();
204
205 // xml namespaces
206 String tmp = null;
207 RPCMember rpcMember = rpcStruct.getMember( "XMLNS" );
208 String[] xmlns = null;
209 if ( rpcMember != null ) {
210 tmp = (String) rpcMember.getValue();
211 }
212 if ( tmp == null ) {
213 xmlns = new String[0];
214 } else {
215 xmlns = StringTools.toArray( tmp, ",", true );
216 }
217
218 // NORMALIZATION
219 // check if the query string needs to be normalized
220 Boolean getsNormalized = false;
221 rpcMember = rpcStruct.getMember( "NORMALIZE" );
222 if ( rpcMember != null ) {
223 getsNormalized = (Boolean) rpcMember.getValue();
224 }
225 // set locale for normalization
226 String locale = null;
227 if ( getsNormalized ) {
228 rpcMember = rpcStruct.getMember( "LOCALE" );
229 if ( rpcMember != null ) {
230 locale = (String) rpcMember.getValue();
231 } else {
232 locale = "default";
233 }
234 }
235
236 // CREATE QUERY
237 // featuretypes to query
238 rpcMember = rpcStruct.getMember( "FEATURETYPES" );
239 tmp = (String) rpcMember.getValue();
240 String[] featureTypes = StringTools.toArray( tmp, ",", true );
241
242 String moduleName = (String) rpcStruct.getMember( "MODULE" ).getValue();
243 String query = null;
244
245 // use template or filter to build query
246 if ( rpcStruct.getMember( "QUERYTEMPLATE" ) != null ) {
247 String queryTemplate = (String) rpcStruct.getMember( "QUERYTEMPLATE" ).getValue();
248 RPCMember filterProperties = rpcStruct.getMember( "FILTERPROPERTIES" );
249 RPCMember sessionId = rpcStruct.getMember( "SESSIONID" );
250 try {
251 query = createQueryFromTemplate( queryTemplate, moduleName, filterProperties, sessionId,
252 getsNormalized, locale );
253 } catch ( Exception e ) {
254 LOG.logError( e.getMessage(), e );
255
256 throw new WFSClientException( "Could not create query from template: " + e.getMessage() );
257 }
258 getRequest().setAttribute( "QUERYTEMPLATE", queryTemplate );
259
260 } else if ( rpcStruct.getMember( "FILTER" ) != null ) {
261 // TODO this is not implemented yet
262 String filter = (String) rpcStruct.getMember( "FILTER" ).getValue();
263 query = createQueryFromFilter( featureTypes, xmlns, filter, getsNormalized, locale );
264 } else {
265 // TODO reactivate this option
266 // String filter = createFilterFromProperties();
267 // query = createQueryFromFilter( featureTypes, xmlns, filter, getsNormalized );
268 throw new WFSClientException( "could not create query" );
269 }
270
271 // PERFORM QUERY
272 // LOG.logDebug( "\n***** QUERY *****\n" + query + "\n" );
273 XMLFragment response = performQuery( query, moduleName );
274 // LOG.logDebug( "\n***** RESPONSE *****\n" + response.getAsString() + "\n" );
275
276 FeatureCollection fc = null;
277 try {
278 GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument();
279 doc.setRootElement( response.getRootElement() );
280 fc = doc.parse();
281 } catch ( Exception e ) {
282 // DOMPrinter.printNode( response.getRootElement(), " " );
283 LOG.logError( e.getMessage(), e );
284
285 throw new WFSClientException( "Could not build FeatureCollection from xml Document: " + e.getMessage() );
286 }
287 // TODO replace initParam
288 // if ( getInitParam( INIT_TARGETSRS ) != null ) {
289 // try {
290 // // TODO comment in again when needed
291 // fc = transformGeometries( fc );
292 // } catch ( Exception e ) {
293 // LOG.logError( e.getMessage(), e );
294 //
295 // throw new WFSClientException( "Could not transform geometries in FeatureCollection." );
296 // }
297 // }
298
299 String resultFormat = null;
300 rpcMember = rpcStruct.getMember( "RESULTFORMAT" );
301 if ( rpcMember != null ) {
302 resultFormat = (String) rpcMember.getValue();
303 }
304 if ( !"XML".equals( resultFormat ) && !"FEATURECOLLECTION".equals( resultFormat ) ) {
305 throw new WFSClientException( "resultFormat" );
306 }
307
308 // WRITE FEATURE RESULTS BACK TO CLIENT
309 try {
310 writeGetFeatureResult( fc, resultFormat );
311 } catch ( Exception e ) {
312 LOG.logError( e.getMessage(), e );
313
314 throw new WFSClientException( "Could not write getFeatureResult: " + e.getMessage() );
315 }
316
317 }
318
319 /**
320 * Creates a WFS GetFeature query from a named template and a set of KVP-encoded properties.
321 *
322 * @param queryTemplate
323 * @param moduleName
324 * @param filterProperties
325 * @param sessionId
326 * the users session id. may be null.
327 * @param getsNormalized
328 * if true, the filter string gets normalized
329 * @param locale
330 * the locale language defining the normalization rules to choose, e.g. "de"
331 * @return Returns the WFS GetFeature query as String.
332 * @throws WFSClientException
333 */
334 private String createQueryFromTemplate( String queryTemplate, String moduleName, RPCMember filterProperties,
335 RPCMember sessionId, Boolean getsNormalized, String locale )
336 throws WFSClientException {
337
338 HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
339 ViewContext vc = (ViewContext) session.getAttribute( org.deegree.portal.Constants.CURRENTMAPCONTEXT );
340
341 GeneralExtension ge = vc.getGeneral().getExtension();
342 AbstractFrontend fe = (AbstractFrontend) ge.getFrontend();
343 Module module = null;
344 Module[] mods = fe.getModulesByName( moduleName );
345 if ( mods.length > 0 ) {
346 module = mods[0];
347 } else {
348 LOG.logError( "no module with the name" + moduleName + "could be found." );
349
350 throw new WFSClientException( "The current map context does not contain the module:" + moduleName );
351 }
352
353 queryTemplate = (String) module.getParameter().getParameter( queryTemplate ).getValue();
354 if ( queryTemplate.startsWith( "'" ) && queryTemplate.endsWith( "'" ) ) {
355 // strip ' from front and end of string
356 queryTemplate = queryTemplate.substring( 1, queryTemplate.length() - 1 );
357 }
358
359 if ( !( new File( queryTemplate ).isAbsolute() ) ) {
360 queryTemplate = getHomePath() + queryTemplate;
361 LOG.logDebug( "The template file now has an absolute path: " + queryTemplate );
362 }
363 StringBuffer template = new StringBuffer( 10000 );
364 try {
365 BufferedReader br = new BufferedReader( new FileReader( queryTemplate ) );
366 String line = null;
367 while ( ( line = br.readLine() ) != null ) {
368 template.append( line );
369 }
370 br.close();
371 } catch ( IOException e ) {
372 LOG.logError( e.getMessage(), e );
373
374 throw new WFSClientException( "could not read query template: " + queryTemplate );
375 }
376 String query = template.toString();
377
378 // SUBSTITUTE FILTER PROPERTIES
379 String tmp = null;
380 if ( filterProperties != null ) {
381 tmp = (String) filterProperties.getValue(); // tmp={myKey=searchStringXXX}{key2=value2}
382 }
383
384 if ( tmp != null ) {
385 String[] properties = StringTools.extractStrings( tmp, "{", "}" );
386
387 for ( int i = 0; i < properties.length; i++ ) {
388 if ( properties[i].startsWith( "{" ) ) {
389 properties[i] = properties[i].substring( 1, properties[i].length() );
390 }
391 if ( properties[i].endsWith( "}" ) ) {
392 properties[i] = properties[i].substring( 0, properties[i].length() - 1 );
393 }
394
395 String[] kvp = StringTools.toArray( properties[i], "=", false );
396 // FIXME instead of using "%" as wildcard: read the wildcard character from the
397 // template!
398 kvp[1] = StringTools.replace( kvp[1], "XXX", "%", true );
399
400 if ( getsNormalized ) {
401 try {
402 kvp[1] = StringTools.normalizeString( kvp[1], locale );
403 } catch ( Exception e ) {
404 LOG.logError( "the search string of the filter property could not be normalized", e );
405 throw new WFSClientException( e.getMessage(), e );
406 }
407 }
408 query = StringTools.replace( query, '$' + kvp[0], kvp[1], true );
409 }
410 }
411
412 // SUBSTITUTE SESSION_ID
413 tmp = null;
414 if ( sessionId != null ) {
415 tmp = (String) sessionId.getValue();
416 }
417 query = StringTools.replace( query, "$SESSION_ID", tmp, true );
418
419 return query;
420 }
421
422 /**
423 * Creates a WFS GetFeature query from a OGC filter expression sent from a client.
424 *
425 * TODO: implement support for getNormalized
426 *
427 * @param featureTypes
428 * @param xmlns
429 * @param filter
430 * @param getsNormalized
431 * if true, the filter string gets normalized
432 * @param locale
433 * the locale language defining the normalization rules to choose, e.g. "de"
434 * @return Returns the WFS GetFeature query as String.
435 */
436 private String createQueryFromFilter( String[] featureTypes, String[] xmlns, String filter, Boolean getsNormalized,
437 String locale ) {
438
439 // TODO handle SESSIONID if it is part of the rpc request
440
441 // normalize filter if needed
442 if ( getsNormalized ) {
443 // FIXME remove try-catch.
444 // TODO Proper implementation of method doNormalizeFilter().
445 try {
446 filter = doNormalizeFilter( filter, locale );
447 } catch ( Exception e ) {
448 LOG.logError( "Could not normalize filter.", e );
449 }
450 }
451
452 StringBuffer query = new StringBuffer( 20000 );
453 String format = "text/xml; subtype=gml/3.1.1";
454 String resultType = "results";
455
456 // TODO get values for parameters from rpc Request
457 // if ( parameter.get( "OUTPUTFORMAT" ) != null ) {
458 // format = (String) parameter.get( "OUTPUTFORMAT" );
459 // }
460 // if ( parameter.get( "RESULTTYPE" ) != null ) {
461 // resultType = (String) parameter.get( "RESULTTYPE" );
462 // }
463
464 query.append( "<wfs:GetFeature outputFormat='" ).append( format );
465 query.append( " resultType='" ).append( resultType ).append( "' " );
466
467 for ( int i = 0; i < xmlns.length; i++ ) {
468 String[] tmp = StringTools.toArray( xmlns[i], "=", false );
469 query.append( "xmlns:" ).append( tmp[0] ).append( "='" );
470 query.append( tmp[1] ).append( "' " );
471 }
472 query.append( "xmlns:wfs='http://www.opengis.net/wfs' " );
473 query.append( "xmlns:ogc='http://www.opengis.net/ogc' " );
474 query.append( "xmlns:gml='http://www.opengis.net/gml' " );
475 query.append( ">" );
476
477 query.append( "<wfs:Query " );
478 for ( int i = 0; i < featureTypes.length; i++ ) {
479 query.append( "typeName='" ).append( featureTypes[i] );
480 if ( i < featureTypes.length - 1 ) {
481 query.append( "," );
482 }
483 }
484 query.append( "'>" );
485 query.append( filter );
486 query.append( "</wfs:Query></wfs:GetFeature>" );
487
488 return query.toString();
489 }
490
491 // /**
492 // * creates an OGC FE filter from a set of KVP-encode properties and logical operations
493 // *
494 // * @return
495 // */
496 // private String createFilterFromProperties() {
497 // // TODO normalization
498 // // TODO handle SESSIONID if it is part of the rpc request
499 //
500 // String tmp = (String) parameter.get( "FILTERPROPERTIES" );
501 // if ( tmp != null ) {
502 // String[] properties = StringExtend.extractArray( tmp, "{", "}" );
503 // String logOp = (String) parameter.get( "LOGICALOPERATOR" );
504 // StringBuffer filter = new StringBuffer( 10000 );
505 // filter.append( "<ogc:Filter>" );
506 // if ( properties.length > 1 ) {
507 // filter.append( "<ogc:" ).append( logOp ).append( '>' );
508 // }
509 // for ( int i = 0; i < properties.length; i++ ) {
510 // String[] prop = StringExtend.extractArray( tmp, "[", "]" );
511 // if ( "!=".equals( prop[1] ) || "NOT LIKE".equals( prop[1] ) ) {
512 // filter.append( "<ogc:Not>" );
513 // }
514 // if ( "=".equals( prop[1] ) || "!=".equals( prop[1] ) ) {
515 // filter.append( "<ogc:PropertyIsEqualTo>" );
516 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
517 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
518 // filter.append( "</ogc:PropertyIsEqualTo>" );
519 // } else if ( ">=".equals( prop[1] ) ) {
520 // filter.append( "<ogc:PropertyIsGreaterThanOrEqualTo>" );
521 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
522 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
523 // filter.append( "</ogc:PropertyIsGreaterThanOrEqualTo>" );
524 // } else if ( ">".equals( prop[1] ) ) {
525 // filter.append( "<ogc:PropertyIsGreaterThan>" );
526 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
527 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
528 // filter.append( "</ogc:PropertyIsGreaterThan>" );
529 // } else if ( "<=".equals( prop[1] ) ) {
530 // filter.append( "<ogc:PropertyIsLessThanOrEqualTo>" );
531 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
532 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
533 // filter.append( "</ogc:PropertyIsLessThanOrEqualTo>" );
534 // } else if ( "<".equals( prop[1] ) ) {
535 // filter.append( "<ogc:PropertyIsLessThan>" );
536 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
537 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
538 // filter.append( "</ogc:PropertyIsLessThan>" );
539 // } else if ( "LIKE".equals( prop[1] ) || "NOT LIKE".equals( prop[1] ) ) {
540 // filter.append( "<ogc:PropertyIsLike wildCard='%' singleChar='#' escape='!'>" );
541 // filter.append( "<ogc:PropertyName>" ).append( prop[0] ).append( "</ogc:PropertyName>" );
542 // filter.append( "<ogc:Literal>" ).append( prop[2] ).append( "</ogc:Literal>" );
543 // filter.append( "</ogc:PropertyIsLike>" );
544 // }
545 // if ( "!=".equals( prop[1] ) || "NOT LIKE".equals( prop[1] ) ) {
546 // filter.append( "</ogc:Not>" );
547 // }
548 // }
549 // if ( properties.length > 1 ) {
550 // filter.append( "</ogc:" ).append( logOp ).append( '>' );
551 // }
552 // filter.append( "</ogc:Filter>" );
553 // return filter.toString();
554 // }
555 // return "";
556 // }
557
558 /**
559 * Replace the filter string with a normalized version.
560 *
561 * @param filter
562 * @param locale
563 * the locale language defining the normalization rules to choose, e.g. "de"
564 * @return the query with a normalized filter if query cannot be transformed to XMLFragment
565 */
566 private String doNormalizeFilter( String filter, String locale ) {
567
568 throw new UnsupportedOperationException( "this method is not fully implemented yet" );
569
570 //
571 //
572 // XMLFragment xmlFilter = new XMLFragment();
573 // try {
574 // xmlFilter.load( new StringReader( filter ),
575 // "http://www.deegree.org/portal/standard/WFSClientListener" );
576 // xmlFilter.prettyPrint( System.out );
577 // } catch ( Exception e ) {
578 // LOG.logError( e.getMessage() );
579 // throw new WFSClientException( "Could not transform filter into XMLFragment", e );
580 // }
581 //
582 // //FIXME normalization of filter using the passed locale !
583 //
584 //
585 // return xmlFilter.getAsString();
586 }
587
588 /**
589 * Performs a GetFeature query against a WFS.
590 *
591 * The WFS address is defined in the module configuration: The default WFS is given with Parameter Name = WFS. If a
592 * different WFS is to be used for a special querytemplate, this is defined by specifying ParameterName =
593 * WFS:querytemplate
594 *
595 * @param query
596 * @param moduleName
597 * @return Returns the response to a WFS GetFeature request as xml Document.
598 * @throws WFSClientException
599 */
600 private XMLFragment performQuery( String query, String moduleName )
601 throws WFSClientException {
602
603 HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
604 ViewContext vc = (ViewContext) session.getAttribute( org.deegree.portal.Constants.CURRENTMAPCONTEXT );
605
606 // WFS to contact
607 GeneralExtension ge = vc.getGeneral().getExtension();
608 AbstractFrontend fe = (AbstractFrontend) ge.getFrontend();
609 Module module = null;
610 Module[] mods = fe.getModulesByName( moduleName );
611 if ( mods.length > 0 ) {
612 module = mods[0];
613 } else {
614 LOG.logError( "no module with the name" + moduleName + "could be found." );
615
616 throw new WFSClientException( "The current map context does not contain the module:" + moduleName );
617 }
618
619 // get WFS address for template of current featuretype OR, if not available, the default WFS
620 String wfsAddress = null;
621 String queryTemplate = (String) getRequest().getAttribute( "QUERYTEMPLATE" );
622 if ( module.getParameter().getParameter( "WFS:" + queryTemplate ) != null ) {
623 wfsAddress = (String) module.getParameter().getParameter( "WFS:" + queryTemplate ).getValue();
624 } else {
625 wfsAddress = (String) module.getParameter().getParameter( "WFS" ).getValue();
626 }
627 if ( wfsAddress == null ) {
628
629 throw new WFSClientException( "WFS is not known by the portal" );
630 }
631 if ( wfsAddress.startsWith( "'" ) && wfsAddress.endsWith( "'" ) ) {
632 // strip ' from front and end of string
633 wfsAddress = wfsAddress.substring( 1, wfsAddress.length() - 1 );
634 }
635
636 InputStream is = null;
637 try {
638 StringRequestEntity re = new StringRequestEntity( query, "text/xml", CharsetUtils.getSystemCharset() );
639 PostMethod post = new PostMethod( wfsAddress );
640 post.setRequestEntity( re );
641 post.setRequestHeader( "Content-type", "text/xml;charset=" + CharsetUtils.getSystemCharset() );
642
643 HttpClient client = new HttpClient();
644 client = WebUtils.enableProxyUsage( client, new URL( wfsAddress ) );
645 client.executeMethod( post );
646 is = post.getResponseBodyAsStream();
647 } catch ( IOException e ) {
648 LOG.logError( e.getMessage(), e );
649
650 throw new WFSClientException( "could not perform query against the WFS." );
651 }
652
653 XMLFragment xmlFrag = new XMLFragment();
654 try {
655 InputStreamReader isr = new InputStreamReader( is, CharsetUtils.getSystemCharset() );
656 xmlFrag.load( isr, wfsAddress );
657 } catch ( Exception e ) {
658 LOG.logError( e.getMessage(), e );
659
660 throw new WFSClientException( "could not load xmlFragment. \n" + e.getMessage(), e );
661 }
662 return xmlFrag;
663 }
664
665 /**
666 * writes the result into the forwarded request object
667 *
668 * @param fc
669 * @param resultFormat
670 * the format of the result in the servlet request. Can be either 'XML' or 'FEATURECOLLECTION'.
671 * @throws WFSClientException
672 * if the feature collection could not be exported to GML.
673 * @throws RuntimeException
674 * if the resultFormat is not supported.
675 */
676
677 private void writeGetFeatureResult( FeatureCollection fc, String resultFormat )
678 throws WFSClientException {
679
680 if ( "XML".equals( resultFormat ) ) {
681 try {
682 GMLFeatureCollectionDocument gmlFcDoc = new GMLFeatureAdapter().export( fc );
683 getRequest().setAttribute( "RESULT", gmlFcDoc );
684 } catch ( Exception e ) {
685 LOG.logError( e.getMessage(), e );
686
687 throw new WFSClientException( "could not export feature collection as GML", e );
688 }
689 } else if ( "FEATURECOLLECTION".equals( resultFormat ) ) {
690 getRequest().setAttribute( "RESULT", fc );
691 } else {
692 throw new RuntimeException( "'" + resultFormat + "' is not a supported format." );
693 }
694
695 }
696
697 }