001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/portal/standard/csw/control/ISO19119RequestFactory.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.csw.control; 038 039 import java.io.BufferedReader; 040 import java.io.InputStream; 041 import java.io.InputStreamReader; 042 import java.util.Properties; 043 044 import org.deegree.datatypes.QualifiedName; 045 import org.deegree.enterprise.control.RPCStruct; 046 import org.deegree.framework.log.ILogger; 047 import org.deegree.framework.log.LoggerFactory; 048 import org.deegree.framework.util.StringTools; 049 import org.deegree.model.filterencoding.Literal; 050 import org.deegree.model.filterencoding.Operation; 051 import org.deegree.model.filterencoding.OperationDefines; 052 import org.deegree.model.filterencoding.PropertyIsCOMPOperation; 053 import org.deegree.model.filterencoding.PropertyName; 054 055 /** 056 * A <code>${type_name}</code> class.<br/> TODO class description 057 * 058 * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a> 059 * @author last edited by: $Author: mschneider $ 060 * 061 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 062 */ 063 public class ISO19119RequestFactory extends CSWRequestFactory { 064 065 private static final ILogger LOG = LoggerFactory.getLogger( ISO19119RequestFactory.class ); 066 067 // private static final char WILDCARD = '*'; 068 // private static final String OUTPUTSCHEMA = "csw:profile"; 069 private static final String OUTPUTSCHEMA = "http://www.isotc211.org/2005/gmd"; 070 071 private RPCStruct struct = null; 072 073 private Properties requestElementsProps = new Properties(); 074 075 /** 076 * 077 * 078 */ 079 public ISO19119RequestFactory() { 080 try { 081 InputStream is = ISO19119RequestFactory.class.getResourceAsStream( "ISO19119requestElements.properties" ); 082 this.requestElementsProps.load( is ); 083 } catch ( Exception e ) { 084 LOG.logError( e.getMessage(), e ); 085 } 086 } 087 088 /** 089 * creates a GetRecord request that is conform to the OGC Stateless Web Service Catalog Profil and GDI NRW catalog 090 * specifications from a RPC struct. 091 * 092 * @param struct 093 * RPC structure containing the request parameter 094 * @param resultType 095 * @return GetFeature request as a string 096 */ 097 @Override 098 public String createRequest( RPCStruct struct, String resultType ) { 099 100 this.struct = struct; 101 102 InputStream is = null; 103 InputStreamReader ireader = null; 104 BufferedReader br = null; 105 StringBuffer sb = null; 106 String request = null; 107 108 is = ISO19119RequestFactory.class.getResourceAsStream( "CSWGetRecordsTemplate.xml" ); 109 // is = ISO19119RequestFactory.class.getResourceAsStream( "CSWGetRecordByIdTemplate.xml" ); 110 111 try { 112 ireader = new InputStreamReader( is ); 113 br = new BufferedReader( ireader ); 114 sb = new StringBuffer( 50000 ); 115 116 while ( ( request = br.readLine() ) != null ) { 117 sb.append( request ); 118 } 119 request = sb.toString(); 120 br.close(); 121 122 } catch ( Exception e ) { 123 LOG.logError( e.getMessage(), e ); 124 } 125 126 request = replaceVarsInSearchRequest( request, resultType ); 127 // request = replaceVarsInOverviewRequest( request ); 128 129 return request; 130 } 131 132 private String replaceVarsInSearchRequest( String request, String resultType ) { 133 134 String filter = createFilterEncoding(); 135 LOG.logDebug( "created filter: ", filter ); 136 request = request.replaceFirst( "\\$FILTER", filter ); 137 138 request = request.replaceFirst( "\\$OUTPUTSCHEMA", OUTPUTSCHEMA ); 139 140 request = request.replaceFirst( "\\$RESULTTYPE", resultType ); 141 142 String startPos = "1"; // default is 1 according to OGC CSW-spec 143 if ( struct.getMember( RPC_STARTPOSITION ) != null ) { 144 startPos = (String) struct.getMember( RPC_STARTPOSITION ).getValue(); 145 } 146 request = request.replaceFirst( "\\$STARTPOSITION", startPos ); 147 148 String maxRecords = Integer.toString( config.getMaxRecords() ); // default is 10 (according to spec) 149 request = request.replaceFirst( "\\$MAXRECORDS", maxRecords ); 150 151 // For 2.0.0 152 // String queryType = "csw:service"; // dataset, dataseries, application 153 // // FOR BOTH CSW2.0.0 AND CSW2.0.2 ! 154 String queryType = "csw:service"; // dataset, dataseries, service, application 155 if ( struct.getMember( RPC_TYPENAME ) != null ) { 156 queryType = (String) struct.getMember( RPC_TYPENAME ).getValue(); 157 } 158 /* 159 * if ( struct.getMember( RPC_TYPENAME ) != null ) { queryType = (String) struct.getMember( RPC_TYPENAME 160 * ).getValue(); if ( !"gmd:MD_Metadata".equals( queryType ) && !"csw:Record".equals( queryType )) { 161 * LOG.logError( StringTools.concat( 100, "typename ", queryType, " is not a supported type.", "Suuported types 162 * are: ", "gmd:MD_Metadata", "csw:Record" ) ); queryType = "gmd:MD_Metadata"; } } 163 */ 164 request = request.replaceFirst( "\\$TYPENAME", queryType ); 165 166 String elementSet = "brief"; // brief, summary, full 167 if ( struct.getMember( RPC_ELEMENTSETNAME ) != null ) { 168 elementSet = (String) struct.getMember( RPC_ELEMENTSETNAME ).getValue(); 169 } 170 request = request.replaceFirst( "\\$ELEMENTSETNAME", elementSet ); 171 172 return request; 173 } 174 175 /** 176 * Creates a filter text according to the given parameters of the rpc request to be added to the GetRecords request 177 * 178 * @return the filter xml fragment 179 */ 180 private String createFilterEncoding() { 181 182 StringBuffer sb = new StringBuffer( 2000 ); 183 int expCounter = 0; 184 185 sb.append( "<csw:Constraint version='1.0.0'><ogc:Filter>" ); 186 187 // build filter encoding structure, handle all known fields sequentially 188 String s = null; 189 190 s = handleServiceSearch(); 191 if ( ( s != null ) && ( s.length() > 0 ) ) { 192 expCounter++; 193 sb.append( s ); 194 } 195 196 // NOTE: if some of the methods below are needed, 197 // copy them from ISO19115RequestFactory and adapt them where needed. 198 199 // s = handleFileIdentifier(); 200 // if ( ( s != null ) && ( s.length() > 0 ) ) { 201 // expCounter++; 202 // sb.append( s ); 203 // } 204 205 // s = handleParentIdentifier(); 206 // if ( ( s != null ) && ( s.length() > 0 ) ) { 207 // expCounter++; 208 // sb.append( s ); 209 // } 210 211 // s = handleKeywords(); 212 // if ( ( s != null ) && ( s.length() > 0 ) ) { 213 // expCounter++; 214 // sb.append( s ); 215 // } 216 217 // s = handleDate(); 218 // if ( ( s != null ) && ( s.length() > 0 ) ) { 219 // expCounter++; 220 // sb.append( s ); 221 // } 222 223 // s = handleBbox(); 224 // if ( ( s != null ) && ( s.length() > 0 ) ) { 225 // expCounter++; 226 // sb.append( s ); 227 // } 228 229 if ( expCounter > 1 ) { 230 sb.insert( "<csw:Constraint version='1.0.0'><ogc:Filter>".length(), "<ogc:And>" ); 231 sb.append( "</ogc:And>" ); 232 } 233 234 sb.append( "</ogc:Filter></csw:Constraint>" ); 235 236 return sb.toString(); 237 } 238 239 /** 240 * @return Returns a string containing the service search part of the filter condition. 241 */ 242 private String handleServiceSearch() { 243 244 StringBuffer sb = new StringBuffer( 2000 ); 245 246 String[] t = null; 247 if ( struct.getMember( Constants.RPC_SERVICESEARCH ) != null ) { 248 String s = (String) struct.getMember( Constants.RPC_SERVICESEARCH ).getValue(); 249 t = StringTools.toArray( s, "|", true ); 250 } 251 252 if ( ( t != null ) && ( t.length > 0 ) ) { 253 // sb.append( "<ogc:Or>" ); 254 for ( int i = 0; i < t.length; i++ ) { 255 if ( ( t[i] != null ) && ( t[i].length() > 0 ) ) { 256 // replace invalid chars 257 // t[i] = StringExtend.replace( t[i], "'", " ", true ); 258 // t[i] = StringExtend.replace( t[i], "\"", " ", true ); 259 260 // determine the way to build FilterEncoding part 261 String cf_props = requestElementsProps.getProperty( Constants.CONF_SERVICESEARCH ); 262 String[] cf = cf_props.split( ";" ); 263 264 for ( int k = 0; k < cf.length; k++ ) { 265 String strOp = t[i]; 266 if ( ( strOp != null ) && ( strOp.length() > 0 ) ) { 267 Operation op = createOperation( OperationDefines.PROPERTYISEQUALTO, cf[k], strOp ); 268 sb.append( op.toXML() ); 269 } 270 } 271 } 272 } 273 // sb.append( "</ogc:Or>" ); 274 } 275 276 return sb.toString(); 277 } 278 279 /** 280 * Creates an operation in the csw GetRecords request 281 * 282 * @param opId 283 * the operationID, ex: PROPERTYISEQUALTO, PROPERTYISELIKE 284 * @param property 285 * what property to compare to, ex: apiso:title 286 * @param value 287 * to compare to 288 * 289 * @return The created operation 290 */ 291 private Operation createOperation( int opId, String property, Object value ) { 292 293 Operation op = null; 294 295 switch ( opId ) { 296 case OperationDefines.PROPERTYISEQUALTO: 297 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO, 298 new PropertyName( new QualifiedName( property ) ), 299 new Literal( (String) value ) ); 300 break; 301 302 // case OperationDefines.PROPERTYISLIKE: 303 // char wildCard = WILDCARD; 304 // char singleChar = '?'; 305 // char escapeChar = '/'; 306 // String lit = wildCard + (String)value + wildCard; 307 // op = new PropertyIsLikeOperation( new PropertyName( new QualifiedName( property ) ), 308 // new Literal( lit ), wildCard, singleChar, escapeChar ); 309 // break; 310 // case OperationDefines.PROPERTYISLESSTHANOREQUALTO: 311 // op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISLESSTHANOREQUALTO, 312 // new PropertyName( new QualifiedName( property ) ), 313 // new Literal( (String)value ) ); 314 // break; 315 // case OperationDefines.PROPERTYISGREATERTHANOREQUALTO: 316 // op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISGREATERTHANOREQUALTO, 317 // new PropertyName( new QualifiedName( property ) ), 318 // new Literal( (String)value ) ); 319 // break; 320 // case OperationDefines.BBOX: 321 // op = new SpatialOperation( OperationDefines.BBOX, 322 // new PropertyName( new QualifiedName( property ) ), 323 // (Geometry)value ); 324 // break; 325 // case OperationDefines.PROPERTYISNULL: 326 // op = new PropertyIsNullOperation( new PropertyName( new QualifiedName( property ) ) ); 327 // break; 328 329 default: 330 op = new PropertyIsCOMPOperation( OperationDefines.PROPERTYISEQUALTO, 331 new PropertyName( new QualifiedName( property ) ), 332 new Literal( (String) value ) ); 333 } 334 335 return op; 336 } 337 338 }