You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2009/04/27 00:58:18 UTC
svn commit: r768826 - in /struts/struts2/trunk/plugins/convention/src:
main/java/org/apache/struts2/convention/
main/java/org/apache/struts2/convention/annotation/
test/java/org/apache/struts2/convention/
test/java/org/apache/struts2/convention/actions...
Author: musachy
Date: Sun Apr 26 22:58:17 2009
New Revision: 768826
URL: http://svn.apache.org/viewvc?rev=768826&view=rev
Log:
WW-3101 @Action and @Actions should be able to be applied to classes, the method will be determined at runtime by Dynamic Action invocation mechanism
Added:
struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationAction.java
struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationDefaultMethodAction.java
struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsAction.java
struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsDefaultMethodAction.java
Modified:
struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java
struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Action.java
struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java
struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java?rev=768826&r1=768825&r2=768826&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java (original)
+++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/PackageBasedActionConfigBuilder.java Sun Apr 26 22:58:17 2009
@@ -40,6 +40,7 @@
import com.opensymphony.xwork2.util.finder.ClassLoaderInterfaceDelegate;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import com.opensymphony.xwork2.util.logging.LoggerUtils;
import org.apache.commons.lang.xwork.StringUtils;
import org.apache.commons.lang.xwork.ObjectUtils;
import org.apache.struts2.StrutsConstants;
@@ -99,6 +100,8 @@
private boolean reload;
private Set<String> fileProtocols;
+ private static final String DEFAULT_METHOD = "execute";
+
/**
* Constructs actions based on a list of packages.
*
@@ -459,6 +462,9 @@
Map<String, PackageConfig.Builder> packageConfigs = new HashMap<String, PackageConfig.Builder>();
for (Class<?> actionClass : classes) {
+ Actions actionsAnnotation = actionClass.getAnnotation(Actions.class);
+ Action actionAnnotation = actionClass.getAnnotation(Action.class);
+
// Skip classes that can't be instantiated
if (cannotInstantiate(actionClass)) {
if (LOG.isTraceEnabled())
@@ -485,7 +491,6 @@
List<String> namespaces = determineActionNamespace(actionClass);
for (String namespace : namespaces) {
String defaultActionName = determineActionName(actionClass);
- String defaultActionMethod = "execute";
PackageConfig.Builder defaultPackageConfig = getPackageConfig(packageConfigs, namespace,
actionPackage, actionClass, null);
@@ -493,7 +498,10 @@
// configuration should still be built or not.
Map<String, List<Action>> map = getActionAnnotations(actionClass);
Set<String> actionNames = new HashSet<String>();
- if (!map.containsKey(defaultActionMethod) && ReflectionTools.containsMethod(actionClass, defaultActionMethod)) {
+ boolean hasDefaultMethod = ReflectionTools.containsMethod(actionClass, DEFAULT_METHOD);
+ if (!map.containsKey(DEFAULT_METHOD)
+ && hasDefaultMethod
+ && actionAnnotation == null && actionsAnnotation == null) {
boolean found = false;
for (String method : map.keySet()) {
List<Action> actions = map.get(method);
@@ -518,7 +526,7 @@
// Build the default
if (!found) {
- createActionConfig(defaultPackageConfig, actionClass, defaultActionName, defaultActionMethod, null);
+ createActionConfig(defaultPackageConfig, actionClass, defaultActionName, DEFAULT_METHOD, null);
}
}
@@ -538,10 +546,18 @@
// some actions will not have any @Action or a default method, like the rest actions
// where the action mapper is the one that finds the right method at runtime
- if (map.isEmpty() && mapAllMatches) {
- Action actionAnnotation = actionClass.getAnnotation(Action.class);
+ if (map.isEmpty() && mapAllMatches && actionAnnotation == null && actionsAnnotation == null) {
createActionConfig(defaultPackageConfig, actionClass, defaultActionName, null, actionAnnotation);
}
+
+ //if there are @Actions or @Action at the class level, create the mappings for them
+ String methodName = hasDefaultMethod ? DEFAULT_METHOD : null;
+ if (actionsAnnotation != null) {
+ List<Action> actionAnnotations = checkActionsAnnotation(actionsAnnotation);
+ for (Action actionAnnotation2 : actionAnnotations)
+ createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation2);
+ } else if (actionAnnotation != null)
+ createActionConfig(defaultPackageConfig, actionClass, defaultActionName, methodName, actionAnnotation);
}
}
@@ -671,20 +687,7 @@
for (Method method : methods) {
Actions actionsAnnotation = method.getAnnotation(Actions.class);
if (actionsAnnotation != null) {
- Action[] actionArray = actionsAnnotation.value();
- boolean valuelessSeen = false;
- List<Action> actions = new ArrayList<Action>();
- for (Action ann : actionArray) {
- if (ann.value().equals(Action.DEFAULT_VALUE) && !valuelessSeen) {
- valuelessSeen = true;
- } else if (ann.value().equals(Action.DEFAULT_VALUE)) {
- throw new ConfigurationException("You may only add a single Action " +
- "annotation that has no value parameter.");
- }
-
- actions.add(ann);
- }
-
+ List<Action> actions = checkActionsAnnotation(actionsAnnotation);
map.put(method.getName(), actions);
} else {
Action ann = method.getAnnotation(Action.class);
@@ -698,6 +701,28 @@
}
/**
+ * Builds a list of actions from an @Actions annotation, and check that they are not all empty
+ * @param actionsAnnotation Actions annotation
+ * @return a list of Actions
+ */
+ protected List<Action> checkActionsAnnotation(Actions actionsAnnotation) {
+ Action[] actionArray = actionsAnnotation.value();
+ boolean valuelessSeen = false;
+ List<Action> actions = new ArrayList<Action>();
+ for (Action ann : actionArray) {
+ if (ann.value().equals(Action.DEFAULT_VALUE) && !valuelessSeen) {
+ valuelessSeen = true;
+ } else if (ann.value().equals(Action.DEFAULT_VALUE)) {
+ throw new ConfigurationException("You may only add a single Action " +
+ "annotation that has no value parameter.");
+ }
+
+ actions.add(ann);
+ }
+ return actions;
+ }
+
+ /**
* Creates a single ActionConfig object.
*
* @param pkgCfg The package the action configuration instance will belong to.
Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Action.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Action.java?rev=768826&r1=768825&r2=768826&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Action.java (original)
+++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Action.java Sun Apr 26 22:58:17 2009
@@ -52,7 +52,7 @@
* </pre>
* <!-- END SNIPPET: javadoc -->
*/
-@Target({ElementType.METHOD})
+@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Action {
String DEFAULT_VALUE = "DEFAULT_VALUE";
Modified: struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java?rev=768826&r1=768825&r2=768826&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java (original)
+++ struts/struts2/trunk/plugins/convention/src/main/java/org/apache/struts2/convention/annotation/Actions.java Sun Apr 26 22:58:17 2009
@@ -33,7 +33,7 @@
* </p>
* <!-- END SNIPPET: javadoc -->
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Actions {
Action[] value() default {};
Modified: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java?rev=768826&r1=768825&r2=768826&view=diff
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java (original)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java Sun Apr 26 22:58:17 2009
@@ -35,11 +35,7 @@
import org.apache.struts2.convention.actions.NoAnnotationAction;
import org.apache.struts2.convention.actions.Skip;
import org.apache.struts2.convention.actions.chain.ChainedAction;
-import org.apache.struts2.convention.actions.action.ActionNameAction;
-import org.apache.struts2.convention.actions.action.ActionNamesAction;
-import org.apache.struts2.convention.actions.action.SingleActionNameAction;
-import org.apache.struts2.convention.actions.action.TestAction;
-import org.apache.struts2.convention.actions.action.TestExtends;
+import org.apache.struts2.convention.actions.action.*;
import org.apache.struts2.convention.actions.defaultinterceptor.SingleActionNameAction2;
import org.apache.struts2.convention.actions.exception.ExceptionsActionLevelAction;
import org.apache.struts2.convention.actions.exception.ExceptionsMethodLevelAction;
@@ -194,6 +190,17 @@
expect(resultMapBuilder.build(TestAction.class, null, "test", actionPkg)).andReturn(results);
expect(resultMapBuilder.build(TestExtends.class, null, "test-extends", actionPkg)).andReturn(results);
+ Actions classLevelActions = ClassLevelAnnotationsAction.class.getAnnotation(Actions.class);
+ expect(resultMapBuilder.build(ClassLevelAnnotationsAction.class, classLevelActions.value()[0], "class1", actionPkg)).andReturn(results);
+ expect(resultMapBuilder.build(ClassLevelAnnotationsAction.class, classLevelActions.value()[1], "class2", actionPkg)).andReturn(results);
+
+ Actions classLevelActionsDefaultMethod = ClassLevelAnnotationsDefaultMethodAction.class.getAnnotation(Actions.class);
+ expect(resultMapBuilder.build(ClassLevelAnnotationsDefaultMethodAction.class, classLevelActionsDefaultMethod.value()[0], "class3", actionPkg)).andReturn(results);
+ expect(resultMapBuilder.build(ClassLevelAnnotationsDefaultMethodAction.class, classLevelActionsDefaultMethod.value()[1], "class4", actionPkg)).andReturn(results);
+
+ expect(resultMapBuilder.build(ClassLevelAnnotationAction.class, ClassLevelAnnotationAction.class.getAnnotation(Action.class), "class5", actionPkg)).andReturn(results);
+ expect(resultMapBuilder.build(ClassLevelAnnotationDefaultMethodAction.class, ClassLevelAnnotationDefaultMethodAction.class.getAnnotation(Action.class), "class6", actionPkg)).andReturn(results);
+
/* org.apache.struts2.convention.actions.idx */
/* org.apache.struts2.convention.actions.idx.idx2 */
expect(resultMapBuilder.build(org.apache.struts2.convention.actions.idx.Index.class, null, "index", idxPkg)).andReturn(results);
@@ -314,7 +321,7 @@
/* org.apache.struts2.convention.actions.action */
PackageConfig pkgConfig = configuration.getPackageConfig("org.apache.struts2.convention.actions.action#struts-default#/action");
assertNotNull(pkgConfig);
- assertEquals(7, pkgConfig.getActionConfigs().size());
+ assertEquals(13, pkgConfig.getActionConfigs().size());
verifyActionConfig(pkgConfig, "action1", ActionNameAction.class, "run1", pkgConfig.getName());
verifyActionConfig(pkgConfig, "action2", ActionNameAction.class, "run2", pkgConfig.getName());
verifyActionConfig(pkgConfig, "actions1", ActionNamesAction.class, "run", pkgConfig.getName());
@@ -323,6 +330,13 @@
verifyActionConfig(pkgConfig, "test", TestAction.class, "execute", pkgConfig.getName());
verifyActionConfig(pkgConfig, "test-extends", TestExtends.class, "execute", pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class1", ClassLevelAnnotationsAction.class, null, pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class2", ClassLevelAnnotationsAction.class, null, pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class3", ClassLevelAnnotationsDefaultMethodAction.class, "execute", pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class4", ClassLevelAnnotationsDefaultMethodAction.class, "execute", pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class5", ClassLevelAnnotationAction.class, null, pkgConfig.getName());
+ verifyActionConfig(pkgConfig, "class6", ClassLevelAnnotationDefaultMethodAction.class, "execute", pkgConfig.getName());
+
/* org.apache.struts2.convention.actions.namespace3 */
//action on namespace1 (action level)
pkgConfig = configuration.getPackageConfig("org.apache.struts2.convention.actions.namespace3#struts-default#/namespaces1");
Added: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationAction.java?rev=768826&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationAction.java (added)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationAction.java Sun Apr 26 22:58:17 2009
@@ -0,0 +1,27 @@
+/*
+ * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $
+ *
+ * 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.convention.actions.action;
+
+import org.apache.struts2.convention.annotation.Action;
+
+@Action("class5")
+public class ClassLevelAnnotationAction {
+}
Added: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationDefaultMethodAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationDefaultMethodAction.java?rev=768826&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationDefaultMethodAction.java (added)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationDefaultMethodAction.java Sun Apr 26 22:58:17 2009
@@ -0,0 +1,30 @@
+/*
+ * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $
+ *
+ * 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.convention.actions.action;
+
+import org.apache.struts2.convention.annotation.Action;
+
+@Action("class6")
+public class ClassLevelAnnotationDefaultMethodAction {
+ public String execute() {
+ return "boo";
+ }
+}
Added: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsAction.java?rev=768826&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsAction.java (added)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsAction.java Sun Apr 26 22:58:17 2009
@@ -0,0 +1,32 @@
+/*
+ * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $
+ *
+ * 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.convention.actions.action;
+
+import org.apache.struts2.convention.annotation.Actions;
+import org.apache.struts2.convention.annotation.Action;
+
+@Actions({
+ @Action("class1"),
+ @Action("class2")
+})
+public class ClassLevelAnnotationsAction {
+
+}
Added: struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsDefaultMethodAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsDefaultMethodAction.java?rev=768826&view=auto
==============================================================================
--- struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsDefaultMethodAction.java (added)
+++ struts/struts2/trunk/plugins/convention/src/test/java/org/apache/struts2/convention/actions/action/ClassLevelAnnotationsDefaultMethodAction.java Sun Apr 26 22:58:17 2009
@@ -0,0 +1,34 @@
+/*
+ * $Id: ActionNamesAction.java 655902 2008-05-13 15:15:12Z bpontarelli $
+ *
+ * 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.convention.actions.action;
+
+import org.apache.struts2.convention.annotation.Actions;
+import org.apache.struts2.convention.annotation.Action;
+
+@Actions({
+ @Action("class3"),
+ @Action("class4")
+})
+public class ClassLevelAnnotationsDefaultMethodAction {
+ public String execute() {
+ return "boo";
+ }
+}