struts-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lukaszlen...@apache.org
Subject svn commit: r1423571 - in /struts/struts2/trunk/plugins/convention/src: main/java/org/apache/struts2/convention/ConventionUnknownHandler.java test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java
Date Tue, 18 Dec 2012 18:36:10 GMT
Author: lukaszlenart
Date: Tue Dec 18 18:36:09 2012
New Revision: 1423571

URL: http://svn.apache.org/viewvc?rev=1423571&view=rev
Log:
WW-3925 adds better support for looking index action when user hits default namespace

Modified:
    struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java
    struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java

Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java?rev=1423571&r1=1423570&r2=1423571&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java
(original)
+++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/ConventionUnknownHandler.java
Tue Dec 18 18:36:09 2012
@@ -66,7 +66,9 @@ import java.util.Map;
  * </p>
  */
 public class ConventionUnknownHandler implements UnknownHandler {
+
     private static final Logger LOG = LoggerFactory.getLogger(ConventionUnknownHandler.class);
+
     protected Configuration configuration;
     protected ObjectFactory objectFactory;
     protected ServletContext servletContext;
@@ -81,24 +83,24 @@ public class ConventionUnknownHandler im
     /**
      * Constructs the unknown handler.
      *
-     * @param   configuration The XWork configuration.
-     * @param   objectFactory The XWork object factory used to create result instances.
-     * @param   servletContext The servlet context used to help build the action configurations.
-     * @param   container The Xwork container
-     * @param   defaultParentPackageName The default XWork package that the unknown handler
will use as
-     *          the parent package for new actions and results.
-     * @param   redirectToSlash A boolean parameter that controls whether or not this will
handle
-     *          unknown actions in the same manner as Apache, Tomcat and other web servers.
This
-     *          handling will send back a redirect for URLs such as /foo to /foo/ if there
doesn't
-     *          exist an action that responds to /foo.
-     * @param   nameSeparator The character used as word separator in the action names. "-"
by default
+     * @param configuration            The XWork configuration.
+     * @param objectFactory            The XWork object factory used to create result instances.
+     * @param servletContext           The servlet context used to help build the action
configurations.
+     * @param container                The Xwork container
+     * @param defaultParentPackageName The default XWork package that the unknown handler
will use as
+     *                                 the parent package for new actions and results.
+     * @param redirectToSlash          A boolean parameter that controls whether or not this
will handle
+     *                                 unknown actions in the same manner as Apache, Tomcat
and other web servers. This
+     *                                 handling will send back a redirect for URLs such as
/foo to /foo/ if there doesn't
+     *                                 exist an action that responds to /foo.
+     * @param nameSeparator            The character used as word separator in the action
names. "-" by default
      */
     @Inject
     public ConventionUnknownHandler(Configuration configuration, ObjectFactory objectFactory,
-            ServletContext servletContext, Container container,
-            @Inject("struts.convention.default.parent.package") String defaultParentPackageName,
-            @Inject("struts.convention.redirect.to.slash") String redirectToSlash,
-            @Inject("struts.convention.action.name.separator") String nameSeparator) {
+                                    ServletContext servletContext, Container container,
+                                    @Inject("struts.convention.default.parent.package") String
defaultParentPackageName,
+                                    @Inject("struts.convention.redirect.to.slash") String
redirectToSlash,
+                                    @Inject("struts.convention.action.name.separator") String
nameSeparator) {
         this.configuration = configuration;
         this.objectFactory = objectFactory;
         this.servletContext = servletContext;
@@ -116,7 +118,7 @@ public class ConventionUnknownHandler im
     }
 
     public ActionConfig handleUnknownAction(String namespace, String actionName)
-    throws XWorkException {
+            throws XWorkException {
         // Strip the namespace if it is just a slash
         if (namespace == null || "/".equals(namespace)) {
             namespace = "";
@@ -173,6 +175,14 @@ public class ConventionUnknownHandler im
                 // Otherwise, if the URL is /foo or /foo/ look for index pages in /foo/
                 actionConfig = buildActionConfig(resource.path, resultsByExtension.get(resource.ext));
             }
+
+            // try to find index action in current namespace or in default one
+            if (actionConfig == null) {
+                if (LOG.isTraceEnabled()) {
+                    LOG.trace("Looking for action named [index] in namespace [#0] or in default
namespace", namespace);
+                }
+                actionConfig = configuration.getRuntimeConfiguration().getActionConfig(namespace,
"index");
+            }
         }
 
         return actionConfig;
@@ -181,9 +191,9 @@ public class ConventionUnknownHandler im
     /**
      * Finds a resource using the given path parts and all of the extensions in the map.
      *
-     * @param   resultsByExtension Map of extension to result type config objects.
-     * @param   parts The parts of the resource.
-     * @return  The resource path or null.
+     * @param resultsByExtension Map of extension to result type config objects.
+     * @param parts              The parts of the resource.
+     * @return The resource path or null.
      */
     protected Resource findResource(Map<String, ResultTypeConfig> resultsByExtension,
String... parts) {
         for (String ext : resultsByExtension.keySet()) {
@@ -197,8 +207,9 @@ public class ConventionUnknownHandler im
                     return new Resource(canonicalPath, ext);
                 }
             } catch (MalformedURLException e) {
-                if (LOG.isErrorEnabled())
+                if (LOG.isErrorEnabled()) {
                     LOG.error("Unable to parse path to the web application resource [#0]
skipping...", canonicalPath);
+                }
             }
         }
 
@@ -214,7 +225,7 @@ public class ConventionUnknownHandler im
     }
 
     protected ActionConfig buildActionConfig(String path, ResultTypeConfig resultTypeConfig)
{
-        Map<String, ResultConfig> results = new HashMap<String,ResultConfig>();
+        Map<String, ResultConfig> results = new HashMap<String, ResultConfig>();
         HashMap<String, String> params = new HashMap<String, String>();
         if (resultTypeConfig.getParams() != null) {
             params.putAll(resultTypeConfig.getParams());
@@ -222,17 +233,17 @@ public class ConventionUnknownHandler im
         params.put(resultTypeConfig.getDefaultResultParam(), path);
 
         PackageConfig pkg = configuration.getPackageConfig(defaultParentPackageName);
-        List<InterceptorMapping> interceptors = InterceptorBuilder.constructInterceptorReference(pkg,
pkg.getFullDefaultInterceptorRef(), Collections.EMPTY_MAP, null, objectFactory);
+        List<InterceptorMapping> interceptors = InterceptorBuilder.constructInterceptorReference(pkg,
pkg.getFullDefaultInterceptorRef(), Collections.<String, String>emptyMap(), null, objectFactory);
         ResultConfig config = new ResultConfig.Builder(Action.SUCCESS, resultTypeConfig.getClassName()).
-            addParams(params).build();
+                addParams(params).build();
         results.put(Action.SUCCESS, config);
 
         return new ActionConfig.Builder(defaultParentPackageName, "execute", ActionSupport.class.getName()).
-            addInterceptors(interceptors).addResultConfigs(results).build();
+                addInterceptors(interceptors).addResultConfigs(results).build();
     }
 
     private Result scanResultsByExtension(String ns, String actionName, String pathPrefix,
-            String resultCode, ActionContext actionContext) {
+                                          String resultCode, ActionContext actionContext)
{
         Map<String, ResultTypeConfig> resultsByExtension = conventionsService.getResultTypesByExtension(parentPackage);
         Result result = null;
         for (String ext : resultsByExtension.keySet()) {
@@ -243,31 +254,31 @@ public class ConventionUnknownHandler im
                         fqan, ext, pathPrefix, resultCode);
             }
 
-            String path = string(pathPrefix, actionName, nameSeparator, resultCode, "." ,
ext);
+            String path = string(pathPrefix, actionName, nameSeparator, resultCode, ".",
ext);
             result = findResult(path, resultCode, ext, actionContext, resultsByExtension);
             if (result != null) {
                 break;
             }
 
-            path = string(pathPrefix, actionName, "." , ext);
+            path = string(pathPrefix, actionName, ".", ext);
             result = findResult(path, resultCode, ext, actionContext, resultsByExtension);
             if (result != null) {
                 break;
             }
 
             // Issue #6 - Scan for result-code as page name
-            path = string(pathPrefix, resultCode, "." , ext);
+            path = string(pathPrefix, resultCode, ".", ext);
             result = findResult(path, resultCode, ext, actionContext, resultsByExtension);
             if (result != null) {
                 break;
             }
 
         }
-      return result;
+        return result;
     }
 
     public Result handleUnknownResult(ActionContext actionContext, String actionName,
-            ActionConfig actionConfig, String resultCode) throws XWorkException {
+                                      ActionConfig actionConfig, String resultCode) throws
XWorkException {
 
         PackageConfig pkg = configuration.getPackageConfig(actionConfig.getPackageName());
         String ns = pkg.getNamespace();
@@ -290,7 +301,7 @@ public class ConventionUnknownHandler im
                     break;
                 }
 
-                path = string(pathPrefix, actionName, "/index." , ext);
+                path = string(pathPrefix, actionName, "/index.", ext);
                 result = findResult(path, resultCode, ext, actionContext, resultsByExtension);
                 if (result != null) {
                     break;
@@ -302,7 +313,7 @@ public class ConventionUnknownHandler im
             //try to find an action to chain to. If the source action is "foo" and
             //the result is "bar", we will try to find an action called "foo-bar"
             //in the same package
-            String chainedTo = new StringBuilder(actionName).append(nameSeparator).append(resultCode).toString();
+            String chainedTo = actionName + nameSeparator + resultCode;
             ActionConfig chainedToConfig = pkg.getActionConfigs().get(chainedTo);
             if (chainedToConfig != null) {
                 if (LOG.isTraceEnabled()) {
@@ -318,7 +329,7 @@ public class ConventionUnknownHandler im
     }
 
     protected Result findResult(String path, String resultCode, String ext, ActionContext
actionContext,
-            Map<String, ResultTypeConfig> resultsByExtension) {
+                                Map<String, ResultTypeConfig> resultsByExtension) {
         try {
             boolean traceEnabled = LOG.isTraceEnabled();
             if (traceEnabled)
@@ -350,7 +361,7 @@ public class ConventionUnknownHandler im
     protected Result buildResult(String path, String resultCode, ResultTypeConfig config,
ActionContext invocationContext) {
         String resultClass = config.getClassName();
 
-        Map<String,String> params = new LinkedHashMap<String,String>();
+        Map<String, String> params = new LinkedHashMap<String, String>();
         if (config.getParams() != null) {
             params.putAll(config.getParams());
         }
@@ -376,10 +387,10 @@ public class ConventionUnknownHandler im
      * Determines the result path prefix that the request URL is for, minus the action name.
This includes
      * the base result location and the namespace, with all the slashes handled.
      *
-     * @param   actionConfig (Optional) The might be a ConventionActionConfig, from which
we can get the
-     *          default base result location of that specific action.
-     * @param   namespace The current URL namespace.
-     * @return  The path prefix and never null.
+     * @param actionConfig (Optional) The might be a ConventionActionConfig, from which we
can get the
+     *                     default base result location of that specific action.
+     * @param namespace    The current URL namespace.
+     * @return The path prefix and never null.
      */
     protected String determinePath(ActionConfig actionConfig, String namespace) {
         String finalPrefix = conventionsService.determineResultPath(actionConfig);
@@ -408,9 +419,9 @@ public class ConventionUnknownHandler im
     /**
      * Not used
      */
-	public Object handleUnknownActionMethod(Object action, String methodName) throws NoSuchMethodException
{
-		throw null;
-	}
+    public Object handleUnknownActionMethod(Object action, String methodName) throws NoSuchMethodException
{
+        throw null;
+    }
 
     public static class Resource {
         final String path;

Modified: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java?rev=1423571&r1=1423570&r2=1423571&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java
(original)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/ConventionUnknownHandlerTest.java
Tue Dec 18 18:36:09 2012
@@ -21,10 +21,22 @@
 package org.apache.struts2.convention;
 
 import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.RuntimeConfiguration;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.config.entities.PackageConfig;
 import com.opensymphony.xwork2.config.entities.ResultTypeConfig;
 import com.opensymphony.xwork2.inject.Container;
 import junit.framework.TestCase;
+import org.apache.struts2.dispatcher.ServletDispatcherResult;
+import org.easymock.EasyMock;
+
+import javax.servlet.ServletContext;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
 import static org.easymock.EasyMock.expect;
 import static org.easymock.classextension.EasyMock.createMock;
 import static org.easymock.classextension.EasyMock.createNiceMock;
@@ -32,13 +44,10 @@ import static org.easymock.classextensio
 import static org.easymock.classextension.EasyMock.replay;
 import static org.easymock.classextension.EasyMock.verify;
 
-import javax.servlet.ServletContext;
-import java.net.URL;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
-
 public class ConventionUnknownHandlerTest extends TestCase {
+
+    private PackageConfig packageConfiguration;
+
     public void testCanonicalizeShouldReturnNullWhenPathIsNull() throws Exception {
         final ConventionUnknownHandler handler = conventionUnknownHandler();
 
@@ -59,6 +68,24 @@ public class ConventionUnknownHandlerTes
                 handler.canonicalize("/should/not/modify/single/slashes.ext"));
     }
 
+    public void testHandleUnknownActionPointToIndex() throws Exception {
+        // given
+        ServletContext servletContext = createStrictMock(ServletContext.class);
+        expect(servletContext.getResource("/does-not-exist.jsp")).andReturn(null);
+        expect(servletContext.getResource("/does-not-exist/index.jsp")).andReturn(null);
+        replay(servletContext);
+
+        ConventionUnknownHandler handler = conventionUnknownHandler(servletContext);
+
+        // when
+        ActionConfig config = handler.handleUnknownAction("", "/does-not-exist");
+
+        // then
+        assertNotNull(config);
+        assertEquals("", config.getPackageName());
+        assertEquals("index", config.getName());
+    }
+
     public void testFindResourceShouldReturnNullAfterTryingEveryExtensionWithoutSuccess()
throws Exception {
         final ServletContext servletContext = createStrictMock(ServletContext.class);  //
Verifies method call order
 
@@ -114,18 +141,31 @@ public class ConventionUnknownHandlerTes
     private Configuration configuration(final String packageName) {
         final Configuration mock = createNiceMock(Configuration.class);
 
-        final PackageConfig packageConfiguration = packageConfiguration();
+        packageConfiguration = packageConfiguration();
         expect(mock.getPackageConfig(packageName)).andStubReturn(packageConfiguration);
+        RuntimeConfiguration runtime = createNiceMock(RuntimeConfiguration.class);
+        expect(runtime.getActionConfig("", "index")).andStubReturn(new ActionConfig.Builder("",
"index", "").build());
+        expect(mock.getRuntimeConfiguration()).andStubReturn(runtime);
 
-        replay(mock);
+        replay(mock, runtime);
 
         return mock;
     }
 
     private Container container() {
         final Container mock = createNiceMock(Container.class);
+        ConventionsService service = EasyMock.createNiceMock(ConventionsService.class);
 
-        replay(mock);
+        expect(mock.getInstance(String.class, ConventionConstants.CONVENTION_CONVENTIONS_SERVICE)).andReturn("test");
+        expect(mock.getInstance(ConventionsService.class, "test")).andStubReturn(service);
+
+        ActionConfig actionConfig = null;
+        expect(service.determineResultPath(actionConfig)).andReturn("");
+        Map<String, ResultTypeConfig> results = new HashMap<String, ResultTypeConfig>();
+        results.put("jsp", new ResultTypeConfig.Builder("dispatcher", ServletDispatcherResult.class.getName()).build());
+        expect(service.getResultTypesByExtension(packageConfiguration)).andReturn(results);
+
+        replay(mock, service);
 
         return mock;
     }



Mime
View raw message