/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ /* * Cr�� le 13 mai 04 * * Pour changer le mod�le de ce fichier g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ package org.squale.welcom.struts.action; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.actions.DispatchAction; import org.apache.struts.util.MessageResources; import org.squale.welcom.struts.util.WatchedTask; /** * @author M327837 Pour changer le mod�le de ce commentaire de type g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ public abstract class WDispatchAction extends WAction { // ----------------------------------------------------- Instance Variables /** * The Class instance of this <code>DispatchAction</code> class. */ protected Class clazz = this.getClass(); /** * Commons Logging instance. */ protected static Log log = LogFactory.getLog( DispatchAction.class ); /** * The message resources for this package. */ protected static MessageResources messages = MessageResources.getMessageResources( "org.apache.struts.actions.LocalStrings" ); /** * The set of Method objects we have introspected for this class, keyed by method name. This collection is populated * as different methods are called, so that introspection needs to occur only once per method name. */ protected HashMap methods = new HashMap(); /** * The set of argument type classes for the reflected method call. These are the same for all calls, so calculate * them only once. */ protected Class types[] = { ActionMapping.class, ActionForm.class, HttpServletRequest.class, HttpServletResponse.class }; protected Class typesProgressBar[] = { ActionMapping.class, ActionForm.class, HttpServletRequest.class, HttpServletResponse.class, WatchedTask.class }; // --------------------------------------------------------- Public Methods /** * Process the specified HTTP request, and create the corresponding HTTP response (or forward to another web * component that will create it). Return an <code>ActionForward</code> instance describing where and how control * should be forwarded, or <code>null</code> if the response has already been completed. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * @exception Exception if an exception occurs * @return ActionForward */ public ActionForward wExecute( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response ) throws Exception { // Identify the request parameter containing the method name final String parameter = mapping.getParameter(); if ( parameter == null ) { final String message = messages.getMessage( "dispatch.handler", mapping.getPath() ); log.error( message ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } // Identify the method name to be dispatched to. // dispatchMethod() will call unspecified() if name is null final String name = request.getParameter( parameter ); // Invoke the named method, and return the result return dispatchMethod( mapping, form, request, response, name ); } /** * Process the specified HTTP request, and create the corresponding HTTP response (or forward to another web * component that will create it). Return an <code>ActionForward</code> instance describing where and how control * should be forwarded, or <code>null</code> if the response has already been completed. * * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * @exception Exception if an exception occurs * @return ActionForward */ public ActionForward wExecute( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response, final WatchedTask task ) throws Exception { // Identify the request parameter containing the method name final String parameter = mapping.getParameter(); if ( parameter == null ) { final String message = messages.getMessage( "dispatch.handler", mapping.getPath() ); log.error( message ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } // Identify the method name to be dispatched to. // dispatchMethod() will call unspecified() if name is null final String name = request.getParameter( parameter ); // Invoke the named method, and return the result return dispatchMethod( mapping, form, request, response, name, task ); } /** * Method which is dispatched to when there is no value for specified request parameter included in the request. * Subclasses of <code>DispatchAction</code> should override this method if they wish to provide default behavior * different than producing an HTTP "Bad Request" error. * * @see org.apache.struts.actions.DispatchAction#unspecified(org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ protected ActionForward unspecified( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response ) throws Exception { final String message = messages.getMessage( "dispatch.parameter", mapping.getPath(), mapping.getParameter() ); log.error( message ); response.sendError( HttpServletResponse.SC_BAD_REQUEST, message ); return ( null ); } // ----------------------------------------------------- Protected Methods /** * Dispatch to the specified method. * * @since Struts 1.1 * @see org.apache.struts.actions.DispatchAction#dispatchMethod(org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, String name) */ protected ActionForward dispatchMethod( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response, final String name ) throws Exception { // Make sure we have a valid method name to call. // This may be null if the user hacks the query string. if ( name == null ) { return this.unspecified( mapping, form, request, response ); } // Identify the method object to be dispatched to Method method = null; try { method = getMethod( name, types ); } catch ( final NoSuchMethodException e ) { final String message = messages.getMessage( "dispatch.method", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } ActionForward forward = null; try { final Object args[] = { mapping, form, request, response }; forward = (ActionForward) method.invoke( this, args ); } catch ( final ClassCastException e ) { final String message = messages.getMessage( "dispatch.return", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } catch ( final IllegalAccessException e ) { final String message = messages.getMessage( "dispatch.error", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } catch ( final InvocationTargetException e ) { // Rethrow the target exception if possible so that the // exception handling machinery can deal with it final Throwable t = e.getTargetException(); if ( t instanceof Exception ) { throw ( (Exception) t ); } else { final String message = messages.getMessage( "dispatch.error", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } } // Return the returned ActionForward instance return ( forward ); } /** * Dispatch to the specified method. * * @since Struts 1.1 * @see org.apache.struts.actions.DispatchAction#dispatchMethod(org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse, String name) */ protected ActionForward dispatchMethod( final ActionMapping mapping, final ActionForm form, final HttpServletRequest request, final HttpServletResponse response, final String name, final WatchedTask task ) throws Exception { // Make sure we have a valid method name to call. // This may be null if the user hacks the query string. if ( name == null || task == null ) { return this.unspecified( mapping, form, request, response ); } // Identify the method object to be dispatched to Method method = null; try { method = getMethod( name, typesProgressBar ); } catch ( final NoSuchMethodException e ) { final String message = messages.getMessage( "dispatch.method", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } ActionForward forward = null; try { final Object args[] = { mapping, form, request, response, task }; forward = (ActionForward) method.invoke( this, args ); } catch ( final ClassCastException e ) { final String message = messages.getMessage( "dispatch.return", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } catch ( final IllegalAccessException e ) { final String message = messages.getMessage( "dispatch.error", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } catch ( final InvocationTargetException e ) { // Rethrow the target exception if possible so that the // exception handling machinery can deal with it final Throwable t = e.getTargetException(); if ( t instanceof Exception ) { throw ( (Exception) t ); } else { final String message = messages.getMessage( "dispatch.error", mapping.getPath(), name ); log.error( message, e ); response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message ); return ( null ); } } // Return the returned ActionForward instance return ( forward ); } /** * Introspect the current class to identify a method of the specified name that accepts the same parameter types as * the <code>execute</code> method does. * * @param name Name of the method to be introspected * @exception NoSuchMethodException if no such method can be found * @return methode */ protected Method getMethod( final String name, Class[] argsTypes ) throws NoSuchMethodException { synchronized ( methods ) { Method method = (Method) methods.get( name ); if ( method == null ) { method = clazz.getMethod( name, argsTypes ); methods.put( name, method ); } return ( method ); } } }