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     **************************************************************************************************/