Author: tv
Date: Tue Aug 12 12:40:41 2014
New Revision: 1617460
URL: http://svn.apache.org/r1617460
Log:
Add Annotation @TurbineActionEvent to annotate action methods with arbitrary
event names.
Added:
turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java
(with props)
Modified:
turbine/core/trunk/src/changes/changes.xml
turbine/core/trunk/src/java/org/apache/turbine/modules/ActionEvent.java
turbine/core/trunk/src/test/org/apache/turbine/modules/ActionLoaderTest.java
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionDoesNothing.java
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionThrowsException.java
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionWithServiceInjection.java
Modified: turbine/core/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/changes/changes.xml?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
--- turbine/core/trunk/src/changes/changes.xml (original)
+++ turbine/core/trunk/src/changes/changes.xml Tue Aug 12 12:40:41 2014
@@ -25,6 +25,10 @@
<body>
<release version="4.0-M2" date="in Subversion">
+ <action type="add" dev="tv">
+ Add Annotation @TurbineActionEvent to annotate action methods
+ with arbitrary event names.
+ </action>
<action type="update" dev="tv">
Update dependencies
- servlet-api to 2.5 (Tomcat 6.0)
Added:
turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java?rev=1617460&view=auto
==============================================================================
---
turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java
(added)
+++
turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java
Tue Aug 12 12:40:41 2014
@@ -0,0 +1,40 @@
+package org.apache.turbine.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/*
+ * 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.
+ */
+
+/**
+ * Annotation to associate methods in modules to action events
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( ElementType.METHOD )
+public @interface TurbineActionEvent
+{
+ /**
+ * Event name, no default
+ *
+ * @return the event name
+ */
+ String value();
+}
Propchange:
turbine/core/trunk/src/java/org/apache/turbine/annotation/TurbineActionEvent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
turbine/core/trunk/src/java/org/apache/turbine/modules/ActionEvent.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/java/org/apache/turbine/modules/ActionEvent.java?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
--- turbine/core/trunk/src/java/org/apache/turbine/modules/ActionEvent.java
(original)
+++ turbine/core/trunk/src/java/org/apache/turbine/modules/ActionEvent.java Tue
Aug 12 12:40:41 2014
@@ -21,16 +21,17 @@ package org.apache.turbine.modules;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Iterator;
+import java.util.Arrays;
import org.apache.commons.collections.map.MultiKeyMap;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fulcrum.parser.ParameterParser;
-import org.apache.fulcrum.parser.ParserService;
+import org.apache.fulcrum.parser.ValueParser.URLCaseFolding;
import org.apache.turbine.Turbine;
import org.apache.turbine.TurbineConstants;
+import org.apache.turbine.annotation.TurbineActionEvent;
import org.apache.turbine.pipeline.PipelineData;
import org.apache.turbine.util.RunData;
@@ -43,7 +44,7 @@ import org.apache.turbine.util.RunData;
* For example, "eventSubmit_doDelete". Then any class that subclasses
* this class will get its "doDelete(RunData data)" method executed.
* If for any reason, it was not able to execute the method, it will
- * fall back to executing the doPeform() method which is required to
+ * fall back to executing the doPerform() method which is required to
* be implemented.
*
* <p>
@@ -145,17 +146,40 @@ public abstract class ActionEvent extend
*
* @param name the name of the method
* @param signature an array of classes forming the signature of the
method
+ * @param pp ParameterParser for correct folding
*
* @return the method object
* @throws NoSuchMethodException if the method does not exist
*/
- protected Method getMethod(String name, Class<?>[] signature) throws
NoSuchMethodException
+ protected Method getMethod(String name, Class<?>[] signature,
ParameterParser pp) throws NoSuchMethodException
{
Method method = (Method) this.methodCache.get(name, signature);
if (method == null)
{
- method = getClass().getMethod(name, signature);
+ // Try annotations of public methods
+ Method[] methods = getClass().getMethods();
+ for (Method m : methods)
+ {
+ if (m.isAnnotationPresent(TurbineActionEvent.class))
+ {
+ TurbineActionEvent tae =
m.getAnnotation(TurbineActionEvent.class);
+ if (name.equals(pp.convert(tae.value()))
+ && Arrays.equals(signature, m.getParameterTypes()))
+ {
+ method = m;
+ break;
+ }
+ }
+ }
+
+ // Try legacy mode
+ if (method == null)
+ {
+ String tmp = name.toLowerCase().substring(METHOD_NAME_LENGTH);
+ method = getClass().getMethod(METHOD_NAME_PREFIX +
StringUtils.capitalize(tmp), signature);
+ }
+
this.methodCache.put(name, signature, method);
}
@@ -214,14 +238,14 @@ public abstract class ActionEvent extend
String key = null;
// Loop through and find the button.
- for (Iterator<String> it = pp.keySet().iterator();
it.hasNext();)
+ for (String k : pp)
{
- key = it.next();
+ key = k;
if (key.startsWith(button))
{
if (considerKey(key, pp))
{
- theButton = formatString(key, pp);
+ theButton = key;
break;
}
}
@@ -229,19 +253,20 @@ public abstract class ActionEvent extend
if (theButton == null)
{
- theButton = DEFAULT_METHOD;
+ theButton = BUTTON + DEFAULT_METHOD;
key = null;
}
+ theButton = formatString(theButton, pp);
Method method = null;
try
{
- method = getMethod(theButton, signature);
+ method = getMethod(theButton, signature, pp);
}
catch (NoSuchMethodException e)
{
- method = getMethod(DEFAULT_METHOD, signature);
+ method = getMethod(DEFAULT_METHOD, signature, pp);
}
finally
{
@@ -289,7 +314,7 @@ public abstract class ActionEvent extend
* @param pp The parameter parser (for correct folding)
* @return A string with the method name in the proper case.
*/
- protected final String formatString(String input, ParameterParser pp)
+ protected String formatString(String input, ParameterParser pp)
{
String tmp = input;
@@ -298,18 +323,17 @@ public abstract class ActionEvent extend
tmp = input.toLowerCase();
// Chop off suffixes (for image type)
- input = (tmp.endsWith(".x") || tmp.endsWith(".y"))
+ String methodName = (tmp.endsWith(".x") ||
tmp.endsWith(".y"))
? input.substring(0, input.length() - 2)
: input;
- if (pp.getUrlFolding() !=
ParserService.URL_CASE_FOLDING_NONE)
+ if (pp.getUrlFolding() == URLCaseFolding.NONE)
{
- tmp =
input.toLowerCase().substring(BUTTON_LENGTH + METHOD_NAME_LENGTH);
- tmp = METHOD_NAME_PREFIX +
StringUtils.capitalize(tmp);
+ tmp = methodName.substring(BUTTON_LENGTH);
}
else
{
- tmp = input.substring(BUTTON_LENGTH);
+ tmp = methodName.toLowerCase().substring(BUTTON_LENGTH);
}
}
Modified:
turbine/core/trunk/src/test/org/apache/turbine/modules/ActionLoaderTest.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/modules/ActionLoaderTest.java?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
---
turbine/core/trunk/src/test/org/apache/turbine/modules/ActionLoaderTest.java
(original)
+++
turbine/core/trunk/src/test/org/apache/turbine/modules/ActionLoaderTest.java
Tue Aug 12 12:40:41 2014
@@ -50,7 +50,7 @@ import static org.junit.Assert.*;
* properly bubbled up when action.event.bubbleexception=true. Or, if
* action.event.bubbleexception=false, then the exceptions should be logged and
* sunk.
- *
+ *
* Changes 2014/Jun/26 (gk): removed Constructor with String parameter as no
Test VelocityErrorScreenTest is found and JUnit does not allow it.
*
* @author <a href="mailto:[email protected]">Eric Pugh</a>
@@ -67,13 +67,13 @@ public class ActionLoaderTest extends Ba
/*
* @see TestCase#setUp()
*/
-
+
@BeforeClass
public static void init() {
tc = new TurbineConfig(".",
"/conf/test/CompleteTurbineResources.properties");
- tc.initialize();
+ tc.initialize();
}
-
+
@Before
public void setUpBefore() throws Exception
{
@@ -245,6 +245,41 @@ public class ActionLoaderTest extends Ba
}
}
+ /**
+ * This unit test verifies that if an Action Event doEventSubmit_ is
called,
+ * a properly annotated method is being called
+ *
+ * @throws Exception
+ * If something goes wrong with the unit test
+ */
+ @Test
+ public void testActionEventAnnotation() throws Exception
+ {
+ // can't seem to figure out how to setup the Mock Request with the
right
+ // parameters...
+ request.setupAddParameter("eventSubmit_annotatedEvent", "foo");
+ RunData data = getRunData(request, response, config);
+ PipelineData pipelineData = data;
+ data.setAction("VelocityActionDoesNothing");
+ data.getParameters().add("eventSubmit_annotatedEvent", "foo");
+
+ int numberOfCalls = VelocityActionDoesNothing.numberOfCalls;
+ int pipelineDataCalls = VelocityActionDoesNothing.pipelineDataCalls;
+ int actionEventCalls = VelocityActionDoesNothing.actionEventCalls;
+ try
+ {
+ ActionLoader.getInstance().exec(pipelineData, data.getAction());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ fail("Should not have thrown an exception.");
+ }
+ assertEquals(numberOfCalls + 1,
VelocityActionDoesNothing.numberOfCalls);
+ assertEquals(pipelineDataCalls,
VelocityActionDoesNothing.pipelineDataCalls);
+ assertEquals(actionEventCalls + 1,
VelocityActionDoesNothing.actionEventCalls);
+ }
+
@Test
public void testNonexistentActionCausesError() throws Exception
{
Modified:
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionDoesNothing.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionDoesNothing.java?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
---
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionDoesNothing.java
(original)
+++
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionDoesNothing.java
Tue Aug 12 12:40:41 2014
@@ -22,6 +22,7 @@ package org.apache.turbine.modules.actio
import static org.junit.Assert.*;
+import org.apache.turbine.annotation.TurbineActionEvent;
import org.apache.turbine.pipeline.PipelineData;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;
@@ -39,13 +40,16 @@ public class VelocityActionDoesNothing e
public static int numberOfCalls;
public static int runDataCalls;
public static int pipelineDataCalls;
+ public static int actionEventCalls;
/**
* Default action is throw an exception.
*
* @param data Current RunData information
* @param context Context to populate
* @exception Exception Thrown on error
+ * @deprecated
*/
+ @Deprecated
@Override
public void doPerform(RunData data, Context context) throws Exception
{
@@ -71,4 +75,20 @@ public class VelocityActionDoesNothing e
VelocityActionDoesNothing.pipelineDataCalls++;
}
+ /**
+ * Annotated action method.
+ *
+ * @param data Current RunData information
+ * @param context Context to populate
+ * @exception Exception Thrown on error
+ */
+ @TurbineActionEvent("annotatedEvent") // subject to URL folding
+ public void arbitraryMethodName(PipelineData pipelineData, Context
context) throws Exception
+ {
+ log.debug("Calling arbitraryMethodName(PipelineData)");
+ VelocityActionDoesNothing.numberOfCalls++;
+ RunData rd = (RunData)pipelineData;
+ assertNotNull("RunData object was Null.", rd);
+ VelocityActionDoesNothing.actionEventCalls++;
+ }
}
Modified:
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionThrowsException.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionThrowsException.java?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
---
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionThrowsException.java
(original)
+++
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionThrowsException.java
Tue Aug 12 12:40:41 2014
@@ -42,7 +42,10 @@ public class VelocityActionThrowsExcepti
* @param data Current RunData information
* @param context Context to populate
* @exception Exception Thrown on error
+ * @deprecated
*/
+ @Override
+ @Deprecated
public void doPerform(RunData data, Context context) throws Exception
{
log.debug("Calling doPerform(RunData)");
@@ -56,6 +59,7 @@ public class VelocityActionThrowsExcepti
* @param context Context to populate
* @exception Exception Thrown on error
*/
+ @Override
public void doPerform(PipelineData data, Context context) throws Exception
{
log.debug("Calling doPerform(PipelineData)");
Modified:
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionWithServiceInjection.java
URL:
http://svn.apache.org/viewvc/turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionWithServiceInjection.java?rev=1617460&r1=1617459&r2=1617460&view=diff
==============================================================================
---
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionWithServiceInjection.java
(original)
+++
turbine/core/trunk/src/test/org/apache/turbine/modules/actions/VelocityActionWithServiceInjection.java
Tue Aug 12 12:40:41 2014
@@ -53,7 +53,9 @@ public class VelocityActionWithServiceIn
* @param data Current RunData information
* @param context Context to populate
* @exception Exception Thrown on error
+ * @deprecated
*/
+ @Deprecated
@Override
public void doPerform(RunData data, Context context) throws Exception
{