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