/* * $Header: /home/cvs/jakarta-struts/src/share/org/apache/struts/action/Action.java,v 1.77 2004/09/07 02:52:18 niallp Exp $ * $Revision: 1.77 $ * $Date: 2004/09/07 02:52:18 $ * * Copyright 2000-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.action; import java.util.Locale; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.sql.DataSource; import org.apache.struts.Globals; import org.apache.struts.config.ModuleConfig; import org.apache.struts.util.MessageResources; import org.apache.struts.util.ModuleUtils; import org.apache.struts.util.RequestUtils; import org.apache.struts.util.TokenProcessor; /** *
An Action is an adapter between the contents of an incoming
* HTTP request and the corresponding business logic that should be executed to
* process this request. The controller (RequestProcessor) will select an
* appropriate Action for each request, create an instance (if necessary),
* and call the execute
method.
Actions must be programmed in a thread-safe manner, because the * controller will share the same instance for multiple simultaneous * requests. This means you should design with the following items in mind: *
*When an Action
instance is first created, the controller
* will call setServlet
with a non-null argument to
* identify the servlet instance to which this Action is attached.
* When the servlet is to be shut down (or restarted), the
* setServlet
method will be called with a null
* argument, which can be used to clean up any allocated resources in use
* by this Action.
An instance of TokenProcessor
to use for token functionality.
The system default Locale.
* * @deprecated Use Locale.getDefault directly. This will be removed after * Struts 1.2. */ protected static Locale defaultLocale = Locale.getDefault(); // :TODO: Remove after Struts 1.2 /** *The servlet to which we are attached.
*/ protected ActionServlet servlet = null; // ------------------------------------------------------------- Properties /** *Return the servlet instance to which we are attached.
*/ public ActionServlet getServlet() { return (this.servlet); } /** *Set the servlet instance to which we are attached (if
* servlet
is non-null), or release any allocated resources
* (if servlet
is null).
Process the specified non-HTTP request, and create the
* corresponding non-HTTP response (or forward to another web
* component that will create it), with provision for handling
* exceptions thrown by the business logic.
* Return an {@link ActionForward} instance describing where and how
* control should be forwarded, or null
if the response has
* already been completed.
The default implementation attempts to forward to the HTTP * version of this method.
* * @param mapping The ActionMapping used to select this instance * @param form The optional ActionForm bean for this request (if any) * @param request The non-HTTP request we are processing * @param response The non-HTTP response we are creating * * @exception Exception if the application business logic throws * an exception. * @since Struts 1.1 */ public ActionForward execute( ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) throws Exception { try { return execute( mapping, form, (HttpServletRequest) request, (HttpServletResponse) response); } catch (ClassCastException e) { return null; } } /** *Process the specified HTTP request, and create the corresponding HTTP
* response (or forward to another web component that will create it),
* with provision for handling exceptions thrown by the business logic.
* Return an {@link ActionForward} instance describing where and how
* control should be forwarded, or null
if the response
* has already been completed.
Generate a new transaction token, to be used for enforcing a single * request for a particular transaction.
* * @param request The request we are processing */ protected String generateToken(HttpServletRequest request) { return token.generateToken(request); } /** *Return the default data source for the current module.
* * @param request The servlet request we are processing * * @since Struts 1.1 */ protected DataSource getDataSource(HttpServletRequest request) { return (getDataSource(request, Globals.DATA_SOURCE_KEY)); } /** *Return the specified data source for the current module.
* * @param request The servlet request we are processing * @param key The key specified in the *<message-resources>
element for the
* requested bundle
*
* @since Struts 1.1
*/
protected DataSource getDataSource(HttpServletRequest request, String key) {
// Identify the current module
ServletContext context = getServlet().getServletContext();
ModuleConfig moduleConfig =
ModuleUtils.getInstance().getModuleConfig(request, context);
return (DataSource) context.getAttribute(key + moduleConfig.getPrefix());
}
/**
* Retrieves any existing errors placed in the request by previous actions. This method could be called instead
* of creating a new ActionMessages() at the beginning of an Action
* This will prevent saveErrors() from wiping out any existing Errors
*
* @return the Errors that already exist in the request, or a new ActionMessages object if empty.
* @param request The servlet request we are processing
* @since Struts 1.2.1
*/
protected ActionMessages getErrors(HttpServletRequest request) {
ActionMessages errors =
(ActionMessages) request.getAttribute(Globals.ERROR_KEY);
if (errors == null) {
errors = new ActionMessages();
}
return errors;
}
/**
* Return the user's currently selected Locale.
*
* @param request The request we are processing
*/
protected Locale getLocale(HttpServletRequest request) {
return RequestUtils.getUserLocale(request, null);
}
/**
* Retrieves any existing messages placed in the request by previous actions. This method could be called instead
* of creating a new ActionMessages() at the beginning of an Action
* This will prevent saveMessages() from wiping out any existing Messages
*
* @return the Messages that already exist in the request, or a new ActionMessages object if empty.
* @param request The servlet request we are processing
* @since Struts 1.2.1
*/
protected ActionMessages getMessages(HttpServletRequest request) {
ActionMessages messages =
(ActionMessages) request.getAttribute(Globals.MESSAGE_KEY);
if (messages == null) {
messages = new ActionMessages();
}
return messages;
}
/**
* Return the default message resources for the current module.
*
* @param request The servlet request we are processing
* @since Struts 1.1
*/
protected MessageResources getResources(HttpServletRequest request) {
return ((MessageResources) request.getAttribute(Globals.MESSAGES_KEY));
}
/**
* Return the specified message resources for the current module.
*
* @param request The servlet request we are processing
* @param key The key specified in the
* <message-resources>
element for the
* requested bundle
*
* @since Struts 1.1
*/
protected MessageResources getResources(
HttpServletRequest request,
String key) {
// Identify the current module
ServletContext context = getServlet().getServletContext();
ModuleConfig moduleConfig =
ModuleUtils.getInstance().getModuleConfig(request, context);
// Return the requested message resources instance
return (MessageResources) context.getAttribute(
key + moduleConfig.getPrefix());
}
/**
* Returns true
if the current form's cancel button was
* pressed. This method will check if the Globals.CANCEL_KEY
* request attribute has been set, which normally occurs if the cancel
* button generated by CancelTag was pressed by the user
* in the current request. If true
, validation performed
* by an ActionForm's validate()
method
* will have been skipped by the controller servlet.
*
* @param request The servlet request we are processing
* @see org.apache.struts.taglib.html.CancelTag
*/
protected boolean isCancelled(HttpServletRequest request) {
return (request.getAttribute(Globals.CANCEL_KEY) != null);
}
/**
* Return true
if there is a transaction token stored in
* the user's current session, and the value submitted as a request
* parameter with this action matches it. Returns false
* under any of the following circumstances:
*
* - No session associated with this request
* - No transaction token saved in the session
* - No transaction token included as a request parameter
* - The included transaction token value does not match the
* transaction token in the user's session
*
*
* @param request The servlet request we are processing
*/
protected boolean isTokenValid(HttpServletRequest request) {
return token.isTokenValid(request, false);
}
/**
* Return true
if there is a transaction token stored in
* the user's current session, and the value submitted as a request
* parameter with this action matches it. Returns false
.
*
* - No session associated with this request
* - No transaction token saved in the session
* - No transaction token included as a request parameter
* - The included transaction token value does not match the
* transaction token in the user's session
*
*
* @param request The servlet request we are processing
* @param reset Should we reset the token after checking it?
*/
protected boolean isTokenValid(HttpServletRequest request, boolean reset) {
return token.isTokenValid(request, reset);
}
/**
* Reset the saved transaction token in the user's session. This
* indicates that transactional token checking will not be needed
* on the next request that is submitted.
*
* @param request The servlet request we are processing
*/
protected void resetToken(HttpServletRequest request) {
token.resetToken(request);
}
/**
* Save the specified error messages keys into the appropriate request
* attribute for use by the <html:errors> tag, if any messages
* are required. Otherwise, ensure that the request attribute is not
* created.
*
* @param request The servlet request we are processing
* @param errors Error messages object
* @deprecated Use saveErrors(HttpServletRequest, ActionMessages) instead.
* This will be removed after Struts 1.2.
*/
protected void saveErrors(HttpServletRequest request, ActionErrors errors) {
this.saveErrors(request,(ActionMessages)errors);
// :TODO: Remove after Struts 1.2.
}
/**
* Save the specified error messages keys into the appropriate request
* attribute for use by the <html:errors> tag, if any messages
* are required. Otherwise, ensure that the request attribute is not
* created.
*
* @param request The servlet request we are processing
* @param errors Error messages object
* @since Struts 1.2
*/
protected void saveErrors(HttpServletRequest request, ActionMessages errors) {
// Remove any error messages attribute if none are required
if ((errors == null) || errors.isEmpty()) {
request.removeAttribute(Globals.ERROR_KEY);
return;
}
// Save the error messages we need
request.setAttribute(Globals.ERROR_KEY, errors);
}
/**
* Save the specified messages keys into the appropriate request
* attribute for use by the <html:messages> tag (if
* messages="true" is set), if any messages are required. Otherwise,
* ensure that the request attribute is not created.
*
* @param request The servlet request we are processing.
* @param messages The messages to save. null
or empty
* messages removes any existing ActionMessages in the request.
*
* @since Struts 1.1
*/
protected void saveMessages(
HttpServletRequest request,
ActionMessages messages) {
// Remove any messages attribute if none are required
if ((messages == null) || messages.isEmpty()) {
request.removeAttribute(Globals.MESSAGE_KEY);
return;
}
// Save the messages we need
request.setAttribute(Globals.MESSAGE_KEY, messages);
}
/**
* Save the specified messages keys into the appropriate session
* attribute for use by the <html:messages> tag (if
* messages="true" is set), if any messages are required. Otherwise,
* ensure that the session attribute is not created.
*
* @param session The session to save the messages in.
* @param messages The messages to save. null
or empty
* messages removes any existing ActionMessages in the session.
*
* @since Struts 1.2
*/
protected void saveMessages(
HttpSession session,
ActionMessages messages) {
// Remove any messages attribute if none are required
if ((messages == null) || messages.isEmpty()) {
session.removeAttribute(Globals.MESSAGE_KEY);
return;
}
// Save the messages we need
session.setAttribute(Globals.MESSAGE_KEY, messages);
}
/**
* Save a new transaction token in the user's current session, creating
* a new session if necessary.
*
* @param request The servlet request we are processing
*/
protected void saveToken(HttpServletRequest request) {
token.saveToken(request);
}
/**
* Set the user's currently selected Locale
into their
* HttpSession
.
*
* @param request The request we are processing
* @param locale The user's selected Locale to be set, or null
* to select the server's default Locale
*/
protected void setLocale(HttpServletRequest request, Locale locale) {
HttpSession session = request.getSession();
if (locale == null) {
locale = Locale.getDefault();
}
session.setAttribute(Globals.LOCALE_KEY, locale);
}
}