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 }