Author: plightbo Date: Wed May 3 15:22:02 2006 New Revision: 399458 URL: http://svn.apache.org/viewcvs?rev=399458&view=rev Log: bob's API work, milestone 1
Added: incubator/webwork2/action-api/src/main/java/org/ incubator/webwork2/action-api/src/main/java/org/apache/ incubator/webwork2/action-api/src/main/java/org/apache/struts/ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Action.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ErrorAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/MessageAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Messages.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ResultNames.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Validatable.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/AbstractAttribute.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ApplicationAttribute.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/Attribute.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/RequestAttribute.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/SessionAttribute.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/UnitOfWork.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/package-info.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/package-info.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ParameterAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletRequestAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletResponseAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/package-info.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Interceptor.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Request.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/RequestAware.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Result.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ThreadLocalRequest.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ValueStack.java incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/package-info.java incubator/webwork2/action-api/src/test/java/org/ incubator/webwork2/action-api/src/test/java/org/apache/ incubator/webwork2/action-api/src/test/java/org/apache/struts/ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/AttributeTest.java incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ReferenceTest.java incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ThreadLocalRequestTest.java Modified: incubator/webwork2/action-api/pom.xml Modified: incubator/webwork2/action-api/pom.xml URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/pom.xml?rev=399458&r1=399457&r2=399458&view=diff ============================================================================== --- incubator/webwork2/action-api/pom.xml (original) +++ incubator/webwork2/action-api/pom.xml Wed May 3 15:22:02 2006 @@ -12,6 +12,34 @@ <packaging>jar</packaging> <name>Struts Action Framework 2.0 API</name> <dependencies> - + <dependency> + <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> + <optional>true</optional> + </dependency> + <dependency> + <groupId>easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + <version>2.0</version> + </dependency> </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <showPackage>false</showPackage> + </configuration> + </plugin> + </plugins> + </build> </project> Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Action.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Action.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Action.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Action.java Wed May 3 15:22:02 2006 @@ -0,0 +1,45 @@ +package org.apache.struts.action2; + +/** + * Default action interface. Provided purely for user convenience. Struts does not require actions to implement any + * interfaces. Actions need only implement a public, no argument method which returns [EMAIL PROTECTED] String}. If a user does + * not specify a method name, Struts defaults to [EMAIL PROTECTED] execute()}. + * + * <p>For example: + * + * <pre> + * static import ResultNames.*; + * + * public class MyAction <b>implements Action</b> { + * + * public String execute() { + * return SUCCESS; + * } + * } + * </pre> + * + * <p>is equivalent to: + * + * <pre> + * static import ResultNames.*; + * + * public class MyAction { + * + * public String execute() { + * return SUCCESS; + * } + * } + * </pre> + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface Action { + + /** + * Executes this action. + * + * @return result name which matches a result name from the action mapping in the configuration file. See [EMAIL PROTECTED] + * ResultNames} for common suggestions. + */ + String execute(); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ErrorAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ErrorAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ErrorAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ErrorAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,45 @@ +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 [EMAIL PROTECTED] (Bob Lee) + */ +public interface ErrorAware { + + /** + * Sets error messages. + * + * @param errors error messages + */ + void setErrors(Messages errors); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/MessageAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/MessageAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/MessageAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/MessageAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,35 @@ +package org.apache.struts.action2; + +/** + * Implemented by actions that may need to record messages. + * + * <pre> + * static import ResultNames.*; + * + * public class Welcome implements MessageAware { + * + * Messages messages; + * + * public String execute() { + * messages.add("welcome"); + * return SUCCESS; + * } + * + * public void setMessages(Messages messages) { + * this.messages = messages; + * } + * } + * </pre> + * + * @see ErrorAware + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface MessageAware { + + /** + * Sets messages. + * + * @param messages messages + */ + void setMessages(Messages messages); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Messages.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Messages.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Messages.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Messages.java Wed May 3 15:22:02 2006 @@ -0,0 +1,72 @@ +package org.apache.struts.action2; + +import java.util.List; +import java.util.Set; + +/** + * 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. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface Messages { + + /** + * Adds request-scoped message. + * + * @param key message key + */ + void add(String key); + + /** + * Adds request-scoped message. + * + * @param key message key + * @param arguments message arguments + */ + void add(String key, Object... arguments); + + /** + * Adds field-scoped message. + * + * @param fieldName name of field to attach message to + * @param key message key + */ + void add(String fieldName, String key); + + /** + * Adds field-scoped message. + * + * @param fieldName name of field to attach message to + * @param key message key + * @param arguments message arguments + */ + void add(String fieldName, String key, Object... arguments); + + /** + * Gets request-scoped messages. + * + * @return unmodifiable list of messages for this request. + */ + List<String> forRequest(); + + /** + * Gets field-scoped messages. + * + * @param fieldName field name + * @return unmodifiable list of messages for the given field name. + */ + List<String> forField(String fieldName); + + /** + * Gets names of fields which have messages attached. + * + * @return unmodifiable set of field names with messages attached. + */ + Set<String> getFieldNames(); + + /** + * Returns true if no request or field-scoped messages have been added. + */ + boolean isEmpty(); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ResultNames.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ResultNames.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ResultNames.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/ResultNames.java Wed May 3 15:22:02 2006 @@ -0,0 +1,36 @@ +package org.apache.struts.action2; + +/** + * Commonly used result names returned by action methods. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public final class ResultNames { + + private ResultNames() {} + + /** + * The action executed successfully. + */ + public static final String SUCCESS = "success"; + + /** + * The action requires more input, i.e. a validation error occurred. + */ + public static final String INPUT = "input"; + + /** + * The action requires the user to log in before executing. + */ + public static final String LOGIN = "login"; + + /** + * The action execution failed irrecoverably. + */ + public static final String ERROR = "error"; + + /** + * The action executed successfully, but do not execute a result. + */ + public static final String NONE = "none"; +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Validatable.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Validatable.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Validatable.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/Validatable.java Wed May 3 15:22:02 2006 @@ -0,0 +1,16 @@ +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 [EMAIL PROTECTED] (Bob Lee) + */ +public interface Validatable { + + /** + * Validates input. Executes before action method. + */ + public void validate(); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/AbstractAttribute.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/AbstractAttribute.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/AbstractAttribute.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/AbstractAttribute.java Wed May 3 15:22:02 2006 @@ -0,0 +1,67 @@ +package org.apache.struts.action2.attribute; + +import java.util.Map; + +/** + * Support for [EMAIL PROTECTED] Attribute} implementations. + * + * <p>This class isn't public because we may want to optimize the implementation later. The current approach maximizes + * code reuse and only performs one thread local lookup per method invocation, but it also creates an object per + * invocation. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +abstract class AbstractAttribute<T> implements Attribute<T> { + + String name; + + AbstractAttribute(String name) { + if (name == null) { + throw new NullPointerException("Null name."); + } + this.name = name; + } + + public T get() { + return execute(new UnitOfWork<T>() { + public T execute(Map<String, Object> map) { + T t = (T) map.get(name); + if (t == null) { + t = initialValue(); + if (t != null) { + map.put(name, t); + } + } + return t; + } + }); + } + + public T set(final T t) { + return execute(new UnitOfWork<T>() { + public T execute(Map<String, Object> map) { + return (T) map.put(name, t); + } + }); + } + + public T remove() { + return execute(new UnitOfWork<T>() { + public T execute(Map<String, Object> map) { + return (T) map.remove(name); + } + }); + } + + abstract T execute(UnitOfWork<T> unitOfWork); + + /** + * Called by [EMAIL PROTECTED] #get()} to initialize the attribute value when it is [EMAIL PROTECTED] null}. The default implementation + * returns [EMAIL PROTECTED] null}. + * + * @return initial attribute value + */ + protected T initialValue() { + return null; + } +} \ No newline at end of file Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ApplicationAttribute.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ApplicationAttribute.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ApplicationAttribute.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/ApplicationAttribute.java Wed May 3 15:22:02 2006 @@ -0,0 +1,28 @@ +package org.apache.struts.action2.attribute; + +import org.apache.struts.action2.spi.Request; +import org.apache.struts.action2.spi.ThreadLocalRequest; + +/** + * A servlet context attribute. Synchronizes on the underlying [EMAIL PROTECTED] ServletContext} instance. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class ApplicationAttribute<T> extends AbstractAttribute<T> { + + /** + * Creates a new attribute. + * + * @param name attribute name + */ + public ApplicationAttribute(String name) { + super(name); + } + + T execute(UnitOfWork<T> unitOfWork) { + Request request = ThreadLocalRequest.get(); + synchronized (request.getServletContext()) { + return unitOfWork.execute(request.getApplicationMap()); + } + } +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/Attribute.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/Attribute.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/Attribute.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/Attribute.java Wed May 3 15:22:02 2006 @@ -0,0 +1,50 @@ +package org.apache.struts.action2.attribute; + +/** + * A key/value entry from a given scope. Provides better type safety and requires less code than accessing the + * [EMAIL PROTECTED] Map} view of a scope directly. For example: + * + * <pre> + * Attribute<Foo> fooAttribute = new SessionAttribute<Foo>("foo") { + * protected Foo initialValue() { + * return new Foo(); + * } + * }; + * + * public String execute() { + * // get Foo instance from current session. + * Foo foo = fooAttribute.get(); + * + * foo.doSomething(); + * return SUCCESS; + * } + * </pre> + * + * <p>All operations are atomic. Implementations synchronize on underlying objects from the servlet API. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface Attribute<T> { + + /** + * Gets attribute value. + * + * @return value + */ + T get(); + + /** + * Sets attribute value. + * + * @param t value + * @return previous value + */ + T set(T t); + + /** + * Removes attribute. + * + * @return previous value + */ + T remove(); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/RequestAttribute.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/RequestAttribute.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/RequestAttribute.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/RequestAttribute.java Wed May 3 15:22:02 2006 @@ -0,0 +1,28 @@ +package org.apache.struts.action2.attribute; + +import org.apache.struts.action2.spi.Request; +import org.apache.struts.action2.spi.ThreadLocalRequest; + +/** + * A request attribute. Synchronizes on the underlying [EMAIL PROTECTED] HttpServletRequest} instance. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class RequestAttribute<T> extends AbstractAttribute<T> { + + /** + * Creates a new attribute. + * + * @param name attribute name + */ + RequestAttribute(String name) { + super(name); + } + + T execute(UnitOfWork<T> unitOfWork) { + Request request = ThreadLocalRequest.get(); + synchronized (request.getServletRequest()) { + return unitOfWork.execute(request.getAttributeMap()); + } + } +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/SessionAttribute.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/SessionAttribute.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/SessionAttribute.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/SessionAttribute.java Wed May 3 15:22:02 2006 @@ -0,0 +1,28 @@ +package org.apache.struts.action2.attribute; + +import org.apache.struts.action2.spi.Request; +import org.apache.struts.action2.spi.ThreadLocalRequest; + +/** + * A session attribute. Synchronizes on the underlying [EMAIL PROTECTED] HttpSession}. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class SessionAttribute<T> extends AbstractAttribute<T> { + + /** + * Creates a new attribute. + * + * @param name attribute name + */ + public SessionAttribute(String name) { + super(name); + } + + T execute(UnitOfWork<T> unitOfWork) { + Request request = ThreadLocalRequest.get(); + synchronized (request.getServletRequest().getSession()) { + return unitOfWork.execute(request.getSessionMap()); + } + } +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/UnitOfWork.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/UnitOfWork.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/UnitOfWork.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/UnitOfWork.java Wed May 3 15:22:02 2006 @@ -0,0 +1,13 @@ +package org.apache.struts.action2.attribute; + +import java.util.Map; + +/** + * Unit of work which should be executed atomically. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +interface UnitOfWork<T> { + + T execute(Map<String, Object> map); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/package-info.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/package-info.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/package-info.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/attribute/package-info.java Wed May 3 15:22:02 2006 @@ -0,0 +1,4 @@ +/** + * @see Attribute + */ +package org.apache.struts.action2.attribute; \ No newline at end of file Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/package-info.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/package-info.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/package-info.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/package-info.java Wed May 3 15:22:02 2006 @@ -0,0 +1,4 @@ +/** + * Struts Action 2.0 user API. + */ +package org.apache.struts.action2; \ No newline at end of file Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ParameterAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ParameterAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ParameterAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ParameterAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,18 @@ +package org.apache.struts.action2.servlet; + +import java.util.Map; + +/** + * Implemented by actions which need direct access to the request parameters. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface ParameterAware { + + /** + * Sets parameters. + * + * @param parameters map of parameter name to parameter values + */ + void setParameters(Map<String, String[]> parameters); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletRequestAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletRequestAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletRequestAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletRequestAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,18 @@ +package org.apache.struts.action2.servlet; + +import javax.servlet.http.HttpServletRequest; + +/** + * Implemented by actions which need direct access to the servlet request. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface ServletRequestAware { + + /** + * Sets the servlet request. + * + * @param request servlet request. + */ + void setServletRequest(HttpServletRequest request); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletResponseAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletResponseAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletResponseAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/ServletResponseAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,18 @@ +package org.apache.struts.action2.servlet; + +import javax.servlet.http.HttpServletResponse; + +/** + * Implemented by actions which need direct access to the servlet response. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface ServletResponseAware { + + /** + * Sets the servlet response. + * + * @param response servlet response + */ + void setServletResponse(HttpServletResponse response); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/package-info.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/package-info.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/package-info.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/servlet/package-info.java Wed May 3 15:22:02 2006 @@ -0,0 +1,4 @@ +/** + * Interfaces for actions which need direct access to the underlying servlet API. Use judiciously. + */ +package org.apache.struts.action2.servlet; \ No newline at end of file Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Interceptor.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Interceptor.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Interceptor.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Interceptor.java Wed May 3 15:22:02 2006 @@ -0,0 +1,16 @@ +package org.apache.struts.action2.spi; + +/** + * Intercepts an action request. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface Interceptor { + + /** + * Intercepts an action request. + * + * @param request current request + */ + String intercept(Request request) throws Exception; +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Request.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Request.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Request.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Request.java Wed May 3 15:22:02 2006 @@ -0,0 +1,126 @@ +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 [EMAIL PROTECTED] (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 [EMAIL PROTECTED] Result} instance for the current action. + * + * @return [EMAIL PROTECTED] Result} instance or [EMAIL PROTECTED] 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; +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/RequestAware.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/RequestAware.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/RequestAware.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/RequestAware.java Wed May 3 15:22:02 2006 @@ -0,0 +1,16 @@ +package org.apache.struts.action2.spi; + +/** + * Implemented by actions that need access to the current [EMAIL PROTECTED] Request}. Use judiciously. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface RequestAware { + + /** + * Sets [EMAIL PROTECTED] Request}. + * + * @param request + */ + void setRequest(Request request); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Result.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Result.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Result.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/Result.java Wed May 3 15:22:02 2006 @@ -0,0 +1,16 @@ +package org.apache.struts.action2.spi; + +/** + * The result of an action request. Struts creates a new [EMAIL PROTECTED] Result} instance for each request. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface Result { + + /** + * Executes result. + * + * @param request + */ + void execute(Request request) throws Exception; +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ThreadLocalRequest.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ThreadLocalRequest.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ThreadLocalRequest.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ThreadLocalRequest.java Wed May 3 15:22:02 2006 @@ -0,0 +1,54 @@ +package org.apache.struts.action2.spi; + +import java.util.concurrent.Callable; + +/** + * Provides a reference to the current [EMAIL PROTECTED] 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 [EMAIL PROTECTED] (Bob Lee) + */ +public final class ThreadLocalRequest { + + static ThreadLocal<Request> threadLocalRequest = new ThreadLocal<Request>(); + + private ThreadLocalRequest() {} + + /** + * Sets [EMAIL PROTECTED] Request} for the current thread and invokes the provided [EMAIL PROTECTED] Callable}. Restores previous [EMAIL PROTECTED] + * Request} (if any) when finished. + * + * @param request for current thread + * @param callable + * @return result of [EMAIL PROTECTED] callable} + * @throws Exception from [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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; + } +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ValueStack.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ValueStack.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ValueStack.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/ValueStack.java Wed May 3 15:22:02 2006 @@ -0,0 +1,93 @@ +package org.apache.struts.action2.spi; + +/** + * A central fixture of the Struts Action framework, the [EMAIL PROTECTED] ValueStack} is a stack which contains the actions + * which have executed in addition to other objects. Users can get and set values on the stack using expressions. The + * [EMAIL PROTECTED] ValueStack} will search down the stack starting with the most recent objects until it finds an object to + * which the expression can apply. + * + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public interface ValueStack extends Iterable<Object> { + + /** + * Gets the top, most recent object from the stack without changing the stack. + * + * @return the top object + */ + Object peek(); + + /** + * Removes the top, most recent object from the stack. + * + * @return the top object + */ + Object pop(); + + /** + * Pushes an object onto the stack. + * + * @param o + */ + void push(Object o); + + /** + * Creates a shallow copy of this stack. + * + * @return a new stack which contains the same objects as this one + */ + ValueStack clone(); + + /** + * Queries the stack. Starts with the top, most recent object. If the expression can apply to the object, this + * method returns the result of evaluating the expression. If the expression does not apply, this method moves + * down the stack to the next object and repeats. Returns [EMAIL PROTECTED] null} if the expression doesn't apply to any + * objects. + * + * @param expression + * @return the evaluation of the expression against the first applicable object in the stack + */ + Object get(String expression); + + /** + * Queries the stack and converts the result to the specified type. Starts with the top, most recent object. If + * the expression can apply to the object, this method returns the result of evaluating the expression converted + * to the specified type. If the expression does not apply, this method moves down the stack to the next object + * and repeats. Returns [EMAIL PROTECTED] null} if the expression doesn't apply to any objects. + * + * @param expression + * @param asType the type to convert the result to + * @return the evaluation of the expression against the first applicable object in the stack converted to the + * specified type + */ + <T> T get(String expression, Class<T> asType); + + /** + * Queries the stack and converts the result to a [EMAIL PROTECTED] String}. Starts with the top, most recent object. If the + * expression can apply to the object, this method returns the result of evaluating the expression converted to a + * [EMAIL PROTECTED] String}. If the expression does not apply, this method moves down the stack to the next object and + * repeats. Returns [EMAIL PROTECTED] null} if the expression doesn't apply to any objects. + * + * @param expression + * @return the evaluation of the expression against the first applicable object in the stack converted to a [EMAIL PROTECTED] + * String} + */ + String getString(String expression); + + /** + * Sets a value on an object from the stack. This method starts at the top, most recent object. If the expression + * applies to that object, this methods sets the given value on that object using the expression and converting + * the type as necessary. If the expression does not apply, this method moves to the next object and repeats. + * + * @param expression + * @param value + */ + void set(String expression, Object value); + + /** + * Returns the number of object on the stack. + * + * @return size of stack + */ + int size(); +} Added: incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/package-info.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/package-info.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/package-info.java (added) +++ incubator/webwork2/action-api/src/main/java/org/apache/struts/action2/spi/package-info.java Wed May 3 15:22:02 2006 @@ -0,0 +1,4 @@ +/** + * Struts Action 2.0 service provider API. + */ +package org.apache.struts.action2.spi; \ No newline at end of file Added: incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/AttributeTest.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/AttributeTest.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/AttributeTest.java (added) +++ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/AttributeTest.java Wed May 3 15:22:02 2006 @@ -0,0 +1,61 @@ +// Copyright 2006 Google Inc. All Rights Reserved. + +package org.apache.struts.action2.attribute; + +import junit.framework.TestCase; + +import java.util.Map; +import java.util.HashMap; + +/** + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class AttributeTest extends TestCase { + + public void testSetGetRemove() { + Map<String, Object> m = new HashMap<String, Object>(); + Attribute<String> a = new AttributeTest.MockAttribute<String>(m, "key"); + + assertNull(a.get()); + assertTrue(m.isEmpty()); + a.set("foo"); + assertEquals("foo", a.get()); + assertFalse(m.isEmpty()); + a.remove(); + assertNull(a.get()); + assertTrue(m.isEmpty()); + } + + public void testInitialValue() { + Map<String, Object> m = new HashMap<String, Object>(); + Attribute<String> a = new AttributeTest.MockAttribute<String>(m, "key") { + protected String initialValue() { + return "foo"; + } + }; + + getAndRemove(a, m); + getAndRemove(a, m); + } + + void getAndRemove(Attribute<String> a, Map<String, Object> m) { + assertEquals("foo", a.get()); + assertFalse(m.isEmpty()); + a.remove(); + assertTrue(m.isEmpty()); + } + + static class MockAttribute<T> extends AbstractAttribute<T> { + + Map<String, Object> map; + + MockAttribute(Map<String, Object> map, String name) { + super(name); + this.map = map; + } + + T execute(UnitOfWork<T> unitOfWork) { + return unitOfWork.execute(map); + } + } +} Added: incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ReferenceTest.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ReferenceTest.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ReferenceTest.java (added) +++ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/attribute/ReferenceTest.java Wed May 3 15:22:02 2006 @@ -0,0 +1,59 @@ +package org.apache.struts.action2.attribute; + +import junit.framework.TestCase; + +import java.util.Map; +import java.util.HashMap; + +/** + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class ReferenceTest extends TestCase { + + public void testSetGetRemove() { + Map<String, Object> m = new HashMap<String, Object>(); + Attribute<String> a = new MockAttribute<String>(m, "key"); + + assertNull(a.get()); + assertTrue(m.isEmpty()); + a.set("foo"); + assertEquals("foo", a.get()); + assertFalse(m.isEmpty()); + a.remove(); + assertNull(a.get()); + assertTrue(m.isEmpty()); + } + + public void testInitialValue() { + Map<String, Object> m = new HashMap<String, Object>(); + Attribute<String> a = new MockAttribute<String>(m, "key") { + protected String initialValue() { + return "foo"; + } + }; + + getAndRemove(a, m); + getAndRemove(a, m); + } + + void getAndRemove(Attribute<String> a, Map<String, Object> m) { + assertEquals("foo", a.get()); + assertFalse(m.isEmpty()); + a.remove(); + assertTrue(m.isEmpty()); + } + + static class MockAttribute<T> extends AbstractAttribute<T> { + + Map<String, Object> map; + + MockAttribute(Map<String, Object> map, String key) { + super(key); + this.map = map; + } + + T execute(UnitOfWork<T> unitOfWork) { + return unitOfWork.execute(map); + } + } +} Added: incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ThreadLocalRequestTest.java URL: http://svn.apache.org/viewcvs/incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ThreadLocalRequestTest.java?rev=399458&view=auto ============================================================================== --- incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ThreadLocalRequestTest.java (added) +++ incubator/webwork2/action-api/src/test/java/org/apache/struts/action2/spi/ThreadLocalRequestTest.java Wed May 3 15:22:02 2006 @@ -0,0 +1,45 @@ +package org.apache.struts.action2.spi; + +import static org.easymock.EasyMock.*; +import junit.framework.TestCase; + +import java.util.concurrent.Callable; + +/** + * @author [EMAIL PROTECTED] (Bob Lee) + */ +public class ThreadLocalRequestTest extends TestCase { + + public void testSetAndCall() throws Exception { + final Request r1 = createMock(Request.class); + final Request r2 = createMock(Request.class); + + ensureNotSet(); + + String result = ThreadLocalRequest.setAndCall(r1, new Callable<String>() { + public String call() throws Exception { + assertSame(r1, ThreadLocalRequest.get()); + String result = ThreadLocalRequest.setAndCall(r2, new Callable<String>() { + public String call() throws Exception { + assertSame(r2, ThreadLocalRequest.get()); + return "foo"; + } + }); + assertSame(r1, ThreadLocalRequest.get()); + return result; + } + }); + + ensureNotSet(); + + assertEquals("foo", result); + } + + private void ensureNotSet() { + try { + ThreadLocalRequest.get(); + fail(); + } + catch (IllegalStateException e) { /* ignore */ } + } +}