Author: mrdon Date: Sat Jul 12 08:55:58 2008 New Revision: 676195 URL: http://svn.apache.org/viewvc?rev=676195&view=rev Log: Adding ability to customize validation failure status code, refactoring content type handler manager into interface and impl for easier testing WW-2358
Added: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java (contents, props changed) - copied, changed from r676177, struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java Modified: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java struts/struts2/trunk/plugins/rest/src/main/resources/struts-plugin.xml struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java Added: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java?rev=676195&view=auto ============================================================================== --- struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java (added) +++ struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java Sat Jul 12 08:55:58 2008 @@ -0,0 +1,64 @@ +/* + * $Id$ + * + * 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.rest.handler.ContentTypeHandler; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.opensymphony.xwork2.config.entities.ActionConfig; + +import java.io.IOException; + +/** + * Manages content type handlers + */ +public interface ContentTypeHandlerManager { + String STRUTS_REST_HANDLER_OVERRIDE_PREFIX = "struts.rest.handlerOverride."; + + /** + * Gets the handler for the request by looking at the request content type and extension + * @param req The request + * @return The appropriate handler + */ + ContentTypeHandler getHandlerForRequest(HttpServletRequest req); + + /** + * Gets the handler for the response by looking at the extension of the request + * @param req The request + * @return The appropriate handler + */ + ContentTypeHandler getHandlerForResponse(HttpServletRequest req, HttpServletResponse res); + + /** + * Handles the result using handlers to generate content type-specific content + * + * @param actionConfig The action config for the current request + * @param methodResult The object returned from the action method + * @param target The object to return, usually the action object + * @return The new result code to process + * @throws IOException If unable to write to the response + */ + String handleResult(ActionConfig actionConfig, Object methodResult, Object target) + throws IOException; +} Copied: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java (from r676177, struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java) URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java?p2=struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java&p1=struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java&r1=676177&r2=676195&rev=676195&view=diff ============================================================================== --- struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/ContentTypeHandlerManager.java (original) +++ struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java Sat Jul 12 08:55:58 2008 @@ -42,7 +42,7 @@ * Manages [EMAIL PROTECTED] ContentTypeHandler} instances and uses them to * process results */ -public class ContentTypeHandlerManager { +public class DefaultContentTypeHandlerManager implements ContentTypeHandlerManager { /** ContentTypeHandlers keyed by the extension */ Map<String,ContentTypeHandler> handlersByExtension = new HashMap<String,ContentTypeHandler>(); @@ -50,7 +50,6 @@ Map<String,ContentTypeHandler> handlersByContentType = new HashMap<String,ContentTypeHandler>(); String defaultExtension; - public static final String STRUTS_REST_HANDLER_OVERRIDE_PREFIX = "struts.rest.handlerOverride."; @Inject("struts.rest.defaultExtension") public void setDefaultExtension(String name) { Propchange: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/DefaultContentTypeHandlerManager.java ------------------------------------------------------------------------------ svn:keywords = Date Author Id Revision HeadURL Modified: struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java?rev=676195&r1=676194&r2=676195&view=diff ============================================================================== --- struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java (original) +++ struts/struts2/trunk/plugins/rest/src/main/java/org/apache/struts2/rest/RestWorkflowInterceptor.java Sat Jul 12 08:55:58 2008 @@ -145,6 +145,8 @@ private String newMethodName = "editNew"; private String putMethodName = "update"; + private int validationFailureStatusCode = SC_BAD_REQUEST; + @Inject(required=false,value="struts.mapper.postMethodName") public void setPostMethodName(String postMethodName) { this.postMethodName = postMethodName; @@ -165,6 +167,11 @@ this.putMethodName = putMethodName; } + @Inject(required=false,value="struts.rest.validationFailureStatusCode") + public void setValidationFailureStatusCode(String code) { + this.validationFailureStatusCode = Integer.parseInt(code); + } + @Inject public void setContentTypeHandlerManager(ContentTypeHandlerManager mgr) { this.manager = mgr; @@ -208,7 +215,7 @@ HttpHeaders info = new DefaultHttpHeaders() .disableCaching() .renderResult(method) - .withStatus(SC_BAD_REQUEST); + .withStatus(validationFailureStatusCode); Map errors = new HashMap(); Modified: struts/struts2/trunk/plugins/rest/src/main/resources/struts-plugin.xml URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/main/resources/struts-plugin.xml?rev=676195&r1=676194&r2=676195&view=diff ============================================================================== --- struts/struts2/trunk/plugins/rest/src/main/resources/struts-plugin.xml (original) +++ struts/struts2/trunk/plugins/rest/src/main/resources/struts-plugin.xml Sat Jul 12 08:55:58 2008 @@ -30,7 +30,7 @@ <bean type="com.opensymphony.xwork2.ActionProxyFactory" name="rest" class="org.apache.struts2.rest.RestActionProxyFactory" /> <bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="rest" class="org.apache.struts2.rest.RestActionMapper" /> - <bean class="org.apache.struts2.rest.ContentTypeHandlerManager" /> + <bean type="org.apache.struts2.rest.ContentTypeHandlerManager" class="org.apache.struts2.rest.DefaultContentTypeHandlerManager" /> <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.JsonLibHandler" /> Modified: struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java?rev=676195&r1=676194&r2=676195&view=diff ============================================================================== --- struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java (original) +++ struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java Sat Jul 12 08:55:58 2008 @@ -45,13 +45,13 @@ public class ContentTypeHandlerManagerTest extends TestCase { - private ContentTypeHandlerManager mgr; + private DefaultContentTypeHandlerManager mgr; private MockHttpServletResponse mockResponse; private MockHttpServletRequest mockRequest; @Override public void setUp() { - mgr = new ContentTypeHandlerManager(); + mgr = new DefaultContentTypeHandlerManager(); mockResponse = new MockHttpServletResponse(); mockRequest = new MockHttpServletRequest(); mockRequest.setMethod("GET"); @@ -121,7 +121,7 @@ mockContainer.expectAndReturn("getInstance", C.args(C.eq(String.class), C.eq(ContentTypeHandlerManager.STRUTS_REST_HANDLER_OVERRIDE_PREFIX+"json")), null); - ContentTypeHandlerManager mgr = new ContentTypeHandlerManager(); + DefaultContentTypeHandlerManager mgr = new DefaultContentTypeHandlerManager(); mgr.setContainer((Container) mockContainer.proxy()); Map<String,ContentTypeHandler> handlers = mgr.handlersByExtension; Added: struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java?rev=676195&view=auto ============================================================================== --- struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java (added) +++ struts/struts2/trunk/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java Sat Jul 12 08:55:58 2008 @@ -0,0 +1,65 @@ +/* + * $Id: RestWorkflowInterceptor.java 666756 2008-06-11 18:11:00Z hermanns $ + * + * 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 com.mockobjects.dynamic.AnyConstraintMatcher; +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ActionSupport; +import junit.framework.TestCase; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.mapper.ActionMapping; + +import java.util.HashMap; + +public class RestWorkflowInterceptorTest extends TestCase { + + public void testCustomValidationFailureStatusCode() throws Exception { + RestWorkflowInterceptor wf = new RestWorkflowInterceptor(); + + ActionSupport action = new ActionSupport(); + action.addActionError("some error"); + + wf.setValidationFailureStatusCode("666"); + Mock mockActionInvocation = new Mock(ActionInvocation.class); + Mock mockActionProxy = new Mock(ActionProxy.class); + mockActionProxy.expectAndReturn("getConfig", null); + mockActionInvocation.expectAndReturn("getProxy", mockActionProxy.proxy()); + mockActionInvocation.expectAndReturn("getAction", action); + Mock mockContentTypeHandlerManager = new Mock(ContentTypeHandlerManager.class); + mockContentTypeHandlerManager.expectAndReturn("handleResult", new AnyConstraintMatcher() { + public boolean matches(Object[] args) { + DefaultHttpHeaders headers = (DefaultHttpHeaders) args[1]; + return 666 == headers.status; + } + }, null); + wf.setContentTypeHandlerManager((ContentTypeHandlerManager) mockContentTypeHandlerManager.proxy()); + + ActionContext.setContext(new ActionContext(new HashMap() {{ + put(ServletActionContext.ACTION_MAPPING, new ActionMapping()); + }})); + wf.doIntercept((ActionInvocation) mockActionInvocation.proxy()); + mockContentTypeHandlerManager.verify(); + mockActionInvocation.verify(); + } +}