/*
* Copyright 2002-2006,2009 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 com.opensymphony.xwork2;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.dispatcher.HttpParameters;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
/**
* <p>
* The ActionContext is the context in which an {@link Action} is executed. Each context is basically a
* container of objects an action needs for execution like the session, parameters, locale, etc.
* </p>
*
* <p>
* The ActionContext is thread local which means that values stored in the ActionContext are
* unique per thread. See the {@link ThreadLocal} class for more information. The benefit of
* this is you don't need to worry about a user specific action context, you just get it:
* </p>
*
* <code>ActionContext context = ActionContext.getContext();</code>
*
* <p>
* Finally, because of the thread local usage you don't need to worry about making your actions thread safe.
* </p>
*
* @author Patrick Lightbody
* @author Bill Lynch (docs)
*/
public class ActionContext implements Serializable {
static ThreadLocal<ActionContext> actionContext = new ThreadLocal<>();
/**
* Constant for the name of the action being executed.
*/
public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
/**
* Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}.
*/
public static final String VALUE_STACK = ValueStack.VALUE_STACK;
/**
* Constant for the action's session.
*/
public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";
/**
* Constant for the action's application context.
*/
public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";
/**
* Constant for the action's parameters.
*/
public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";
/**
* Constant for the action's locale.
*/
public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";
/**
* Constant for the action's type converter.
*/
public static final String TYPE_CONVERTER = "com.opensymphony.xwork2.ActionContext.typeConverter";
/**
* Constant for the action's {@link com.opensymphony.xwork2.ActionInvocation invocation} context.
*/
public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";
/**
* Constant for the map of type conversion errors.
*/
public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";
/**
* Constant for the container
*/
public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";
private Map<String, Object> context;
/**
* Creates a new ActionContext initialized with another context.
*
* @param context a context map.
*/
public ActionContext(Map<String, Object> context) {
this.context = context;
}
/**
* Sets the action invocation (the execution state).
*
* @param actionInvocation the action execution state.
*/
public void setActionInvocation(ActionInvocation actionInvocation) {
put(ACTION_INVOCATION, actionInvocation);
}
/**
* Gets the action invocation (the execution state).
*
* @return the action invocation (the execution state).
*/
public ActionInvocation getActionInvocation() {
return (ActionInvocation) get(ACTION_INVOCATION);
}
/**
* Sets the action's application context.
*
* @param application the action's application context.
*/
public void setApplication(Map<String, Object> application) {
put(APPLICATION, application);
}
/**
* Returns a Map of the ServletContext when in a servlet environment or a generic application level Map otherwise.
*
* @return a Map of ServletContext or generic application level Map
*/
public Map<String, Object> getApplication() {
return (Map<String, Object>) get(APPLICATION);
}
/**
* Sets the action context for the current thread.
*
* @param context the action context.
*/
public static void setContext(ActionContext context) {
actionContext.set(context);
}
/**
* Returns the ActionContext specific to the current thread.
*
* @return the ActionContext for the current thread, is never <tt>null</tt>.
*/
public static ActionContext getContext() {
return actionContext.get();
}
/**
* Sets the action's context map.
*
* @param contextMap the context map.
*/
public void setContextMap(Map<String, Object> contextMap) {
getContext().context = contextMap;
}
/**
* Gets the context map.
*
* @return the context map.
*/
public Map<String, Object> getContextMap() {
return context;
}
/**
* Sets conversion errors which occurred when executing the action.
*
* @param conversionErrors a Map of errors which occurred when executing the action.
*/
public void setConversionErrors(Map<String, Object> conversionErrors) {
put(CONVERSION_ERRORS, conversionErrors);
}
/**
* Gets the map of conversion errors which occurred when executing the action.
*
* @return the map of conversion errors which occurred when executing the action or an empty map if
* there were no errors.
*/
public Map<String, Object> getConversionErrors() {
Map<String, Object> errors = (Map) get(CONVERSION_ERRORS);
if (errors == null) {
errors = new HashMap<>();
setConversionErrors(errors);
}
return errors;
}
/**
* Sets the Locale for the current action.
*
* @param locale the Locale for the current action.
*/
public void setLocale(Locale locale) {
put(LOCALE, locale);
}
/**
* Gets the Locale of the current action. If no locale was ever specified the platform's
* {@link java.util.Locale#getDefault() default locale} is used.
*
* @return the Locale of the current action.
*/
public Locale getLocale() {
Locale locale = (Locale) get(LOCALE);
if (locale == null) {
locale = Locale.getDefault();
setLocale(locale);
}
return locale;
}
/**
* Sets the name of the current Action in the ActionContext.
*
* @param name the name of the current action.
*/
public void setName(String name) {
put(ACTION_NAME, name);
}
/**
* Gets the name of the current Action.
*
* @return the name of the current action.
*/
public String getName() {
return (String) get(ACTION_NAME);
}
/**
* Sets the action parameters.
*
* @param parameters the parameters for the current action.
*/
public void setParameters(HttpParameters parameters) {
put(PARAMETERS, parameters);
}
/**
* Returns a Map of the HttpServletRequest parameters when in a servlet environment or a generic Map of
* parameters otherwise.
*
* @return a Map of HttpServletRequest parameters or a multipart map when in a servlet environment, or a
* generic Map of parameters otherwise.
*/
public HttpParameters getParameters() {
return (HttpParameters) get(PARAMETERS);
}
/**
* Sets a map of action session values.
*
* @param session the session values.
*/
public void setSession(Map<String, Object> session) {
put(SESSION, session);
}
/**
* Gets the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
*
* @return the Map of HttpSession values when in a servlet environment or a generic session map otherwise.
*/
public Map<String, Object> getSession() {
return (Map<String, Object>) get(SESSION);
}
/**
* Sets the OGNL value stack.
*
* @param stack the OGNL value stack.
*/
public void setValueStack(ValueStack stack) {
put(VALUE_STACK, stack);
}
/**
* Gets the OGNL value stack.
*
* @return the OGNL value stack.
*/
public ValueStack getValueStack() {
return (ValueStack) get(VALUE_STACK);
}
/**
* Gets the container for this request
*
* @param cont The container
*/
public void setContainer(Container cont) {
put(CONTAINER, cont);
}
/**
* Sets the container for this request
*
* @return The container
*/
public Container getContainer() {
return (Container) get(CONTAINER);
}
public <T> T getInstance(Class<T> type) {
Container cont = getContainer();
if (cont != null) {
return cont.getInstance(type);
} else {
throw new XWorkException("Cannot find an initialized container for this request.");
}
}
/**
* Returns a value that is stored in the current ActionContext by doing a lookup using the value's key.
*
* @param key the key used to find the value.
* @return the value that was found using the key or <tt>null</tt> if the key was not found.
*/
public Object get(String key) {
return context.get(key);
}
/**
* Stores a value in the current ActionContext. The value can be looked up using the key.
*
* @param key the key of the value.
* @param value the value to be stored.
*/
public void put(String key, Object value) {
context.put(key, value);
}
}