001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/portal/standard/csw/control/TurnPageListener.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.IOException;
040    import java.io.StringReader;
041    import java.util.ArrayList;
042    import java.util.HashMap;
043    import java.util.List;
044    import java.util.Map;
045    
046    import javax.servlet.http.HttpServletRequest;
047    import javax.servlet.http.HttpSession;
048    
049    import org.deegree.enterprise.control.FormEvent;
050    import org.deegree.enterprise.control.RPCParameter;
051    import org.deegree.enterprise.control.RPCStruct;
052    import org.deegree.enterprise.control.RPCWebEvent;
053    import org.deegree.framework.log.ILogger;
054    import org.deegree.framework.log.LoggerFactory;
055    import org.deegree.framework.util.CharsetUtils;
056    import org.deegree.framework.util.StringTools;
057    import org.deegree.framework.xml.DOMPrinter;
058    import org.deegree.framework.xml.XMLTools;
059    import org.deegree.i18n.Messages;
060    import org.deegree.ogcbase.CommonNamespaces;
061    import org.deegree.portal.standard.csw.CatalogClientException;
062    import org.deegree.portal.standard.csw.configuration.CSWClientConfiguration;
063    import org.deegree.portal.standard.csw.model.DataSessionRecord;
064    import org.w3c.dom.Document;
065    import org.xml.sax.SAXException;
066    
067    /**
068     * A <code>${type_name}</code> class.<br/> TODO class description
069     *
070     * @author <a href="mailto:mays@lat-lon.de">Judit Mays</a>
071     * @author last edited by: $Author: mschneider $
072     *
073     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
074     */
075    public class TurnPageListener extends SimpleSearchListener {
076    
077        private static final ILogger LOG = LoggerFactory.getLogger( TurnPageListener.class );
078    
079        /* (non-Javadoc)
080         * @see org.deegree.portal.standard.csw.control.SimpleSearchListener#actionPerformed(org.deegree.enterprise.control.FormEvent)
081         */
082        @Override
083        public void actionPerformed( FormEvent event ) {
084    
085            RPCWebEvent rpcEvent = (RPCWebEvent) event;
086            HttpSession session = ( (HttpServletRequest) this.getRequest() ).getSession( true );
087            config = (CSWClientConfiguration) session.getAttribute( Constants.CSW_CLIENT_CONFIGURATION );
088    
089            nsContext = CommonNamespaces.getNamespaceContext();
090    
091            try {
092                validateRequest( rpcEvent );
093            } catch ( Exception e ) {
094                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_REQ", e.getMessage() ) );
095                LOG.logError( e.getMessage(), e );
096    
097                return;
098            }
099    
100            RPCStruct struct = null;
101            try {
102                struct = extractRPCStruct( rpcEvent, 0 );
103            } catch ( CatalogClientException e ) {
104                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_RPC_EVENT", e.getMessage() ) );
105                LOG.logError( e.getMessage(), e );
106    
107                return;
108            }
109    
110            // load request from session
111            String req = (String) session.getAttribute( SESSION_REQUESTFORRESULTS );
112    
113            // exchange digits
114            try {
115                req = replaceIndexAttribs( req, struct );
116            } catch ( Exception e ) {
117                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_INVALID_REQ", e.getMessage() ) );
118                LOG.logError( e.getMessage(), e );
119    
120                return;
121            }
122    
123            // load request into session again for further use
124            session.setAttribute( SESSION_REQUESTFORRESULTS, req );
125    
126            List<String> catalogs = new ArrayList<String>( 1 );
127            catalogs.add( (String) struct.getMember( RPC_CATALOG ).getValue() );
128            HashMap result = null;
129    
130            String protocol = (String) session.getAttribute( Constants.RPC_PROTOCOL );
131    
132            // performRequest of SimpleSearchListener
133            try {
134                // result = performRequest( protocol, req, catalogs, "TPL" );
135                // For 2.0.2
136                result = performRequest( protocol, req, catalogs );
137            } catch ( Exception e ) {
138                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_SERVER_ERROR", e.getMessage() ) );
139                LOG.logError( e.getMessage(), e );
140    
141                return;
142            }
143    
144            // create data session records for results and add them to the List in the session.
145            List<DataSessionRecord> dsrListSession = (ArrayList<DataSessionRecord>) session.getAttribute( SESSION_DATARECORDS );
146            List<DataSessionRecord> dsrList = null;
147            try {
148                dsrList = createDataSessionRecords( result );
149            } catch ( CatalogClientException e ) {
150                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_CREATE_DSRLIST", e.getMessage() ) );
151                LOG.logError( e.getMessage(), e );
152    
153                return;
154            }
155            for ( int i = 0; i < dsrList.size(); i++ ) {
156                if ( !dsrListSession.contains( dsrList.get( i ) ) ) {
157                    dsrListSession.add( dsrList.get( i ) );
158                }
159            }
160            session.setAttribute( SESSION_DATARECORDS, dsrListSession );
161    
162            Map availableServiceCatalogsMap = null;
163            try { // TODO make usable for other formats, not only "ISO19119"
164                availableServiceCatalogsMap = doServiceSearch( result, "ISO19119", "HITS" );
165            } catch ( CatalogClientException e ) {
166                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_CREATE_SEARCH_RESULTS", e.getMessage() ) );
167                LOG.logError( e.getMessage(), e );
168    
169                return;
170            }
171            session.setAttribute( SESSION_AVAILABLESERVICECATALOGS, availableServiceCatalogsMap );
172    
173            // handleResult von SimpleSearchListener
174            HashMap resultHits = (HashMap) session.getAttribute( SESSION_RESULTFORHITS );
175            try {
176                String pathToFile = StringTools.concat( 100, "file:", getHomePath(),
177                                                        "WEB-INF/conf/igeoportal/csw/metaList2html.xsl" );
178                handleResult( resultHits, result, pathToFile );
179    
180            } catch ( Exception e ) {
181                gotoErrorPage( Messages.getMessage( "IGEO_STD_CSW_ERROR_HANDLE_RESULT", e.getMessage() ) );
182                LOG.logError( e.getMessage(), e );
183    
184                return;
185            }
186    
187        }
188    
189        /*
190         * (non-Javadoc)
191         *
192         * @see org.deegree.portal.standard.csw.control.SimpleSearchListener#validateRequest(org.deegree.enterprise.control.RPCWebEvent)
193         */
194        @Override
195        protected void validateRequest( RPCWebEvent rpcEvent )
196                                throws CatalogClientException {
197    
198            RPCParameter[] params = extractRPCParameters( rpcEvent );
199    
200            // validity check for number of parameters in RPCMethodCall
201            if ( params.length != 1 ) {
202                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_WRONG_PARAMS_NUMBER", "1",
203                                                                       params.length ) );
204            }
205    
206            RPCStruct struct = extractRPCStruct( rpcEvent, 0 );
207            String catalog = (String) extractRPCMember( struct, RPC_CATALOG );
208            String format = (String) extractRPCMember( struct, RPC_FORMAT );
209            Integer matches = (Integer) extractRPCMember( struct, "matches" );
210            Integer recReturned = (Integer) extractRPCMember( struct, "recReturned" );
211            String direction = (String) extractRPCMember( struct, "direction" );
212            if ( catalog == null || format == null || matches == null || recReturned == null || direction == null ) {
213                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_MISSING_PARAMS" ) );
214            }
215    
216            // validity check for format
217            // is requested catalog capable to serve requested metadata format?
218            List formats = config.getCatalogFormats( catalog );
219            if ( !formats.contains( format ) ) {
220                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_WRONG_FORMAT", catalog, format ) );
221            }
222    
223            return;
224        }
225    
226        /**
227         * @param request
228         * @param struct
229         * @return Returns the request after replacing the index.
230         * @throws IOException
231         * @throws SAXException
232         * @throws CatalogClientException
233         */
234        private String replaceIndexAttribs( String request, RPCStruct struct )
235                                throws IOException, SAXException, CatalogClientException {
236    
237            // read string as xml document
238            StringReader sr = new StringReader( request );
239            Document doc = XMLTools.parse( sr );
240            //
241            int oldStartPos = Integer.parseInt( doc.getDocumentElement().getAttribute( "startPosition" ) );
242            int maxRec = Integer.parseInt( doc.getDocumentElement().getAttribute( "maxRecords" ) );
243    
244            int matches;
245            int recRet;
246            String direction;
247    
248            try {
249                matches = ( (Integer) struct.getMember( "matches" ).getValue() ).intValue();
250                recRet = ( (Integer) struct.getMember( "recReturned" ).getValue() ).intValue();
251                direction = (String) struct.getMember( "direction" ).getValue();
252            } catch ( Exception e ) {
253                LOG.logError( e.getMessage(), e );
254                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_INVALID_STRUCT", e.getMessage() ) );
255            }
256    
257            // validity check
258            if ( recRet > maxRec ) {
259                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_WRONG_NUMBER" ) );
260            }
261    
262            int newStartPos = 1;
263            if ( "previous".equals( direction ) ) {
264                newStartPos = oldStartPos - maxRec < 1 ? 1 : oldStartPos - maxRec;
265            } else if ( "next".equals( direction ) ) {
266                newStartPos = oldStartPos + recRet;
267            } else {
268                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_WRONG_DIRECTION" ) );
269            }
270    
271            // validity check: 1 <= startPosition <= matches
272            if ( newStartPos > matches || newStartPos < 1 ) {
273                throw new CatalogClientException( Messages.getMessage( "IGEO_STD_CSW_ERROR_WRONG_STARTPOS", newStartPos ) );
274            }
275    
276            // replace value of startPosition
277            doc.getDocumentElement().setAttribute( "startPosition", String.valueOf( newStartPos ) );
278    
279            // return doc as string
280            return DOMPrinter.nodeToString( doc, CharsetUtils.getSystemCharset() );
281        }
282    
283    }