blob: 52572520bdb513d1045fc38ee8971dacca1012b4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.empire.struts2.action;
import java.sql.Connection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import org.apache.empire.commons.ErrorType;
import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.Column;
import org.apache.empire.struts2.actionsupport.ActionBase;
import org.apache.empire.struts2.actionsupport.ActionError;
import org.apache.empire.struts2.actionsupport.ActionPropertySupport;
import org.apache.empire.struts2.actionsupport.TextProviderActionSupport;
import org.apache.empire.struts2.web.EmpireThreadManager;
import org.apache.empire.struts2.web.UrlHelperEx;
import org.apache.empire.struts2.web.FieldErrors;
import org.apache.empire.struts2.web.WebRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.TextProvider;
import com.opensymphony.xwork2.util.ValueStack;
/**
* WebAction should be used as the superclass for all your struts2 action classes.<BR>
* It implements necessary interfaces for parameter-, translation- and error-handling.<BR>
*/
public abstract class WebAction extends ActionBase
implements Disposable, ExceptionAware, ActionAccessValidator, ActionErrorProvider, TextProvider
// implements Action, Validateable, ValidationAware, ValidationAware, TextProvider, LocaleProvider, Serializable
{
// Logger
@SuppressWarnings("hiding")
protected static Logger log = LoggerFactory.getLogger(WebAction.class);
// Default Name for Item param
public static String DEFAULT_ITEM_PROPERTY_NAME = "item";
public static String PORTLET_ACTION_RESULT = "struts.portlet.actionResult";
private final transient TextProvider textProvider = TextProviderActionSupport.getInstance(getClass(), this); // new TextProviderFactory().createInstance(getClass(), this);
private ActionPropertySupport itemProperty = new ActionPropertySupport(this, DEFAULT_ITEM_PROPERTY_NAME, true);
// ------- Implementation of Disposable interface -------
/**
* Initialize the action
*
* Should be used instead of the constructor to initialize the action
* The method is called from the ActionBasicsInterceptor
*/
public void init()
{
// Avoid the constructor for initialization and use init instead
// this is called by the ActionBasicsInterceptor
}
/**
* Cleanup resources allocated by the action
*
* this requires the action to be stored on the request in a param named "action"
* the ActionBasicsInterceptor performs this task
* the dispose method will then be called from the EmpireStrutsDispatcher
*/
public int dispose()
{
if (hasActionError())
return EXITCODE_ERROR;
// Cleanup any resouces
return EXITCODE_SUCCESS;
}
// ------- Implementation of ExceptionAware interface -------
/**
* handle any exception that may have occurred
* The method is called from the ActionBasicsInterceptor
*/
public String handleException(Throwable exception, String method)
{
// Uncaught exception
ActionError excetionError = new ActionError(exception);
// Check if there already is an error
if (actionError!=null && actionError.hasError())
{ // War replace
log.warn("An uncaught exception occurred after an error has already been set!");
log.warn("Replacing error of " + actionError.getErrorMessage() + " with " + excetionError.getErrorMessage());
}
else
{ log.warn("An uncaught exception occurred. Message is " + excetionError.getErrorMessage());
}
// uncaught exception
setActionError(excetionError);
// retrun error mapping
return null; // Default Exception Handling
}
// ------- Implementation of ActionAccessValidator interface -------
/**
* Determines whether the user needs to Login to access this page
* important: return false if the user has already logged in!
*
* The method is called from the ActionAccessInterceptor
*/
public boolean loginRequired()
{
return false;
}
/**
* Determines whether the user has access to this page or a particular method
*
* The method is called from the ActionAccessInterceptor
*/
public boolean hasAccess(String method)
{
return true;
}
// ------- Action Error -------
private final String LAST_ACTION_ERROR_ATTRIBUTE = "lastActionError";
private ActionError actionError;
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#hasActionError()
*/
public boolean hasActionError()
{
return ((actionError!=null && actionError.hasError()) || fieldErrors!=null);
}
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#getActionError()
*/
public void clearActionErrors()
{
actionError = null;
fieldErrors = null;
// Remove from Session
ActionContext context = ActionContext.getContext();
if (context!=null)
context.getSession().remove(LAST_ACTION_ERROR_ATTRIBUTE);
}
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#getLastActionError(boolean)
*/
public ErrorInfo getLastActionError(boolean clear)
{
ActionContext context = ActionContext.getContext();
ErrorInfo error = (ErrorInfo)context.getSession().get(LAST_ACTION_ERROR_ATTRIBUTE);
if (clear)
context.getSession().remove(LAST_ACTION_ERROR_ATTRIBUTE);
return error;
}
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#getLocalizedErrorMessage(org.apache.empire.commons.ErrorInfo)
*/
public String getLocalizedErrorMessage(ErrorInfo error)
{ // Get the message
if (error==null) // || !error.hasError())
return "";
// Translate the error
String msgKey = error.getErrorType().getKey();
String[] args = ObjectUtils.toStringArray(error.getErrorParams(), "Null");
return getText(msgKey, args);
}
protected void setActionError(ErrorInfo error)
{
// Check error param
if (error==null)
{ // No Error
actionError = null;
return;
}
/*
if (error.hasError()==false)
{ log.warn("setActionError: No error information supplied.");
error = new ActionError(Errors.Internal, "No error information available!");
}
*/
// We have an error
if (error instanceof ActionError)
actionError = ((ActionError)error);
else
actionError = new ActionError(error);
// put Error on session
ActionContext context = ActionContext.getContext();
context.getSession().put(LAST_ACTION_ERROR_ATTRIBUTE, actionError);
}
protected final void setActionError(ErrorType errType)
{
setActionError(new ActionError(errType));
}
protected final void setActionError(ErrorType errType, String param)
{
setActionError(new ActionError(errType, param));
}
@Override
public final void setActionError(Exception exception)
{
setActionError(new ActionError(exception));
}
// ------- Field Errors -------
private Map<String, ErrorInfo> fieldErrors;
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#getFieldErrors()
*/
public Map<String, ErrorInfo> getItemErrors()
{
return fieldErrors;
}
private void addItemError(String item, ActionError error)
{
if (fieldErrors== null)
fieldErrors = new LinkedHashMap<String, ErrorInfo>();
// Error Message
if (log.isWarnEnabled())
log.warn("Invlalid value for item or field " + item + " Message= " + error.getErrorMessage());
// Map of errors
fieldErrors.put(item, error);
}
protected void addItemError(String item, ErrorType errorType, String title, ErrorInfo error)
{ // Check error
if (error==null) // .hasError()==false)
{ log.error("addItemError has been called without an error provided!");
return;
}
// Get Title
if (title.startsWith("!"))
title = getText(title.substring(1));
// Get Message
String msgKey = error.getErrorType().getKey();
String[] args = ObjectUtils.toStringArray(error.getErrorParams(), "Null");
String msg = getText(msgKey, args);
// Get full Message
addItemError(item, new ActionError(errorType, new String[] { title, msg }));
}
@Override
protected void addFieldError(String name, Column column, ErrorInfo error)
{
addItemError(name, FieldErrors.FieldError, column.getTitle(), error);
}
// ------- Action Message -------
private final String LAST_ACTION_MESSAGE_ATTRIBUTE = "lastActionMessage";
/*
* @see org.apache.empire.struts2.action.ActionErrorProvider#getLastActionMessage(boolean)
*/
public String getLastActionMessage(boolean clear)
{
ActionContext context = ActionContext.getContext();
Object msg = context.getSession().get(LAST_ACTION_MESSAGE_ATTRIBUTE);
if (clear)
context.getSession().remove(LAST_ACTION_MESSAGE_ATTRIBUTE);
return StringUtils.toString(msg);
}
protected void setActionMessage(String message)
{ // put Message on session
if (message.startsWith("!"))
message = getText(message.substring(1));
ActionContext context = ActionContext.getContext();
context.getSession().put(LAST_ACTION_MESSAGE_ATTRIBUTE, message);
}
// ------- Locale Provider -------
public Locale getLocale()
{
return ActionContext.getContext().getLocale();
}
// ------- Text Provider -------
/*
* UPGRADE-struts 2.1.6
* CHANGE: added method "hasKey(String key)"
* Reason: The interface com.opensymphony.xwork2.config.entities.Parameterizable changed
*/
public boolean hasKey(String key) {
return textProvider.hasKey(key);
}
public String getText(String aTextName) {
return textProvider.getText(aTextName);
}
public String getText(String aTextName, String defaultValue) {
return textProvider.getText(aTextName, defaultValue);
}
public String getText(String aTextName, String defaultValue, String obj) {
return textProvider.getText(aTextName, defaultValue, obj);
}
public String getText(String aTextName, List<Object> args) {
return textProvider.getText(aTextName, args);
}
public String getText(String key, String[] args) {
return textProvider.getText(key, args);
}
public String getText(String aTextName, String defaultValue, List<Object> args) {
return textProvider.getText(aTextName, defaultValue, args);
}
public String getText(String key, String defaultValue, String[] args) {
return textProvider.getText(key, defaultValue, args);
}
public String getText(String key, String defaultValue, List<Object> args, ValueStack stack) {
return textProvider.getText(key, defaultValue, args, stack);
}
public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
return textProvider.getText(key, defaultValue, args, stack);
}
public ResourceBundle getTexts() {
return textProvider.getTexts();
}
public ResourceBundle getTexts(String aBundleName) {
return textProvider.getTexts(aBundleName);
}
// ------- Special -------
@Override
public int getListPageSize()
{
return -1; // Infinite List Size
}
@Override
protected Connection getConnection()
{
return null;
}
// ------- ActionItem Property -------
public String getItemPropertyName()
{
return itemProperty.getName();
}
public String getItem()
{ // Get Item from request?
return itemProperty.getValue();
}
public void setItem(String value)
{ // Set Session Item
itemProperty.setValue(value);
}
public void clearItem()
{
itemProperty.clear();
}
public boolean isNewItem()
{
return getItemNewFlag();
}
protected final boolean hasItem(boolean lookOnSession)
{
return itemProperty.hasValue(lookOnSession);
}
protected final Object[] getItemKey()
{
return getRecordKeyFromString( getItem() );
}
protected final boolean getItemNewFlag()
{
return getRecordNewFlagFromString( getItem() );
}
// ------- Request Param accessors -------
public final Map<String,Object> getRequestParameters()
{
ActionContext context = ActionContext.getContext();
return (context!=null) ? context.getParameters() : null;
}
public final boolean hasRequestParam(String param)
{
return (getRequestParam(param)!=null);
}
public final String getRequestParam(String param)
{
Map<String,Object> params = getRequestParameters();
Object value = params.get( param );
// Is the error provided?
if (value==null)
return null;
// Check if it is a String-Array
if (value instanceof String[])
return ((String[])value)[0];
// convert to string
return value.toString();
}
public final String[] getRequestArrayParam(String param)
{
Map<String,Object> params = getRequestParameters();
Object value = params.get( param );
if (value==null)
return null; // null is default
// Check if it is a String-Array
if (value instanceof String[])
return (String[])value;
// Create new String array
return new String[] { value.toString() };
}
public final Integer getRequestIntParam(String param)
{
String s = getRequestParam(param);
if (s==null)
return 0; // not found
return Integer.parseInt(s);
}
@SuppressWarnings("unchecked")
public final void putRequestParam(String name, String value)
{
Map params = getRequestParameters();
if (value!=null)
params.put(name, new String[] { value });
else
params.remove(name);
}
// ------- ActionParam accessors -------
protected String getActionParam(String name)
{
// If name is null, then use WebAction-Item
if (name==null || name.length()==0)
{ log.error("Invalid value for parameter 'name'");
return null;
}
// Find Item on Request
String item = getRequestParam(name);
// Check if item is supplied
if (item==null)
return StringUtils.toString(getActionObject(name));
// Set Session Item
putActionObject(name, item);
return item;
}
// ------- URL generator -------
/**
* returns the url for an action.
* Waring: The following function may only use in a Servlet environment.
* @deprecated
*/
@Deprecated
public String getActionURL(String action, Map<String,Object> parameters)
{
Object request = EmpireThreadManager.getCurrentRequest();
if ((request instanceof WebRequest)==false)
{
log.error("cannot determine action URL. Request object does not implement WebRequest");
return null;
}
// We have a webRequest
WebRequest webRequest = (WebRequest)request;
// Get the uri
String uri = "/" + action;
if (uri.indexOf('.')<0)
uri += ".action";
// now build the url
return UrlHelperEx.buildUrl(uri, webRequest.getRequestContext(), webRequest.getResponseContext(), parameters, null, true, true);
}
// ----------- Portlet --------------
public String renderPortlet()
{
Map<String, Object> sessionMap = ActionContext.getContext().getSession();
Object result = sessionMap.get(PORTLET_ACTION_RESULT);
if (log.isDebugEnabled())
log.debug("Processing portlet render result with result=" + result);
return result.toString();
}
}