| /* |
| * 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(); |
| } |
| |
| } |