001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_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 }