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 }