📄 actionsupport.java
字号:
/*
* WebWork, Web Application Framework
*
* Distributable under Apache license.
* See terms of license at opensource.org
*/
package webwork.action;
import org.apache.commons.logging.*;
import java.io.Serializable;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.text.MessageFormat;
import javax.servlet.ServletRequest;
import webwork.util.editor.PropertyEditorException;
/**
* This is a useful base class for WebWork Action implementations. It gives you access to
* a set of useful functionality, including result view mapping, error handling, and i18n.
* <p>
* It is also possible to use this class by way of delegation instead of subclassing.
* This is useful in the case that your action cannot use subclassing to add functionality
*
* @see Action
* @author Rickard Oberg (rickard@middleware-company.com)
* @author Victor Salaman (salaman@qoretech.com)
* @version $Revision: 1.50 $
*/
public class ActionSupport
implements Action, Serializable, IllegalArgumentAware
{
// Attributes ----------------------------------------------------
static private Log debugLog = LogFactory.getLog(ActionSupport.class);
protected transient Log log = LogFactory.getLog(this.getClass());
protected Map errorMap;
protected Collection errorMessages;
protected String command;
private String actionName = null;
// IllegalArgumentAware implementation -----------------------------
/*
* This method is called when a field cannot be set because of an invalid or empty value.
* If the exception is a PropertyEditorException then the exception message is a
* bundle key that will be looked up by calling the getPropertyEditorMessage method.
*
* @see IllegalArgumentAware
* @see webwork.util.editor.PropertyEditorException
*/
public void addIllegalArgumentException(String fieldName, IllegalArgumentException e)
{
String msg = e.getMessage();
if (e instanceof PropertyEditorException)
{
msg = getPropertyEditorMessage(fieldName, (PropertyEditorException) e);
}
addError(fieldName, msg);
}
/**
* This method is called from addIllegalArgumentException and it should return an
* error message (that may be localized).
* The implementation here does this by calling the getText method but you may
* override it with your own implementation.
* The default messages are stored in the ActionSupport.properties file
*/
protected String getPropertyEditorMessage(String fieldName, PropertyEditorException pe)
{
String bundleText = getText(pe.getBundleKey());
Object[] propertyValues = pe.getPropertyValues();
if (propertyValues == null)
return bundleText;
else
return MessageFormat.format(bundleText, propertyValues);
}
// CommandDriven implementation ----------------------------------
/**
* Support implementation of CommandDriven interface. Let your action
* subclasses implement CommandDriven if they support this notion.
*
* @see CommandDriven
*/
public void setCommand(String command)
{
this.command = command;
}
/**
* Detect whether a particular command has been issued
*/
public boolean isCommand(String aName)
{
return (command != null && command.equals(aName));
}
// Action implementation -----------------------------------------
/**
* Execute will first check the request for a result exception. If one
* is found, then it will add its message as an error message and throw
* the ResultException. If there no exception is found, then it will
* invoke the "command" - invokeCommand(). If we are not invoking a command,
* it will call validate() and then doExecute().
*
* @return view
*/
public String execute()
throws Exception
{
long start = 0;
if (debugLog.isDebugEnabled())
{
debugLog.debug("Action executing..");
start = System.currentTimeMillis();
}
try
{
// if we're in a web context - check to see if there already is a result exception
// in the request. If so, add its message as an error message and throw it.
Object request = ActionContext.getContext().get(ServletActionContext.REQUEST);
if (request != null)
{
ResultException re = (ResultException) ((ServletRequest)request).getAttribute("webwork.action.ResultException");
if (re != null)
{
// Any error message in the exception is added in the catch later
// Remove it since it has been handled
((ServletRequest)request).removeAttribute("webwork.action.ResultException");
throw re;
}
}
// Check whether command is being invoked
if (command != null && command.length() > 0 && this instanceof CommandDriven)
{
return invokeCommand();
} else
{
// Validate input data
validate();
// Do main processing
return doExecute();
}
} catch (ResultException e)
{
// Add the error message from the exception, it there is one
String msg = e.getMessage();
if (msg != null)
addErrorMessage(msg);
return e.getResult();
} finally
{
if (debugLog.isDebugEnabled())
{
debugLog.debug("Action execution done");
debugLog.debug("Action executed in " + (System.currentTimeMillis() - start) + " ms");
}
}
}
// Public ---------------------------------------------------------
/**
* "default" command
*/
public String doDefault()
throws Exception
{
return INPUT;
}
/**
* Get the list of error messages for this action
*
* @return list of error messages
*/
public Collection getErrorMessages()
{
if (errorMessages == null)
errorMessages = new ArrayList();
return errorMessages;
}
public void setErrorMessages(Collection errorMessages)
{
this.errorMessages = errorMessages;
}
/**
* Check whether there are any error messages
*
* @return true if any error messages have been registered
*/
public boolean getHasErrorMessages()
{
return (errorMessages == null) ? false : errorMessages.size() > 0;
}
/**
* Add an error message to this action
*
* @param anErrorMessage
*/
public void addErrorMessage(String anErrorMessage)
{
if (errorMessages == null)
errorMessages = new ArrayList();
errorMessages.add(anErrorMessage);
}
/**
* This method is used to attach an error message to a particular form field.
*
* @param fieldName name of field
* @param errorMessage the error message
*/
public void addError(String fieldName, String errorMessage)
{
if (errorMap == null)
errorMap = new HashMap();
errorMap.put(fieldName, errorMessage);
}
/**
* Get the field specific errors associated with this action.
*
* @return map with errors
*/
public Map getErrors()
{
if (errorMap == null)
errorMap = new HashMap();
return errorMap;
}
public void setErrors(Map errorMap)
{
this.errorMap = errorMap;
}
/**
* Check whether there are any errors associated with this action.
*
* @return whether there are any errors
*/
public boolean getHasErrors()
{
return (errorMap == null) ? false : errorMap.size() > 0;
}
/**
* Get the locale for this action.
*
* Applications may customize how locale is chosen by
* subclassing ActionSupport and override this method.
*
* @return the locale to use
*/
public Locale getLocale()
{
return ActionContext.getLocale();
}
/**
* Get the named bundle.
*
* You can override the getLocale() method to change the behaviour of how
* to choose locale for the bundles that are returned. Typically you would
* use the LocaleAware interface to get the users configured locale, or use
* your own method to allow the user to select the locale and store it in
* the session (by using the SessionAware interface).
*
* @param aBundleName bundle name
* @return a resource bundle
*/
public ResourceBundle getTexts(String aBundleName)
{
return ResourceBundle.getBundle(aBundleName, getLocale(), Thread.currentThread().getContextClassLoader());
}
/**
* Get the resource bundle associated with this action.
* This will be based on the actual subclass that is used.
*
* @return resouce bundle
*/
public ResourceBundle getTexts()
{
return getTexts(getClass().getName());
}
/**
* Get a text from the resource bundles associated with this action.
* The resource bundles are searched, starting with the one associated
* with this particular action, and testing all its superclasses' bundles.
* It will stop once a bundle is found that contains the given text. This gives
* a cascading style that allow global texts to be defined for an application base
* class.
*
* @param aTextName name of text to be found
* @return value of named text
*/
public String getText(String aTextName)
{
Class thisClass = getClass();
MissingResourceException e;
do
{
try
{
ResourceBundle bundle = getTexts(thisClass.getName());
return bundle.getString(aTextName);
} catch (MissingResourceException ex)
{
e = ex;
thisClass = thisClass.getSuperclass();
}
} while (!thisClass.equals(Object.class));
throw e;
}
// Protected -----------------------------------------------------
protected String doExecute()
throws Exception
{
// Override this method in subclasses
return SUCCESS;
}
/**
* Subclasses may override this method to provide validation
* of input data. The execute() method should call validate()
* in the beginning of its code (which will delegate to this method),
* so as to check input data
* before doing the actual processing.
* <p>
* If any application errors arise these should be registered
* by calling addErrorMessage or addError .
* <p>
* If the validation is dependent on whether a command has been issued,
* and what that command is, then the isCommand() method should be used.
*
*/
protected void doValidation()
{
}
/**
* Do validation. This method is called implicitly before executing doExecute(), but must be
* called explicitly from within command implementation methods. The actual validation should be done by overriding
* the doValidation() method. If any errors have been registered by doValidation()
* this method will throw ResultException() which should simply be passed through.
*/
protected void validate()
throws ResultException
{
// Do validation of input
doValidation();
// Check if any errors was detected
if (invalidInput())
{
throw new ResultException(Action.INPUT);
}
}
/**
* Check whether there are any error messages. Just a nicer way
* of doing "getHasErrorMessages() || getHasErrors()".
*
* @return true if any error messages have been registered
*/
public boolean invalidInput()
{
return getHasErrorMessages() || getHasErrors();
}
/**
* Invokes an alternate execution path for the action. The name of the action
* is derived by prepending a "do" and capitalizing the first letter of the
* action.
*
*/
protected String invokeCommand() throws Exception
{
StringBuffer sb = new StringBuffer("do");
sb.append(command);
sb.setCharAt(2, Character.toUpperCase(sb.charAt(2)));
String cmd = sb.toString();
debugLog.debug("Executing action with command=" + command + " (mapped to method: " + cmd + ")");
Method method;
try
{
method = getClass().getMethod(cmd, new Class[0]);
} catch (NoSuchMethodException e)
{
throw new IllegalArgumentException("No command '" + command + "' in action");
}
try
{
return (String) method.invoke(this, new Object[0]);
} catch (InvocationTargetException e)
{
/**
* We try to return the source exception.
*/
Throwable t = e.getTargetException();
if (t instanceof Exception)
throw (Exception) t;
throw e;
}
}
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
// Restore log
log = LogFactory.getLog(this.getClass());
}
/**
* This is used to get the current action's class name
*/
protected String getActionName()
{
if (actionName == null)
{
String classname = getClass().getName();
actionName = classname.substring(classname.lastIndexOf('.') + 1);
}
return actionName;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -