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