mirror of
https://github.com/apache/struts.git
synced 2026-08-06 15:17:00 +00:00
bob's latest API
git-svn-id: https://svn.apache.org/repos/asf/struts/action2/trunk@408662 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
+2
-1
@@ -16,18 +16,19 @@
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
<!-- has to be compile for WebWorkTestCase, which is part of the base package so others can write unit tests -->
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.apache.struts.action2;
|
||||
|
||||
/**
|
||||
* Implemented by actions that may need to record error messages. For example:
|
||||
*
|
||||
* <pre>
|
||||
* static import ResultNames.*;
|
||||
*
|
||||
* public class SetName implements ErrorAware {
|
||||
*
|
||||
* Messages errors;
|
||||
* String name;
|
||||
*
|
||||
* public String execute() {
|
||||
* if ("".equals(name) {
|
||||
* errors.add("name.required");
|
||||
* return INPUT;
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
* return SUCCESS;
|
||||
* }
|
||||
*
|
||||
* public void setErrors(Messages errors) {
|
||||
* this.errors = errors;
|
||||
* }
|
||||
*
|
||||
* public void setName(String name) {
|
||||
* this.name = name;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see MessageAware
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface ErrorAware {
|
||||
|
||||
/**
|
||||
* Sets error messages.
|
||||
*
|
||||
* @param errors error messages
|
||||
*/
|
||||
void setErrors(Messages errors);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,33 @@
|
||||
package org.apache.struts.action2;
|
||||
|
||||
/**
|
||||
* Implemented by actions that may need to record messages.
|
||||
* Implemented by actions which may need to record errors or messages.
|
||||
*
|
||||
* <pre>
|
||||
* static import ResultNames.*;
|
||||
*
|
||||
* public class Welcome implements MessageAware {
|
||||
* public class SetName implements MessageAware {
|
||||
*
|
||||
* Messages messages;
|
||||
* String name;
|
||||
*
|
||||
* public String execute() {
|
||||
* messages.add("welcome");
|
||||
* return SUCCESS;
|
||||
* }
|
||||
*
|
||||
* public void setName(String name) {
|
||||
* if ("".equals(name))
|
||||
* messages.forField("name").addError("name.required");
|
||||
*
|
||||
* this.name = name;
|
||||
* }
|
||||
*
|
||||
* public void setMessages(Messages messages) {
|
||||
* this.messages = messages;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see ErrorAware
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface MessageAware {
|
||||
|
||||
@@ -2,71 +2,193 @@ package org.apache.struts.action2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Request and field-scoped messages or errors. Uses keys instead of actual messages to decouple code from messages.
|
||||
* Messages may come from multiple actions and interceptors.
|
||||
* Collection of messages. Supports nesting messages by field name.
|
||||
*
|
||||
* <p>Uses keys when adding instead of actual messages to decouple code from messages.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface Messages {
|
||||
|
||||
/**
|
||||
* Adds request-scoped message.
|
||||
* Message severity.
|
||||
*/
|
||||
public enum Severity {
|
||||
|
||||
/**
|
||||
* Informational messages.
|
||||
*/
|
||||
INFO,
|
||||
|
||||
/**
|
||||
* Warning messages.
|
||||
*/
|
||||
WARN,
|
||||
|
||||
/**
|
||||
* Error messages.
|
||||
*/
|
||||
ERROR,
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets nested messages for the given field.
|
||||
*
|
||||
* <p>Supports dot notation to represent nesting. For example:
|
||||
*
|
||||
* <pre>
|
||||
* messages.forField("foo").forField("bar") == messages.forField("foo.bar")
|
||||
* </pre>
|
||||
*
|
||||
* @param fieldName name of the field
|
||||
* @return nested {@code Messages} for given field name
|
||||
*/
|
||||
Messages forField(String fieldName);
|
||||
|
||||
/**
|
||||
* Gets map of field name to messages for that field.
|
||||
*
|
||||
* @return map of field name to {@code Messages}
|
||||
*/
|
||||
Map<String, Messages> forFields();
|
||||
|
||||
/**
|
||||
* Adds informational message.
|
||||
*
|
||||
* @param key message key
|
||||
* @see Severity.INFO
|
||||
*/
|
||||
void add(String key);
|
||||
void addInformation(String key);
|
||||
|
||||
/**
|
||||
* Adds informational message.
|
||||
*
|
||||
* @param key message key
|
||||
* @param arguments message arguments
|
||||
* @see Severity.INFO
|
||||
*/
|
||||
void addInformation(String key, Object... arguments);
|
||||
|
||||
/**
|
||||
* Adds warning message.
|
||||
*
|
||||
* @param key message key
|
||||
* @see Severity.WARN
|
||||
*/
|
||||
void addWarning(String key);
|
||||
|
||||
/**
|
||||
* Adds warning message.
|
||||
*
|
||||
* @param key message key
|
||||
* @param arguments message arguments
|
||||
* @see Severity.WARN
|
||||
*/
|
||||
void addWarning(String key, Object... arguments);
|
||||
|
||||
/**
|
||||
* Adds error message.
|
||||
*
|
||||
* @param key message key
|
||||
* @see Severity.ERROR
|
||||
*/
|
||||
void addError(String key);
|
||||
|
||||
/**
|
||||
* Adds error message.
|
||||
*
|
||||
* @param key message key
|
||||
* @param arguments message arguments
|
||||
* @see Severity.ERROR
|
||||
*/
|
||||
void addError(String key, Object... arguments);
|
||||
|
||||
/**
|
||||
* Adds message.
|
||||
*
|
||||
* @param severity message severity
|
||||
* @param key message key
|
||||
*/
|
||||
void add(Severity severity, String key);
|
||||
|
||||
/**
|
||||
* Adds request-scoped message.
|
||||
*
|
||||
* @param severity message severity
|
||||
* @param key message key
|
||||
* @param arguments message arguments
|
||||
*/
|
||||
void add(String key, Object... arguments);
|
||||
void add(Severity severity, String key, Object... arguments);
|
||||
|
||||
/**
|
||||
* Adds field-scoped message.
|
||||
* Gets set of severities for which this {@code Messages} instance has messages. Not recursive.
|
||||
*
|
||||
* @param fieldName name of field to attach message to
|
||||
* @param key message key
|
||||
* @return unmodifiable set of {@link Severity} sorted from least to most severe
|
||||
*/
|
||||
void add(String fieldName, String key);
|
||||
Set<Severity> getSeverities();
|
||||
|
||||
/**
|
||||
* Adds field-scoped message.
|
||||
* Gets message strings for the given severity. Not recursive.
|
||||
*
|
||||
* @param fieldName name of field to attach message to
|
||||
* @param key message key
|
||||
* @param arguments message arguments
|
||||
* @param severity message severity
|
||||
* @return unmodifiable list of messages
|
||||
*/
|
||||
void add(String fieldName, String key, Object... arguments);
|
||||
List<String> forSeverity(Severity severity);
|
||||
|
||||
/**
|
||||
* Gets request-scoped messages.
|
||||
* Gets error message strings for this {@code Messages} instance. Not recursive.
|
||||
*
|
||||
* @return unmodifiable list of messages for this request.
|
||||
* @return unmodifiable list of messages
|
||||
*/
|
||||
List<String> forRequest();
|
||||
List<String> getErrors();
|
||||
|
||||
/**
|
||||
* Gets field-scoped messages.
|
||||
* Gets error message strings for this {@code Messages} instance. Not recursive.
|
||||
*
|
||||
* @param fieldName field name
|
||||
* @return unmodifiable list of messages for the given field name.
|
||||
* @return unmodifiable list of messages
|
||||
*/
|
||||
List<String> forField(String fieldName);
|
||||
List<String> getWarnings();
|
||||
|
||||
/**
|
||||
* Gets names of fields which have messages attached.
|
||||
* Gets informational message strings for this {@code Messages} instance. Not recursive.
|
||||
*
|
||||
* @return unmodifiable set of field names with messages attached.
|
||||
* @return unmodifiable list of messages
|
||||
*/
|
||||
Set<String> getFieldNames();
|
||||
List<String> getInformation();
|
||||
|
||||
/**
|
||||
* Returns true if no request or field-scoped messages have been added.
|
||||
* Returns true if this or a nested {@code Messages} instance has error messages.
|
||||
*
|
||||
* @see Severity.ERROR
|
||||
*/
|
||||
boolean hasErrors();
|
||||
|
||||
/**
|
||||
* Returns true if this or a nested {@code Messages} instance has warning messages.
|
||||
*
|
||||
* @see Severity.WARN
|
||||
*/
|
||||
boolean hasWarnings();
|
||||
|
||||
/**
|
||||
* Returns true if this or a nested {@code Messages} instance has informational messages.
|
||||
*
|
||||
* @see Severity.INFO
|
||||
*/
|
||||
boolean hasInformation();
|
||||
|
||||
/**
|
||||
* Returns true if this and all nested {@code Messages} instances have no messages.
|
||||
*/
|
||||
boolean isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this and all nested {@code Messages} instances have no messages for the given severity.
|
||||
*
|
||||
* @param severity message severity
|
||||
*/
|
||||
boolean isEmpty(Severity severity);
|
||||
}
|
||||
@@ -4,10 +4,9 @@ package org.apache.struts.action2;
|
||||
* Implemented by actions which wish to execute some validation logic before their action method. Useful for
|
||||
* cross-field validations.
|
||||
*
|
||||
* @see ErrorAware
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface Validatable {
|
||||
public interface Validatable extends MessageAware {
|
||||
|
||||
/**
|
||||
* Validates input. Executes before action method.
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package org.apache.struts.action2.attribute;
|
||||
|
||||
import org.apache.struts.action2.spi.Request;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequest;
|
||||
import org.apache.struts.action2.spi.RequestContext;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequestContext;
|
||||
|
||||
/**
|
||||
* A servlet context attribute. Synchronizes on the underlying {@code ServletContext} instance.
|
||||
@@ -20,9 +20,9 @@ public class ApplicationAttribute<T> extends AbstractAttribute<T> {
|
||||
}
|
||||
|
||||
T execute(UnitOfWork<T> unitOfWork) {
|
||||
Request request = ThreadLocalRequest.get();
|
||||
synchronized (request.getServletContext()) {
|
||||
return unitOfWork.execute(request.getApplicationMap());
|
||||
RequestContext requestContext = ThreadLocalRequestContext.get();
|
||||
synchronized (requestContext.getServletContext()) {
|
||||
return unitOfWork.execute(requestContext.getApplicationMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.apache.struts.action2.attribute;
|
||||
|
||||
import org.apache.struts.action2.spi.Request;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequest;
|
||||
import org.apache.struts.action2.spi.RequestContext;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequestContext;
|
||||
|
||||
/**
|
||||
* A request attribute. Synchronizes on the underlying {@code HttpServletRequest} instance.
|
||||
@@ -20,9 +20,9 @@ public class RequestAttribute<T> extends AbstractAttribute<T> {
|
||||
}
|
||||
|
||||
T execute(UnitOfWork<T> unitOfWork) {
|
||||
Request request = ThreadLocalRequest.get();
|
||||
synchronized (request.getServletRequest()) {
|
||||
return unitOfWork.execute(request.getAttributeMap());
|
||||
RequestContext requestContext = ThreadLocalRequestContext.get();
|
||||
synchronized (requestContext.getServletRequest()) {
|
||||
return unitOfWork.execute(requestContext.getAttributeMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.apache.struts.action2.attribute;
|
||||
|
||||
import org.apache.struts.action2.spi.Request;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequest;
|
||||
import org.apache.struts.action2.spi.RequestContext;
|
||||
import org.apache.struts.action2.spi.ThreadLocalRequestContext;
|
||||
|
||||
/**
|
||||
* A session attribute. Synchronizes on the underlying {@code HttpSession}.
|
||||
@@ -20,9 +20,9 @@ public class SessionAttribute<T> extends AbstractAttribute<T> {
|
||||
}
|
||||
|
||||
T execute(UnitOfWork<T> unitOfWork) {
|
||||
Request request = ThreadLocalRequest.get();
|
||||
synchronized (request.getServletRequest().getSession()) {
|
||||
return unitOfWork.execute(request.getSessionMap());
|
||||
RequestContext requestContext = ThreadLocalRequestContext.get();
|
||||
synchronized (requestContext.getServletRequest().getSession()) {
|
||||
return unitOfWork.execute(requestContext.getSessionMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
* Struts Action 2.0 user API.
|
||||
* Struts Action 2.0 user API
|
||||
*/
|
||||
package org.apache.struts.action2;
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Context of an action execution.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface ActionContext {
|
||||
|
||||
/**
|
||||
* Gets action instance.
|
||||
*/
|
||||
Object getAction();
|
||||
|
||||
/**
|
||||
* Gets action method.
|
||||
*/
|
||||
Method getMethod();
|
||||
|
||||
/**
|
||||
* Gets action name.
|
||||
*/
|
||||
String getActionName();
|
||||
|
||||
/**
|
||||
* Gets the path for the action's namespace.
|
||||
*/
|
||||
String getNamespacePath();
|
||||
|
||||
/**
|
||||
* Gets the {@link Result} instance for the action.
|
||||
*
|
||||
* @return {@link Result} instance or {@code null} if we don't have a result yet.
|
||||
*/
|
||||
Result getResult();
|
||||
|
||||
/**
|
||||
* Adds a result interceptor for the action. Enables executing code before and after a result, executing an
|
||||
* alternate result, etc.
|
||||
*/
|
||||
void addResultInterceptor(Result interceptor);
|
||||
|
||||
/**
|
||||
* Gets context of action which chained to us.
|
||||
*
|
||||
* @return context of previous action or {@code null} if this is the first action in the chain
|
||||
*/
|
||||
ActionContext getPrevious();
|
||||
|
||||
/**
|
||||
* Gets context of action which this action chained to.
|
||||
*
|
||||
* @return context of next action or {@code null} if we haven't chained to another action yet or this is the last
|
||||
* action in the chain.
|
||||
*/
|
||||
ActionContext getNext();
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public interface Interceptor {
|
||||
/**
|
||||
* Intercepts an action request.
|
||||
*
|
||||
* @param request current request
|
||||
* @param requestContext current request context
|
||||
*/
|
||||
String intercept(Request request) throws Exception;
|
||||
String intercept(RequestContext requestContext) throws Exception;
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
import org.apache.struts.action2.Messages;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.ServletContext;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* A Struts request. A single request may span multiple actions with action chaining.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface Request {
|
||||
|
||||
/**
|
||||
* Gets current action instance.
|
||||
*/
|
||||
Object getAction();
|
||||
|
||||
/**
|
||||
* Gets current action method.
|
||||
*/
|
||||
Method getMethod();
|
||||
|
||||
/**
|
||||
* Gets current action name.
|
||||
*/
|
||||
String getActionName();
|
||||
|
||||
/**
|
||||
* Gets the path for the current action's namespace.
|
||||
*/
|
||||
String getNamespacePath();
|
||||
|
||||
/**
|
||||
* Gets the {@link Result} instance for the current action.
|
||||
*
|
||||
* @return {@link Result} instance or {@code null} if we don't have a result yet.
|
||||
*/
|
||||
Result getResult();
|
||||
|
||||
/**
|
||||
* Adds a result interceptor for the current action. Enables executing code before and after a result, executing
|
||||
* an alternate result, etc.
|
||||
*/
|
||||
void addResultInterceptor(Result interceptor);
|
||||
|
||||
/**
|
||||
* Gets map of request parameters.
|
||||
*/
|
||||
Map<String, String[]> getParameterMap();
|
||||
|
||||
/**
|
||||
* Gets map of request attributes.
|
||||
*/
|
||||
Map<String, Object> getAttributeMap();
|
||||
|
||||
/**
|
||||
* Gets map of session attributes.
|
||||
*/
|
||||
Map<String, Object> getSessionMap();
|
||||
|
||||
/**
|
||||
* Gets map of application (servlet context) attributes.
|
||||
*/
|
||||
Map<String, Object> getApplicationMap();
|
||||
|
||||
/**
|
||||
* Finds cookies with the given name,
|
||||
*/
|
||||
List<Cookie> findCookiesForName(String name);
|
||||
|
||||
/**
|
||||
* Gets locale.
|
||||
*/
|
||||
Locale getLocale();
|
||||
|
||||
/**
|
||||
* Sets locale. Stores the locale in the session for future requests.
|
||||
*/
|
||||
void setLocale(Locale locale);
|
||||
|
||||
/**
|
||||
* Gets messages.
|
||||
*/
|
||||
Messages getMessages();
|
||||
|
||||
/**
|
||||
* Gets error messages.
|
||||
*/
|
||||
Messages getErrors();
|
||||
|
||||
/**
|
||||
* Gets the servlet request.
|
||||
*/
|
||||
HttpServletRequest getServletRequest();
|
||||
|
||||
/**
|
||||
* Gets the servlet response.
|
||||
*/
|
||||
HttpServletResponse getServletResponse();
|
||||
|
||||
/**
|
||||
* Gets the servlet context.
|
||||
*/
|
||||
ServletContext getServletContext();
|
||||
|
||||
/**
|
||||
* Gets the value stack.
|
||||
*/
|
||||
ValueStack getValueStack();
|
||||
|
||||
/**
|
||||
* Invokes the next interceptor or the action method if no more interceptors remain.
|
||||
*
|
||||
* @return result name
|
||||
* @throws IllegalStateException if already invoked or called from the action
|
||||
*/
|
||||
String proceed() throws Exception;
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
/**
|
||||
* Implemented by actions that need access to the current {@link Request}. Use judiciously.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface RequestAware {
|
||||
|
||||
/**
|
||||
* Sets {@link Request}.
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
void setRequest(Request request);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
import org.apache.struts.action2.Messages;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Request context. A single request may span multiple actions with action chaining.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface RequestContext {
|
||||
|
||||
/**
|
||||
* Gets context of the currently executing action.
|
||||
*
|
||||
* @return current action context
|
||||
*/
|
||||
ActionContext getActionContext();
|
||||
|
||||
/**
|
||||
* Convenience method. Equivalent to {@code getActionContext().getAction()}.
|
||||
*
|
||||
* @return currently executing action
|
||||
*/
|
||||
Object getAction();
|
||||
|
||||
/**
|
||||
* Gets map of request parameters.
|
||||
*/
|
||||
Map<String, String[]> getParameterMap();
|
||||
|
||||
/**
|
||||
* Gets map of request attributes.
|
||||
*/
|
||||
Map<String, Object> getAttributeMap();
|
||||
|
||||
/**
|
||||
* Gets map of session attributes.
|
||||
*/
|
||||
Map<String, Object> getSessionMap();
|
||||
|
||||
/**
|
||||
* Gets map of application (servlet context) attributes.
|
||||
*/
|
||||
Map<String, Object> getApplicationMap();
|
||||
|
||||
/**
|
||||
* Finds cookies with the given name,
|
||||
*/
|
||||
List<Cookie> findCookiesForName(String name);
|
||||
|
||||
/**
|
||||
* Gets locale.
|
||||
*/
|
||||
Locale getLocale();
|
||||
|
||||
/**
|
||||
* Sets locale. Stores the locale in the session for future requests.
|
||||
*/
|
||||
void setLocale(Locale locale);
|
||||
|
||||
/**
|
||||
* Gets messages.
|
||||
*/
|
||||
Messages getMessages();
|
||||
|
||||
/**
|
||||
* Gets error messages.
|
||||
*/
|
||||
Messages getErrors();
|
||||
|
||||
/**
|
||||
* Gets the servlet request.
|
||||
*/
|
||||
HttpServletRequest getServletRequest();
|
||||
|
||||
/**
|
||||
* Gets the servlet response.
|
||||
*/
|
||||
HttpServletResponse getServletResponse();
|
||||
|
||||
/**
|
||||
* Gets the servlet context.
|
||||
*/
|
||||
ServletContext getServletContext();
|
||||
|
||||
/**
|
||||
* Gets the value stack.
|
||||
*/
|
||||
ValueStack getValueStack();
|
||||
|
||||
/**
|
||||
* Invokes the next interceptor or the action method if no more interceptors remain.
|
||||
*
|
||||
* @return result name
|
||||
* @throws IllegalStateException if already invoked or called from the action
|
||||
*/
|
||||
String proceed() throws Exception;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
/**
|
||||
* Implemented by actions that need access to the current {@link org.apache.struts.action2.spi.RequestContext}. Use
|
||||
* judiciously.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public interface RequestContextAware {
|
||||
|
||||
/**
|
||||
* Sets {@link org.apache.struts.action2.spi.RequestContext}.
|
||||
*
|
||||
* @param requestContext
|
||||
*/
|
||||
void setRequestContext(RequestContext requestContext);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public interface Result {
|
||||
/**
|
||||
* Executes result.
|
||||
*
|
||||
* @param request
|
||||
* @param requestContext
|
||||
*/
|
||||
void execute(Request request) throws Exception;
|
||||
void execute(RequestContext requestContext) throws Exception;
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Provides a reference to the current {@link Request} for this thread.
|
||||
*
|
||||
* <p>Actions which spawn additional threads are responsible for setting this value if access to Struts from the
|
||||
* additional thread is needed.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public final class ThreadLocalRequest {
|
||||
|
||||
static ThreadLocal<Request> threadLocalRequest = new ThreadLocal<Request>();
|
||||
|
||||
private ThreadLocalRequest() {}
|
||||
|
||||
/**
|
||||
* Sets {@link Request} for the current thread and invokes the provided {@link Callable}. Restores previous {@code
|
||||
* Request} (if any) when finished.
|
||||
*
|
||||
* @param request for current thread
|
||||
* @param callable
|
||||
* @return result of {@code callable}
|
||||
* @throws Exception from {@code callable}
|
||||
*/
|
||||
public static <T> T setAndCall(Request request, Callable<T> callable) throws Exception {
|
||||
Request old = threadLocalRequest.get();
|
||||
try {
|
||||
threadLocalRequest.set(request);
|
||||
return callable.call();
|
||||
} finally {
|
||||
if (old == null)
|
||||
threadLocalRequest.remove();
|
||||
else
|
||||
threadLocalRequest.set(old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Request} for the current thread.
|
||||
*
|
||||
* @return request for current thread
|
||||
* @throws IllegalStateException if no request has been set
|
||||
*/
|
||||
public static Request get() {
|
||||
Request request = threadLocalRequest.get();
|
||||
if (request == null) {
|
||||
throw new IllegalStateException(ThreadLocalRequest.class.getName() + " has not been set.");
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.apache.struts.action2.spi;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Provides a reference to the current {@link RequestContext} for this thread.
|
||||
*
|
||||
* <p>Actions which spawn additional threads are responsible for setting this value if access to Struts from the
|
||||
* additional thread is needed.
|
||||
*
|
||||
* @author crazybob@google.com (Bob Lee)
|
||||
*/
|
||||
public final class ThreadLocalRequestContext {
|
||||
|
||||
static ThreadLocal<RequestContext> threadLocalRequestContext = new ThreadLocal<RequestContext>();
|
||||
|
||||
private ThreadLocalRequestContext() {}
|
||||
|
||||
/**
|
||||
* Sets {@link RequestContext} for the current thread and invokes the provided {@link Callable}. Restores previous
|
||||
* {@code RequestContext} (if any) when finished.
|
||||
*
|
||||
* @param requestContext for current thread
|
||||
* @param callable
|
||||
* @return result of {@code callable}
|
||||
* @throws Exception from {@code callable}
|
||||
*/
|
||||
public static <T> T setAndCall(RequestContext requestContext, Callable<T> callable) throws Exception {
|
||||
RequestContext old = threadLocalRequestContext.get();
|
||||
try {
|
||||
threadLocalRequestContext.set(requestContext);
|
||||
return callable.call();
|
||||
} finally {
|
||||
if (old == null)
|
||||
threadLocalRequestContext.remove();
|
||||
else
|
||||
threadLocalRequestContext.set(old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link RequestContext} for the current thread.
|
||||
*
|
||||
* @return request for current thread
|
||||
* @throws IllegalStateException if no request has been set
|
||||
*/
|
||||
public static RequestContext get() {
|
||||
RequestContext requestContext = threadLocalRequestContext.get();
|
||||
if (requestContext == null) {
|
||||
throw new IllegalStateException(ThreadLocalRequestContext.class.getName() + " has not been set.");
|
||||
}
|
||||
return requestContext;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
* Struts Action 2.0 service provider API.
|
||||
* Struts Action 2.0 service provider API
|
||||
*/
|
||||
package org.apache.struts.action2.spi;
|
||||
@@ -11,21 +11,21 @@ import java.util.concurrent.Callable;
|
||||
public class ThreadLocalRequestTest extends TestCase {
|
||||
|
||||
public void testSetAndCall() throws Exception {
|
||||
final Request r1 = createMock(Request.class);
|
||||
final Request r2 = createMock(Request.class);
|
||||
final RequestContext r1 = createMock(RequestContext.class);
|
||||
final RequestContext r2 = createMock(RequestContext.class);
|
||||
|
||||
ensureNotSet();
|
||||
|
||||
String result = ThreadLocalRequest.setAndCall(r1, new Callable<String>() {
|
||||
String result = ThreadLocalRequestContext.setAndCall(r1, new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
assertSame(r1, ThreadLocalRequest.get());
|
||||
String result = ThreadLocalRequest.setAndCall(r2, new Callable<String>() {
|
||||
assertSame(r1, ThreadLocalRequestContext.get());
|
||||
String result = ThreadLocalRequestContext.setAndCall(r2, new Callable<String>() {
|
||||
public String call() throws Exception {
|
||||
assertSame(r2, ThreadLocalRequest.get());
|
||||
assertSame(r2, ThreadLocalRequestContext.get());
|
||||
return "foo";
|
||||
}
|
||||
});
|
||||
assertSame(r1, ThreadLocalRequest.get());
|
||||
assertSame(r1, ThreadLocalRequestContext.get());
|
||||
return result;
|
||||
}
|
||||
});
|
||||
@@ -37,7 +37,7 @@ public class ThreadLocalRequestTest extends TestCase {
|
||||
|
||||
private void ensureNotSet() {
|
||||
try {
|
||||
ThreadLocalRequest.get();
|
||||
ThreadLocalRequestContext.get();
|
||||
fail();
|
||||
}
|
||||
catch (IllegalStateException e) { /* ignore */ }
|
||||
|
||||
Reference in New Issue
Block a user