001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/portal/standard/csw/control/ISO19115RequestFactory.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2008 by:
006 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 53177 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
044 package org.deegree.portal.standard.csw.control;
045
046 import java.io.BufferedReader;
047 import java.io.InputStream;
048 import java.io.InputStreamReader;
049 import java.util.Properties;
050
051 import org.deegree.datatypes.QualifiedName;
052 import org.deegree.enterprise.control.RPCStruct;
053 import org.deegree.framework.log.ILogger;
054 import org.deegree.framework.log.LoggerFactory;
055 import org.deegree.framework.util.StringTools;
056 import org.deegree.i18n.Messages;
057 import org.deegree.model.crs.CRSFactory;
058 import org.deegree.model.crs.CoordinateSystem;
059 import org.deegree.model.crs.GeoTransformer;
060 import org.deegree.model.crs.UnknownCRSException;
061 import org.deegree.model.filterencoding.Literal;
062 import org.deegree.model.filterencoding.Operation;
063 import org.deegree.model.filterencoding.OperationDefines;
064 import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
065 import org.deegree.model.filterencoding.PropertyIsLikeOperation;
066 import org.deegree.model.filterencoding.PropertyIsNullOperation;
067 import org.deegree.model.filterencoding.PropertyName;
068 import org.deegree.model.filterencoding.SpatialOperation;
069 import org.deegree.model.spatialschema.Envelope;
070 import org.deegree.model.spatialschema.Geometry;
071 import org.deegree.model.spatialschema.GeometryException;
072 import org.deegree.model.spatialschema.GeometryFactory;
073 import org.deegree.portal.standard.csw.CatalogClientException;
074
075 /**
076 * A <code>${type_name}</code> class.<br/>
077 *
078 * class for creating a get GetRecord Request against a catalog based on OGC Stateless Web Service
079 * Catalog Profil and GDI NRW catalog specifications to access data metadata (ISO 19115).
080 * <p>
081 * The only public method of the class receives a 'model' represented by a <tt>HashMap</tt> that
082 * contains the request parameters as name-value-pairs. The names corresponds to the
083 * form-field-names. For common this will be the fields of a HTML-form but it can be any other form
084 * (e.g. swing-application)
085 * </p>
086 *
087 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
088 * @author last edited by: $Author: rbezema $
089 *
090 * @version $Revision: 9457 $, $Date: 2008-01-08 12:04:29 +0100 (Di, 08 Jan 2008) $
091 */
092 public class ISO19115RequestFactory extends CSWRequestFactory {
093
094 private static final ILogger LOG = LoggerFactory.getLogger( ISO19115RequestFactory.class );
095
096 static final String RPC_SIMPLESEARCH = "RPC_SIMPLESEARCH";
097
098 private static final char WILDCARD = '*';
099
100 private static final String OUTPUTSCHEMA = "csw:profile";
101
102 private RPCStruct struct = null;
103
104 private Properties requestElementsProps = new Properties();
105
106 /**
107 *
108 */
109 public ISO19115RequestFactory() {
110 try {
111 InputStream is = ISO19115RequestFactory.class.getResourceAsStream( "ISO19115requestElements.properties" );
112 this.requestElementsProps.load( is );
113 } catch ( Exception e ) {
114 e.printStackTrace();
115 }
116 }
117
118 /**
119 * creates a GetRecord request that is conform to the OGC Stateless Web Service Catalog Profil
120 * and GDI NRW catalog specifications from a RPC struct.
121 *
122 * @param struct
123 * RPC structure containing the request parameter
124 * @param resultType
125 * @return GetFeature request as a string
126 * @throws CatalogClientException
127 */
128 @Override
129 public String createRequest( RPCStruct struct, String resultType )
130 throws CatalogClientException {
131
132
133
134 this.struct = struct;
135 boolean isSearchRequest = false;
136 boolean isOverviewRequest = false;
137
138 if ( "HITS".equals( resultType ) || "RESULTS".equals( resultType ) ) {
139 isSearchRequest = true;
140 } else if ( resultType == null ) {
141 isOverviewRequest = true;
142 }
143
144 InputStream is = null;
145 InputStreamReader ireader = null;
146 BufferedReader br = null;
147 StringBuffer sb = null;
148 String request = null;
149
150 if ( isSearchRequest ) {
151 is = ISO19115RequestFactory.class.getResourceAsStream( "CSWGetRecordsTemplate.xml" );
152 } else if ( isOverviewRequest ) {
153 is = ISO19115RequestFactory.class.getResourceAsStream( "CSWGetRecordByIdTemplate.xml" );
154 }
155
156 try {
157 ireader = new InputStreamReader( is );
158 br = new BufferedReader( ireader );
159 sb = new StringBuffer( 50000 );
160
161 while ( ( request = br.readLine() ) != null ) {
162 sb.append( request );
163 }
164 request = sb.toString();
165 br.close();
166
167 } catch ( Exception e ) {
168 LOG.logError( e.getMessage(), e );
169 }
170
171 if ( isSearchRequest ) {
172 try {
173 request = replaceVarsInSearchRequest( request, resultType );
174 } catch ( UnknownCRSException e ) {
175 throw new CatalogClientException( e.getMessage(), e );
176 }
177 } else if ( isOverviewRequest ) {
178 request = replaceVarsInOverviewRequest( request );
179 }
180
181
182 return request;
183 }
184
185 /**
186 * @param request
187 * @param resultType
188 * @return Returns the request, where all variables are replaced by values.
189 * @throws CatalogClientException
190 * @throws UnknownCRSException
191 */
192 private String replaceVarsInSearchRequest( String request, String resultType )
193 throws CatalogClientException, UnknownCRSException {
194
195 // replace variables from template
196
197 String filter = createFilterEncoding();
198 request = request.replaceFirst( "\\$FILTER", filter );
199
200 request = request.replaceFirst( "\\$OUTPUTSCHEMA", OUTPUTSCHEMA );
201
202 request = request.replaceFirst( "\\$RESULTTYPE", resultType );
203
204 // According to OGC CSW-spec default is 1
205 String startPos = "1";
206 if ( struct.getMember( RPC_STARTPOSITION ) != null ) {
207 startPos = (String) struct.getMember( RPC_STARTPOSITION ).getValue();
208 }
209 request = request.replaceFirst( "\\$STARTPOSITION", startPos );
210
211 // According to OGC CSW-spec default is 10
212 String maxRecords = Integer.toString( config.getMaxRecords() );
213 request = request.replaceFirst( "\\$MAXRECORDS", maxRecords );
214
215 String queryType = "csw:dataset"; // dataset, dataseries, service, application
216 if ( struct.getMember( RPC_TYPENAME ) != null ) {
217 queryType = (String) struct.getMember( RPC_TYPENAME ).getValue();
218 }
219 request = request.replaceFirst( "\\$TYPENAME", queryType );
220
221 String elementSet = "brief"; // brief, summary, full
222 if ( struct.getMember( RPC_ELEMENTSETNAME ) != null ) {
223 elementSet = (String) struct.getMember( RPC_ELEMENTSETNAME ).getValue();
224 }
225 request = request.replaceFirst( "\\$ELEMENTSETNAME", elementSet );
226
227 return request;
228 }
229
230 /**
231 * @param request
232 * @return Returns the request, where all variables are replaced by values.
233 * @throws CatalogClientException
234 */
235 private String replaceVarsInOverviewRequest( String request )
236 throws CatalogClientException {
237
238 String id;
239 if ( struct.getMember( Constants.RPC_IDENTIFIER ) != null ) {
240 id = (String) struct.getMember( Constants.RPC_IDENTIFIER ).getValue();
241 } else {
242 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_ID_NOT_SET" ) );
243 }
244 request = request.replaceFirst( "\\$IDENTIFIER", id );
245
246 request = request.replaceFirst( "\\$OUTPUTSCHEMA", OUTPUTSCHEMA );
247
248 String elementSet = "full"; // brief, summary, full
249 if ( struct.getMember( RPC_ELEMENTSETNAME ) != null ) {
250 elementSet = (String) struct.getMember( RPC_ELEMENTSETNAME ).getValue();
251 }
252 request = request.replaceFirst( "\\$ELEMENTSETNAME", elementSet );
253
254 return request;
255 }
256
257 /**
258 * takes RequestModel and builds a String result out of it. The result should be OGC
259 * FilterEncoding conformant.
260 *
261 * @return Returns the fragment for filter encoding.
262 * @throws CatalogClientException
263 * @throws UnknownCRSException
264 */
265 private String createFilterEncoding()
266 throws CatalogClientException, UnknownCRSException {
267
268 StringBuffer sb = new StringBuffer( 2000 );
269 int expCounter = 0;
270
271 sb.append( "<csw:Constraint version='1.0.0'><ogc:Filter>" );
272
273 // build filter encoding structure, handle all known fields sequentially
274 String s = handleFileIdentifier();
275 if ( ( s != null ) && ( s.length() > 0 ) ) {
276 expCounter++;
277 sb.append( s );
278 }
279
280 s = handleParentIdentifier();
281 if ( ( s != null ) && ( s.length() > 0 ) ) {
282 expCounter++;
283 sb.append( s );
284 }
285
286 s = handleSimpleSearch();
287 if ( ( s != null ) && ( s.length() > 0 ) ) {
288 expCounter++;
289 sb.append( s );
290 }
291
292 s = handleTopiccategory();
293 if ( ( s != null ) && ( s.length() > 0 ) ) {
294 expCounter++;
295 sb.append( s );
296 }
297
298 s = handleKeywords();
299 if ( ( s != null ) && ( s.length() > 0 ) ) {
300 expCounter++;
301 sb.append( s );
302 }
303
304 s = handleDate();
305 if ( ( s != null ) && ( s.length() > 0 ) ) {
306 expCounter++;
307 sb.append( s );
308 }
309
310 s = handleBbox();
311 if ( ( s != null ) && ( s.length() > 0 ) ) {
312 expCounter++;
313 sb.append( s );
314 }
315
316 if ( expCounter > 1 ) {
317 sb.insert( "<csw:Constraint version='1.0.0'><ogc:Filter>".length(), "<ogc:And>" );
318 sb.append( "</ogc:And>" );
319 }
320
321 sb.append( "</ogc:Filter></csw:Constraint>" );
322
323 return sb.toString();
324 }
325
326 /**
327 * Build OGC Filterencoding fragment: use <code>CSWRequestmodel</code> field <b>fileIdentifier</b>
328 * to create Comparison Operation.
329 *
330 * @return Returns the fragment for fileIdentifier. May be empty.
331 */
332 private String handleFileIdentifier() {
333
334 StringBuffer sb = new StringBuffer( 1000 );
335
336 String id = null;
337 if ( struct.getMember( Constants.RPC_IDENTIFIER ) != null ) {
338 id = (String) struct.getMember( Constants.RPC_IDENTIFIER ).getValue();
339 }
340
341 if ( ( id != null ) && ( id.trim().length() > 0 ) ) {
342 String cf_props = requestElementsProps.getProperty( Constants.CONF_IDENTIFIER );
343 String[] cf = cf_props.split( ";" );
344
345 sb = new StringBuffer( 1000 );
346 Operation op1 = createOperation( OperationDefines.PROPERTYISEQUALTO, cf[0], id );
347 sb.append( op1.toXML() );
348 }
349
350 return sb.toString();
351 }
352
353 /**
354 * Build OGC Filterencoding fragment: use <code>CSWRequestmodel</code> field
355 * <b>parentIdentifier</b> to create Comparison Operation.
356 *
357 * @return Returns the fragment for parentIdentifier. May be empty.
358 */
359 private String handleParentIdentifier() {
360
361 StringBuffer sb = new StringBuffer( 1000 );
362 String id = null;
363 if ( struct.getMember( RPC_DATASERIES ) != null ) {
364 id = (String) struct.getMember( RPC_DATASERIES ).getValue();
365 }
366
367 if ( ( id != null ) && ( id.trim().length() > 0 ) ) {
368 String cf_props = requestElementsProps.getProperty( CONF_DATASERIES );
369 String[] cf = cf_props.split( ";" );
370
371 sb = new StringBuffer( 1000 );
372 Operation op1 = createOperation( OperationDefines.PROPERTYISEQUALTO, cf[0], id );
373 sb.append( op1.toXML() );
374 }
375
376 return sb.toString();
377 }
378
379 /**
380 * Spread <code>CSWRequestmodel</code> field <b>terms</b> to several Comparison Operations
381 * with pre-defined Property names.
382 *
383 * @return Returns the fragment for the search string. May be empty.
384 */
385 private String handleSimpleSearch() {
386
387 StringBuffer sb = new StringBuffer( 2000 );
388
389 String[] t = null;
390 if ( struct.getMember( RPC_SIMPLESEARCH ) != null ) {
391 String s = (String) struct.getMember( RPC_SIMPLESEARCH ).getValue();
392 t = StringTools.toArray( s, ",;|", true );
393 }
394
395 if ( ( t != null ) && ( t.length > 0 ) ) {
396 sb.append( "<ogc:Or>" );
397
398 for ( int i = 0; i < t.length; i++ ) {
399 // replace invalid chars
400 if ( ( t[i] != null ) && ( t[i].length() > 0 ) ) {
401 t[i] = StringTools.replace( t[i], "'", " ", true );
402 t[i] = StringTools.replace( t[i], "\"", " ", true );
403
404 // determine the way to build FilterEncoding part
405 String cf_props = requestElementsProps.getProperty( Constants.CONF_SIMPLESEARCH );
406 String[] cf = cf_props.split( ";" );
407
408 for ( int k = 0; k < cf.length; k++ ) {
409 String strOp = t[i];
410
411 if ( ( strOp != null ) && ( strOp.length() > 0 ) ) {
412 // LOWERCASE SECTION
413 strOp = strOp.substring( 0, 1 ).toLowerCase() + strOp.substring( 1 );
414
415 Operation op = createOperation( OperationDefines.PROPERTYISLIKE, cf[k],
416 strOp );
417 sb.append( op.toXML() );
418
419 // FIRST LETTER UPPERCASE SECTION
420 strOp = strOp.substring( 0, 1 ).toUpperCase() + strOp.substring( 1 );
421 op = createOperation( OperationDefines.PROPERTYISLIKE, cf[k], strOp );
422 sb.append( op.toXML() );
423 }
424 }
425 }
426 }
427 sb.append( "</ogc:Or>" );
428 }
429
430 return sb.toString();
431 }
432
433 /**
434 * Builds OGC Filterencoding fragment: for <code>CSWRequestmodel</code> field <b>topiccategory</b>.
435 *
436 * @return Returns the fragment for topiccategory. May be null, if no topiccategory is
437 * specified.
438 */
439 private String handleTopiccategory() {
440
441 String tc = null;
442 if ( struct.getMember( RPC_TOPICCATEGORY ) != null ) {
443 tc = (String) struct.getMember( RPC_TOPICCATEGORY ).getValue();
444 }
445
446 if ( tc != null && !tc.startsWith( "..." ) && tc.length() > 0 ) {
447 String cf_props = requestElementsProps.getProperty( Constants.CONF_TOPICCATEGORY );
448 String[] cf = cf_props.split( ";" );
449
450 Operation op1 = createOperation( OperationDefines.PROPERTYISEQUALTO, cf[0], tc );
451 tc = op1.toXML().toString();
452 } else {
453 tc = null;
454 }
455
456 return tc;
457 }
458
459 /**
460 * Build OGC Filterencoding fragment: Split <code>CSWRequestmodel</code> field <b>keywords</b>
461 * to one Comparison Operation for each keyword.
462 *
463 * @return Returns the fragment for keywords. May be empty, if no keywords are specified.
464 */
465 private String handleKeywords() {
466
467 StringBuffer sb = new StringBuffer( 1000 );
468 String[] tc = null;
469 if ( struct.getMember( RPC_KEYWORDS ) != null ) {
470 String s = (String) struct.getMember( RPC_KEYWORDS ).getValue();
471 tc = StringTools.toArray( s, ",;", true );
472 }
473
474 if ( ( tc != null ) && ( tc.length > 0 ) ) {
475 String cf_props = requestElementsProps.getProperty( Constants.CONF_KEYWORDS );
476 String[] cf = cf_props.split( ";" );
477
478 sb = new StringBuffer( 1000 );
479 int i = 0;
480
481 for ( i = 0; i < tc.length; i++ ) {
482 if ( tc[i].trim().length() > 0 ) {
483 Operation op1 = createOperation( OperationDefines.PROPERTYISEQUALTO, cf[0],
484 tc[i] );
485 sb.append( op1.toXML() );
486 }
487 }
488
489 if ( i > 1 ) {
490 sb.insert( 0, "<ogc:Or>" );
491 sb.append( "</ogc:Or>" );
492 }
493 }
494
495 return sb.toString();
496 }
497
498 /**
499 * Build OGC Filterencoding fragment: use <code>dateFrom</code> and <code>dateTo</code> to
500 * create Comparison Operations.
501 *
502 * @return Returns the fragment for dates specified in the <code>RPCStruct</code>. May be
503 * null, if no dates are specified.
504 */
505 private String handleDate() {
506
507 String s = null;
508
509 if ( struct.getMember( Constants.RPC_DATEFROM ) == null
510 && struct.getMember( Constants.RPC_DATETO ) == null ) {
511 return s;
512 }
513
514 // RPC_DATEFROM
515 String fy = null;
516 String fm = null;
517 String fd = null;
518
519 if ( struct.getMember( Constants.RPC_DATEFROM ) != null ) {
520 RPCStruct st = (RPCStruct) struct.getMember( Constants.RPC_DATEFROM ).getValue();
521 if ( st.getMember( Constants.RPC_YEAR ) != null ) {
522 fy = st.getMember( Constants.RPC_YEAR ).getValue().toString();
523 }
524 if ( st.getMember( Constants.RPC_MONTH ) != null ) {
525 fm = st.getMember( Constants.RPC_MONTH ).getValue().toString();
526 }
527 if ( st.getMember( Constants.RPC_DAY ) != null ) {
528 fd = st.getMember( Constants.RPC_DAY ).getValue().toString();
529 }
530 }
531
532 if ( fy == null ) {
533 fy = "0000";
534 }
535 if ( fm == null ) {
536 fm = "1";
537 }
538 if ( Integer.parseInt( fm ) < 10 ) {
539 fm = "0" + Integer.parseInt( fm );
540 }
541 if ( fd == null ) {
542 fd = "1";
543 }
544 if ( Integer.parseInt( fd ) < 10 ) {
545 fd = "0" + Integer.parseInt( fd );
546 }
547 String df = fy + "-" + fm + "-" + fd;
548
549 // RPC_DATETO
550 String ty = null;
551 String tm = null;
552 String td = null;
553
554 if ( struct.getMember( Constants.RPC_DATETO ) != null ) {
555 RPCStruct st = (RPCStruct) struct.getMember( Constants.RPC_DATETO ).getValue();
556 if ( st.getMember( Constants.RPC_YEAR ) != null ) {
557 ty = st.getMember( Constants.RPC_YEAR ).getValue().toString();
558 }
559 if ( st.getMember( Constants.RPC_MONTH ) != null ) {
560 tm = st.getMember( Constants.RPC_MONTH ).getValue().toString();
561 }
562 if ( st.getMember( Constants.RPC_DAY ) != null ) {
563 td = st.getMember( Constants.RPC_DAY ).getValue().toString();
564 }
565 }
566
567 if ( ty == null ) {
568 ty = "9999";
569 }
570 if ( tm == null ) {
571 tm = "12";
572 }
573 if ( Integer.parseInt( tm ) < 10 ) {
574 tm = "0" + Integer.parseInt( tm );
575 }
576 if ( td == null ) {
577 td = "31";
578 }
579 if ( Integer.parseInt( td ) < 10 ) {
580 td = "0" + Integer.parseInt( td );
581 }
582 String dt = ty + "-" + tm + "-" + td;
583
584 String date_props = requestElementsProps.getProperty( Constants.CONF_DATE );
585 String[] conf_date = date_props.split( ";" );
586
587 if ( ( ty != null ) && ( ty.length() > 0 ) ) {
588 StringBuffer sb = new StringBuffer( "<ogc:And>" );
589
590 Operation op1 = null;
591 op1 = createOperation( OperationDefines.PROPERTYISGREATERTHANOREQUALTO, conf_date[0],
592 df );
593 sb.append( op1.toXML() );
594 op1 = createOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO, conf_date[0], dt );
595 sb.append( op1.toXML() );
596
597 sb.append( "</ogc:And>" );
598 s = sb.toString();
599 }
600
601 return s;
602 }
603
604 /**
605 * Build OGC Filterencoding fragment: use <code>CSWRequestmodel</code> field <b>geographicBox</b>
606 * to create Comparison Operation.
607 *
608 * @return Returns the fragment for the geographic bounding box. May be empty, if no bounding
609 * box is specified.
610 * @throws CatalogClientException
611 * @throws UnknownCRSException
612 */
613 private String handleBbox()
614 throws CatalogClientException, UnknownCRSException {
615
616 StringBuffer sb = new StringBuffer( 1000 );
617 if ( struct.getMember( Constants.RPC_BBOX ) != null ) {
618 RPCStruct bboxStruct = (RPCStruct) struct.getMember( Constants.RPC_BBOX ).getValue();
619
620 Double minx = (Double) bboxStruct.getMember( Constants.RPC_BBOXMINX ).getValue();
621 Double miny = (Double) bboxStruct.getMember( Constants.RPC_BBOXMINY ).getValue();
622 Double maxx = (Double) bboxStruct.getMember( Constants.RPC_BBOXMAXX ).getValue();
623 Double maxy = (Double) bboxStruct.getMember( Constants.RPC_BBOXMAXY ).getValue();
624
625 // FIXME check if srs is correct
626 CoordinateSystem srs = CRSFactory.create( config.getSrs() );
627 Envelope bbox = GeometryFactory.createEnvelope( minx.doubleValue(), miny.doubleValue(),
628 maxx.doubleValue(), maxy.doubleValue(),
629 srs );
630 try {
631 // transform request boundingbox to EPSG:4326 because a ISO 19115
632 // compliant catalog must store the bbox of an entry like this
633 GeoTransformer gt = new GeoTransformer( "EPSG:4326" );
634 bbox = gt.transform( bbox, config.getSrs() );
635 } catch ( Exception e ) {
636 throw new CatalogClientException( e.toString() );
637 }
638
639 Geometry boxGeom = null;
640 try {
641 boxGeom = GeometryFactory.createSurface( bbox, srs );
642 } catch ( GeometryException e ) {
643 throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_CREATE_SURFACE",
644 e.getMessage() ) );
645 }
646
647 String reProps = requestElementsProps.getProperty( Constants.CONF_GEOGRAPHICBOX );
648 String[] re = reProps.split( ";" );
649
650 if ( boxGeom != null ) {
651 Operation op1 = createOperation( OperationDefines.BBOX, re[0], boxGeom );
652 sb.append( op1.toXML() );
653 }
654 }
655
656 return sb.toString();
657 }
658
659 // /**
660 // * @param bbox The bounding box to be used as filter condition.
661 // * @return Returns the GML bounding box snippet.
662 // */
663 // private String createGMLBox( Envelope bbox ) {
664 // StringBuffer sb = new StringBuffer( 1000 );
665 //
666 // sb.append( "<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" >" );
667 // sb.append( "<gml:coord><gml:X>" );
668 // sb.append( "" + bbox.getMin().getX() );
669 // sb.append( "</gml:X><gml:Y>" );
670 // sb.append( "" + bbox.getMin().getY() );
671 // sb.append( "</gml:Y></gml:coord><gml:coord><gml:X>" );
672 // sb.append( "" + bbox.getMax().getX() );
673 // sb.append( "</gml:X><gml:Y>" );
674 // sb.append( "" + bbox.getMax().getY() );
675 // sb.append( "</gml:Y></gml:coord></gml:Box>" );
676 //
677 // return sb.toString();
678 // }
679
680 /**
681 * @param opId
682 * @param property
683 * @param value
684 * @return Returns the operation to create.
685 */
686 private Operation createOperation( int opId, String property, Object value ) {
687
688 Operation op = null;
689
690 switch ( opId ) {
691 case OperationDefines.PROPERTYISEQUALTO:
692 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO,
693 new PropertyName( new QualifiedName( property ) ),
694 new Literal( (String) value ) );
695 break;
696 case OperationDefines.PROPERTYISLIKE:
697
698 char wildCard = WILDCARD;
699 char singleChar = '?';
700 char escapeChar = '/';
701 String lit = wildCard + (String) value + wildCard;
702 op = new PropertyIsLikeOperation( new PropertyName( new QualifiedName( property ) ),
703 new Literal( lit ), wildCard, singleChar, escapeChar );
704 break;
705 case OperationDefines.PROPERTYISLESSTHANOREQUALTO:
706 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO,
707 new PropertyName( new QualifiedName( property ) ),
708 new Literal( (String) value ) );
709 break;
710 case OperationDefines.PROPERTYISGREATERTHANOREQUALTO:
711 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISGREATERTHANOREQUALTO,
712 new PropertyName( new QualifiedName( property ) ),
713 new Literal( (String) value ) );
714 break;
715 case OperationDefines.BBOX:
716 op = new SpatialOperation( OperationDefines.BBOX,
717 new PropertyName( new QualifiedName( property ) ),
718 (Geometry) value );
719 break;
720 case OperationDefines.PROPERTYISNULL:
721 op = new PropertyIsNullOperation( new PropertyName( new QualifiedName( property ) ) );
722 break;
723 default:
724 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO,
725 new PropertyName( new QualifiedName( property ) ),
726 new Literal( (String) value ) );
727 }
728
729 return op;
730 }
731
732 }