You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mr...@apache.org on 2007/10/21 10:17:32 UTC

svn commit: r586868 - in /struts/sandbox/trunk/struts2-rest-plugin: showcase/src/main/java/org/apache/struts2/rest/example/ src/main/java/org/apache/struts2/rest/ src/main/resources/

Author: mrdon
Date: Sun Oct 21 01:17:30 2007
New Revision: 586868

URL: http://svn.apache.org/viewvc?rev=586868&view=rev
Log:
Adding automatic validation support

Added:
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java
      - copied, changed from r586735, struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerSelector.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java
Removed:
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerSelector.java
Modified:
    struts/sandbox/trunk/struts2-rest-plugin/showcase/src/main/java/org/apache/struts2/rest/example/OrderResource.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/DefaultRestInfo.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ResourceClasspathPackageProvider.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestActionInvocation.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestInfo.java
    struts/sandbox/trunk/struts2-rest-plugin/src/main/resources/struts-plugin.xml

Modified: struts/sandbox/trunk/struts2-rest-plugin/showcase/src/main/java/org/apache/struts2/rest/example/OrderResource.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/showcase/src/main/java/org/apache/struts2/rest/example/OrderResource.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/showcase/src/main/java/org/apache/struts2/rest/example/OrderResource.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/showcase/src/main/java/org/apache/struts2/rest/example/OrderResource.java Sun Oct 21 01:17:30 2007
@@ -11,8 +11,10 @@
 import org.apache.struts2.rest.RestInfo;
 
 import com.opensymphony.xwork2.ModelDriven;
+import com.opensymphony.xwork2.Validateable;
+import com.opensymphony.xwork2.ValidationAwareSupport;
 
-public class OrderResource implements ModelDriven<Object>, ParameterAware{
+public class OrderResource extends ValidationAwareSupport implements ModelDriven<Object>, ParameterAware, Validateable{
     
     private Order model = new Order();
     private static Map<String,Order> orders = new HashMap<String,Order>() {{
@@ -21,6 +23,12 @@
         put("5", new Order("5", "Jim", 66));
     }};
     private Collection<Order> list;
+    
+    public void validate() {
+        if (model.getId() == null || model.getId().length() ==0) {
+            addFieldError("id", "ID is wrong");
+        }
+    }
     
     public String show() {
         return "show";

Copied: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java (from r586735, struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerSelector.java)
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java?p2=struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java&p1=struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerSelector.java&r1=586735&r2=586868&rev=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerSelector.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java Sun Oct 21 01:17:30 2007
@@ -1,17 +1,43 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 
+import org.apache.struts2.ServletActionContext;
 import org.apache.struts2.rest.handler.ContentTypeHandler;
 
+import com.opensymphony.xwork2.ModelDriven;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.inject.Container;
 import com.opensymphony.xwork2.inject.Inject;
 
-public class ContentTypeHandlerSelector {
+public class ContentTypeHandlerManager {
 
     private Map<String,ContentTypeHandler> handlers = new HashMap<String,ContentTypeHandler>();
     private String defaultHandlerName;
@@ -36,6 +62,39 @@
             extension = defaultHandlerName;
         }
         return handlers.get(extension);
+    }
+    
+    public String handleResult(ActionConfig actionConfig, Object methodResult, Object target)
+            throws IOException {
+        String resultCode = null;
+        HttpServletRequest req = ServletActionContext.getRequest();
+        HttpServletResponse res = ServletActionContext.getResponse();
+        if (target instanceof ModelDriven) {
+            target = ((ModelDriven)target).getModel();
+        }
+        
+        if (methodResult instanceof RestInfo) {
+            RestInfo info = (RestInfo) methodResult;
+            resultCode = info.apply(req, res, target);
+        } else {
+            resultCode = (String) methodResult;
+        }
+        ContentTypeHandler handler = getHandlerForRequest(req);
+        String extCode = resultCode+"-"+handler.getExtension();
+        if (actionConfig.getResults().get(extCode) != null) {
+            resultCode = extCode;
+        } else {
+            ByteArrayOutputStream bout = new ByteArrayOutputStream();
+            
+            resultCode = handler.fromObject(target, resultCode, bout);
+            if (bout.size() > 0) {
+                res.setContentLength(bout.size());
+                res.setContentType(handler.getContentType());
+                res.getOutputStream().write(bout.toByteArray());
+                res.getOutputStream().close();
+            }
+        }
+        return resultCode;
     }
     
     protected String findExtension(String url) {

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ContentTypeInterceptor.java Sun Oct 21 01:17:30 2007
@@ -1,3 +1,23 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
 
 import javax.servlet.http.HttpServletRequest;
@@ -12,10 +32,10 @@
 
 public class ContentTypeInterceptor implements Interceptor {
 
-    ContentTypeHandlerSelector selector;
+    ContentTypeHandlerManager selector;
     
     @Inject
-    public void setContentTypeHandlerSelector(ContentTypeHandlerSelector sel) {
+    public void setContentTypeHandlerSelector(ContentTypeHandlerManager sel) {
         this.selector = sel;
     }
     

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/DefaultRestInfo.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/DefaultRestInfo.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/DefaultRestInfo.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/DefaultRestInfo.java Sun Oct 21 01:17:30 2007
@@ -1,3 +1,23 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
 
 import static javax.servlet.http.HttpServletResponse.*;

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ResourceClasspathPackageProvider.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ResourceClasspathPackageProvider.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ResourceClasspathPackageProvider.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/ResourceClasspathPackageProvider.java Sun Oct 21 01:17:30 2007
@@ -1,3 +1,23 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
 
 import org.apache.struts2.config.ClasspathPackageProvider;

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestActionInvocation.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestActionInvocation.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestActionInvocation.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestActionInvocation.java Sun Oct 21 01:17:30 2007
@@ -81,14 +81,14 @@
 
     private static final Logger LOG = LoggerFactory.getLogger(RestActionInvocation.class);
     
-    private ContentTypeHandlerSelector handlerSelector;
+    private ContentTypeHandlerManager handlerSelector;
 
     protected RestActionInvocation(Map extraContext, boolean pushAction) throws Exception {
         super(extraContext, pushAction);
     }
 
     @Inject
-    public void setMimeTypeHandlerSelector(ContentTypeHandlerSelector sel) {
+    public void setMimeTypeHandlerSelector(ContentTypeHandlerManager sel) {
         this.handlerSelector = sel;
     }
     
@@ -161,36 +161,9 @@
             this.explicitResult = (Result) methodResult;
             return null;
         } else if (methodResult != null) {
-            HttpServletRequest req = ServletActionContext.getRequest();
-            HttpServletResponse res = ServletActionContext.getResponse();
-            ContentTypeHandler handler = handlerSelector.getHandlerForRequest(req);
-            Object target = action;
-            if (target instanceof ModelDriven) {
-                target = ((ModelDriven)target).getModel();
-            }
-            
-            if (methodResult instanceof RestInfo) {
-                RestInfo info = (RestInfo) methodResult;
-                resultCode = info.apply(req, res, target);
-            } else {
-                resultCode = (String) methodResult;
-            }
-            
-            String extCode = resultCode+"-"+handler.getExtension();
-            if (actionConfig.getResults().get(extCode) != null) {
-                resultCode = extCode;
-            } else {
-                ByteArrayOutputStream bout = new ByteArrayOutputStream();
-                
-                resultCode = handler.fromObject(target, resultCode, bout);
-                if (bout.size() > 0) {
-                    res.setContentLength(bout.size());
-                    res.setContentType(handler.getContentType());
-                    res.getOutputStream().write(bout.toByteArray());
-                    res.getOutputStream().close();
-                }
-            }
+            resultCode = handlerSelector.handleResult(actionConfig, methodResult, action);
         }
         return resultCode;
     }
+
 }

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestInfo.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestInfo.java?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestInfo.java (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestInfo.java Sun Oct 21 01:17:30 2007
@@ -1,3 +1,23 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
 
 import javax.servlet.http.HttpServletRequest;

Added: struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java?rev=586868&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java (added)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java Sun Oct 21 01:17:30 2007
@@ -0,0 +1,182 @@
+/*
+ * $Id: Restful2ActionMapper.java 540819 2007-05-23 02:48:36Z mrdon $
+ *
+ * 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.struts2.rest;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.ValidationAware;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+
+import static javax.servlet.http.HttpServletResponse.*;
+
+/**
+ * <!-- START SNIPPET: description -->
+ *
+ * An interceptor that makes sure there are not validation errors before allowing the interceptor chain to continue.
+ * <b>This interceptor does not perform any validation</b>.
+ *
+ * <p/>This interceptor does nothing if the name of the method being invoked is specified in the <b>excludeMethods</b>
+ * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to
+ * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the
+ * <b>excludeMethods</b> parameter to "input, back".
+ *
+ * <b>Note:</b> As this method extends off MethodFilterInterceptor, it is capable of
+ * deciding if it is applicable only to selective methods in the action class. This is done by adding param tags
+ * for the interceptor element, naming either a list of excluded method names and/or a list of included method
+ * names, whereby includeMethods overrides excludedMethods. A single * sign is interpreted as wildcard matching
+ * all methods for both parameters.
+ * See {@link MethodFilterInterceptor} for more info.
+ *
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Interceptor parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ *
+ * <ul>
+ *
+ * <li>inputResultName - Default to "input". Determine the result name to be returned when
+ * an action / field error is found.</li>
+ *
+ * </ul>
+ *
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Extending the interceptor:</u>
+ *
+ * <p/>
+ *
+ * <!-- START SNIPPET: extending -->
+ *
+ * There are no known extension points for this interceptor.
+ *
+ * <!-- END SNIPPET: extending -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * 
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="params"/&gt;
+ *     &lt;interceptor-ref name="validation"/&gt;
+ *     &lt;interceptor-ref name="workflow"/&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ * 
+ * &lt;-- In this case myMethod as well as mySecondMethod of the action class
+ *        will not pass through the workflow process --&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="params"/&gt;
+ *     &lt;interceptor-ref name="validation"/&gt;
+ *     &lt;interceptor-ref name="workflow"&gt;
+ *         &lt;param name="excludeMethods"&gt;myMethod,mySecondMethod&lt;/param&gt;
+ *     &lt;/interceptor-ref name="workflow"&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ *
+ * &lt;-- In this case, the result named "error" will be used when
+ *        an action / field error is found --&gt;
+ * &lt;-- The Interceptor will only be applied for myWorkflowMethod method of action
+ *        classes, since this is the only included method while any others are excluded --&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="params"/&gt;
+ *     &lt;interceptor-ref name="validation"/&gt;
+ *     &lt;interceptor-ref name="workflow"&gt;
+ *        &lt;param name="inputResultName"&gt;error&lt;/param&gt;
+*         &lt;param name="excludeMethods"&gt;*&lt;/param&gt;
+*         &lt;param name="includeMethods"&gt;myWorkflowMethod&lt;/param&gt;
+ *     &lt;/interceptor-ref&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ *
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ * @author Rainer Hermanns
+ * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
+ * @author Philip Luppens
+ * @author tm_jee
+ */
+public class RestWorkflowInterceptor extends MethodFilterInterceptor {
+	
+	private static final long serialVersionUID = 7563014655616490865L;
+
+	private static final Logger LOG = LoggerFactory.getLogger(RestWorkflowInterceptor.class);
+	
+	private String inputResultName = Action.INPUT;
+	
+	private ContentTypeHandlerManager manager;
+	
+	@Inject
+	public void setContentTypeHandlerManager(ContentTypeHandlerManager mgr) {
+	    this.manager = mgr;
+	}
+	
+	/**
+	 * Set the <code>inputResultName</code> (result name to be returned when 
+	 * a action / field error is found registered). Default to {@link Action#INPUT}
+	 * 
+	 * @param inputResultName what result name to use when there was validation error(s).
+	 */
+	public void setInputResultName(String inputResultName) {
+		this.inputResultName = inputResultName;
+	}
+	
+	/**
+	 * Intercept {@link ActionInvocation} and returns a <code>inputResultName</code>
+	 * when action / field errors is found registered.
+	 * 
+	 * @return String result name
+	 */
+    protected String doIntercept(ActionInvocation invocation) throws Exception {
+        Object action = invocation.getAction();
+        
+        if (action instanceof ValidationAware) {
+            ValidationAware validationAwareAction = (ValidationAware) action;
+
+            if (validationAwareAction.hasErrors()) {
+            	if (LOG.isDebugEnabled()) {
+            		LOG.debug("Errors on action "+validationAwareAction+", returning result name 'input'");
+            	}
+            	RestInfo info = new DefaultRestInfo()
+            	    .disableCaching()
+            	    .renderResult(inputResultName)
+            	    .withStatus(SC_BAD_REQUEST);
+            	
+            	Map errors = new HashMap();
+            	errors.put("actionErrors", validationAwareAction.getActionErrors());
+            	errors.put("fieldErrors", validationAwareAction.getFieldErrors());
+            	return manager.handleResult(invocation.getProxy().getConfig(), info, errors);
+            }
+        }
+
+        return invocation.invoke();
+    }
+
+}

Modified: struts/sandbox/trunk/struts2-rest-plugin/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-rest-plugin/src/main/resources/struts-plugin.xml?rev=586868&r1=586867&r2=586868&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-rest-plugin/src/main/resources/struts-plugin.xml (original)
+++ struts/sandbox/trunk/struts2-rest-plugin/src/main/resources/struts-plugin.xml Sun Oct 21 01:17:30 2007
@@ -11,7 +11,7 @@
 	
 	<bean type="com.opensymphony.xwork2.config.PackageProvider" name="rest" class="org.apache.struts2.rest.ResourceClasspathPackageProvider" />
 
-	<bean class="org.apache.struts2.rest.ContentTypeHandlerSelector" />
+	<bean class="org.apache.struts2.rest.ContentTypeHandlerManager" />
 
     <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="xml" class="org.apache.struts2.rest.handler.XStreamHandler" />
     <bean type="org.apache.struts2.rest.handler.ContentTypeHandler" name="json" class="org.apache.struts2.rest.handler.XStreamJsonHandler" />
@@ -27,6 +27,7 @@
     <package name="rest-default" extends="struts-default">
         <interceptors>
             <interceptor name="rest" class="org.apache.struts2.rest.ContentTypeInterceptor"/>
+            <interceptor name="restWorkflow" class="org.apache.struts2.rest.RestWorkflowInterceptor"/>
 
             <!-- A complete stack with all the common interceptors in place.
                  Generally, this stack should be the one you use, though it
@@ -59,10 +60,10 @@
                 <interceptor-ref name="rest" />
                 <interceptor-ref name="conversionError"/>
                 <interceptor-ref name="validation">
-                    <param name="excludeMethods">input,back,cancel,browse</param>
+                    <param name="excludeMethods">input,back,cancel,browse,index,show</param>
                 </interceptor-ref>
-                <interceptor-ref name="workflow">
-                    <param name="excludeMethods">input,back,cancel,browse</param>
+                <interceptor-ref name="restWorkflow">
+                    <param name="excludeMethods">input,back,cancel,browse,index,show</param>
                 </interceptor-ref>
             </interceptor-stack>