Author: mrdon
Date: Sat Oct 13 08:41:39 2007
New Revision: 584413

URL: http://svn.apache.org/viewvc?rev=584413&view=rev
Log:
Adding action annotation
WW-2251
Added:
    
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/Action.java
    
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/AnnotatedAction.java
Modified:
    
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/ClasspathPackageProvider.java
    
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/ClasspathPackageProviderTest.java

Added: 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/Action.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/Action.java?rev=584413&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/Action.java
 (added)
+++ 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/Action.java
 Sat Oct 13 08:41:39 2007
@@ -0,0 +1,31 @@
+/*
+ * $Id: Namespace.java 584166 2007-10-12 14:07:52Z 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.config;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
[EMAIL PROTECTED](RetentionPolicy.RUNTIME)
+public @interface Action {
+    public static final String DEFAULT_NAMESPACE = "__default_namespace__";
+    String namespace() default DEFAULT_NAMESPACE;
+    String name();
+}

Modified: 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/ClasspathPackageProvider.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/ClasspathPackageProvider.java?rev=584413&r1=584412&r2=584413&view=diff
==============================================================================
--- 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/ClasspathPackageProvider.java
 (original)
+++ 
struts/struts2/trunk/plugins/codebehind/src/main/java/org/apache/struts2/config/ClasspathPackageProvider.java
 Sat Oct 13 08:41:39 2007
@@ -246,7 +246,8 @@
             public boolean matches(Class type) {
                 // TODO: should also find annotated classes
                 return (Action.class.isAssignableFrom(type) ||
-                        type.getSimpleName().endsWith("Action"));
+                        type.getSimpleName().endsWith("Action") ||
+                        
type.getAnnotation(org.apache.struts2.config.Action.class) != null);
             }
 
         }, pkgs);
@@ -274,26 +275,53 @@
      * @param cls Action or POJO instance to process
      * @param pkgs List of packages that were scanned for Actions
      */
-    protected void processActionClass(Class cls, String[] pkgs) {
+    protected void processActionClass(Class<?> cls, String[] pkgs) {
+        ActionConfig actionConfig = new ActionConfig();
         String name = cls.getName();
         String actionPackage = cls.getPackage().getName();
         String actionNamespace = null;
         String actionName = null;
-        for (String pkg : pkgs) {
-            if (name.startsWith(pkg)) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("ClasspathPackageProvider: Processing class 
"+name);
-                }
-                name = name.substring(pkg.length() + 1);
-
+        
+        org.apache.struts2.config.Action actionAnn = 
+            (org.apache.struts2.config.Action) 
cls.getAnnotation(org.apache.struts2.config.Action.class);
+        if (actionAnn != null) {
+            actionName = actionAnn.name();
+            if 
(actionAnn.namespace().equals(org.apache.struts2.config.Action.DEFAULT_NAMESPACE))
 {
                 actionNamespace = "";
-                actionName = name;
-                int pos = name.lastIndexOf('.');
-                if (pos > -1) {
-                    actionNamespace = "/" + name.substring(0, 
pos).replace('.','/');
-                    actionName = name.substring(pos+1);
+            } else {
+                actionNamespace = actionAnn.namespace();
+            }
+        } else {
+            for (String pkg : pkgs) {
+                if (name.startsWith(pkg)) {
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("ClasspathPackageProvider: Processing class 
"+name);
+                    }
+                    name = name.substring(pkg.length() + 1);
+    
+                    actionNamespace = "";
+                    actionName = name;
+                    int pos = name.lastIndexOf('.');
+                    if (pos > -1) {
+                        actionNamespace = "/" + name.substring(0, 
pos).replace('.','/');
+                        actionName = name.substring(pos+1);
+                    }
+                    break;
                 }
-                break;
+            }
+            // Truncate Action suffix if found
+            if (actionName.endsWith(ACTION)) {
+                actionName = actionName.substring(0, actionName.length() - 
ACTION.length());
+            }
+
+            // Force initial letter of action to lowercase, if desired
+            if ((forceLowerCase) && (actionName.length() > 1)) {
+                int lowerPos = actionName.lastIndexOf('/') + 1;
+                StringBuilder sb = new StringBuilder();
+                sb.append(actionName.substring(0, lowerPos));
+                sb.append(Character.toLowerCase(actionName.charAt(lowerPos)));
+                sb.append(actionName.substring(lowerPos + 1));
+                actionName = sb.toString();
             }
         }
 
@@ -318,22 +346,6 @@
             }
         }
 
-        // Truncate Action suffix if found
-        if (actionName.endsWith(ACTION)) {
-            actionName = actionName.substring(0, actionName.length() - 
ACTION.length());
-        }
-
-        // Force initial letter of action to lowercase, if desired
-        if ((forceLowerCase) && (actionName.length() > 1)) {
-            int lowerPos = actionName.lastIndexOf('/') + 1;
-            StringBuilder sb = new StringBuilder();
-            sb.append(actionName.substring(0, lowerPos));
-            sb.append(Character.toLowerCase(actionName.charAt(lowerPos)));
-            sb.append(actionName.substring(lowerPos + 1));
-            actionName = sb.toString();
-        }
-
-        ActionConfig actionConfig = new ActionConfig();
         actionConfig.setClassName(cls.getName());
         actionConfig.setPackageName(actionPackage);
 
@@ -355,15 +367,27 @@
     protected PackageConfig loadPackageConfig(String actionNamespace, String 
actionPackage, Class actionClass) {
         PackageConfig parent = null;
 
+        // Check for the @Namespace annotation
         if (actionClass != null) {
             Namespace ns = (Namespace) 
actionClass.getAnnotation(Namespace.class);
             if (ns != null) {
                 parent = loadPackageConfig(actionNamespace, actionPackage, 
null);
                 actionNamespace = ns.value();
                 actionPackage = actionClass.getName();
+                
+            // See if the namespace has been overridden by the @Action 
annotation    
+            } else {
+                org.apache.struts2.config.Action actionAnn = 
+                    (org.apache.struts2.config.Action) 
actionClass.getAnnotation(org.apache.struts2.config.Action.class);
+                if (actionAnn != null && 
!actionAnn.DEFAULT_NAMESPACE.equals(actionAnn.namespace())) {
+                    // we pass null as the namespace in case the parent 
package hasn't been loaded yet
+                    parent = loadPackageConfig(null, actionPackage, null);
+                    actionPackage = actionClass.getName();
+                }
             }
         }
 
+        
         PackageConfig pkgConfig = loadedPackageConfigs.get(actionPackage);
         if (pkgConfig == null) {
             pkgConfig = new PackageConfig();
@@ -382,6 +406,10 @@
             pkgConfig.setNamespace(actionNamespace);
 
             loadedPackageConfigs.put(actionPackage, pkgConfig);
+            
+        // if the parent package was first created by a child, ensure the 
namespace is correct
+        } else if (pkgConfig.getNamespace() == null) {
+            pkgConfig.setNamespace(actionNamespace);
         }
         return pkgConfig;
     }

Added: 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/AnnotatedAction.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/AnnotatedAction.java?rev=584413&view=auto
==============================================================================
--- 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/AnnotatedAction.java
 (added)
+++ 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/AnnotatedAction.java
 Sat Oct 13 08:41:39 2007
@@ -0,0 +1,26 @@
+/*
+ * $Id: CustomNamespaceAction.java 584166 2007-10-12 14:07:52Z 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.config;
+
[EMAIL PROTECTED](name="myaction",namespace="/foo")
+public class AnnotatedAction {
+
+}

Modified: 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/ClasspathPackageProviderTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/ClasspathPackageProviderTest.java?rev=584413&r1=584412&r2=584413&view=diff
==============================================================================
--- 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/ClasspathPackageProviderTest.java
 (original)
+++ 
struts/struts2/trunk/plugins/codebehind/src/test/java/org/apache/struts2/config/ClasspathPackageProviderTest.java
 Sat Oct 13 08:41:39 2007
@@ -20,9 +20,11 @@
  */
 package org.apache.struts2.config;
 
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.struts2.dispatcher.ServletDispatcherResult;
+import org.apache.struts2.util.StrutsTestCaseHelper;
 
 import com.opensymphony.xwork2.config.Configuration;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
@@ -38,7 +40,7 @@
     ClasspathPackageProvider provider;
     Configuration config;
 
-    public void setUp() {
+    public void setUp() throws Exception {
         provider = new ClasspathPackageProvider();
         provider.setActionPackages("org.apache.struts2.config");
         config = new DefaultConfiguration();
@@ -52,9 +54,14 @@
         provider.init(config);
         provider.loadPackages();
     }
-
+    
+    public void tearDown() throws Exception {
+        provider = null;
+        config = null;
+    }
+    
     public void testFoundRootPackages() {
-        assertEquals(5, config.getPackageConfigs().size());
+        assertEquals(6, config.getPackageConfigs().size());
         PackageConfig pkg = 
config.getPackageConfig("org.apache.struts2.config");
         assertNotNull(pkg);
         Map configs = pkg.getActionConfigs();
@@ -85,7 +92,23 @@
         ActionConfig ac = (ActionConfig) configs.get("customParentPackage");
         assertNotNull(ac);
     }
-
+    
+    public void testCustomActionAnnotation() {
+        PackageConfig pkg = 
config.getPackageConfig("org.apache.struts2.config.AnnotatedAction");
+        Map configs = pkg.getAllActionConfigs();
+        // assertEquals(2, configs.size());
+        ActionConfig config = (ActionConfig) configs.get("myaction");
+        assertNotNull(config);
+    }
+    
+    public void testCustomActionAnnotationOfAnyName() {
+        PackageConfig pkg = 
config.getPackageConfig("org.apache.struts2.config");
+        Map configs = pkg.getAllActionConfigs();
+        // assertEquals(2, configs.size());
+        ActionConfig config = (ActionConfig) configs.get("myaction2");
+        assertNotNull(config);
+    }
+    
     public void testResultAnnotations() {
         PackageConfig pkg = 
config.getPackageConfig("org.apache.struts2.config.cltest");
         assertEquals("/cltest", pkg.getNamespace());


Reply via email to