You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2010/02/19 19:53:16 UTC
svn commit: r911910 - in
/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform:
BaseEventHandlerMethodInvoker.java EventHandlerMethodInvoker.java
EventHandlerMethodParameterSource.java OnEventWorker.java
Author: hlship
Date: Fri Feb 19 18:53:16 2010
New Revision: 911910
URL: http://svn.apache.org/viewvc?rev=911910&view=rev
Log:
Recode OnEventWorker using the new TransformMethod APIs
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java (with props)
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java?rev=911910&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java Fri Feb 19 18:53:16 2010
@@ -0,0 +1,82 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.internal.transform;
+
+import org.apache.tapestry5.internal.InternalConstants;
+import org.apache.tapestry5.runtime.ComponentEvent;
+import org.apache.tapestry5.services.MethodAccess;
+import org.apache.tapestry5.services.MethodInvocationResult;
+import org.apache.tapestry5.services.TransformMethod;
+
+/**
+ * Base class for invoking event handler methods that also serves when invoking an
+ * event handler method that takes no parameters.
+ *
+ * @since 5.2.0
+ */
+public class BaseEventHandlerMethodInvoker implements EventHandlerMethodInvoker
+{
+ private final MethodAccess access;
+
+ private final String identifier;
+
+ private final String eventType;
+
+ private final String componentId;
+
+ public BaseEventHandlerMethodInvoker(TransformMethod method, String eventType, String componentId)
+ {
+ this.eventType = eventType;
+ this.componentId = componentId;
+
+ access = method.getAccess();
+ identifier = method.getMethodIdentifier();
+ }
+
+ public void invokeEventHandlerMethod(ComponentEvent event, Object instance)
+ {
+ event.setMethodDescription(identifier);
+
+ MethodInvocationResult result = access.invoke(instance, constructParameters(event));
+
+ result.rethrow();
+
+ event.storeResult(result.getReturnValue());
+ }
+
+ public String getComponentId()
+ {
+ return componentId;
+ }
+
+ public String getEventType()
+ {
+ return eventType;
+ }
+
+ /**
+ * Returns 0 (the event method takes no parameters). Subclasses should override.
+ */
+ public int getMinContextValueCount()
+ {
+ return 0;
+ }
+
+ /** Overridden in subclasses to provide the actual values to be passed to the method. */
+ protected Object[] constructParameters(ComponentEvent event)
+ {
+ return InternalConstants.EMPTY_STRING_ARRAY;
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/BaseEventHandlerMethodInvoker.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java?rev=911910&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java Fri Feb 19 18:53:16 2010
@@ -0,0 +1,50 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.internal.transform;
+
+import org.apache.tapestry5.runtime.ComponentEvent;
+
+/**
+ * An object that can invoke an event handler method on a component instance.
+ *
+ * @since 5.2.0
+ */
+public interface EventHandlerMethodInvoker
+{
+ /**
+ * The type of event this method handles, i.e., "action".
+ */
+ String getEventType();
+
+ /**
+ * The id of the component this method should be invoked for, or
+ * the blank string to ignore component id when matching.
+ */
+ String getComponentId();
+
+ /**
+ * The minimum number of of context values needed. The method
+ * should be invoked if there are at least this number of
+ * context values.
+ */
+ int getMinContextValueCount();
+
+ /**
+ * Given an event and a component instance, invoke the component event method. The method
+ * is passed appropriate parameters. If the invocation throws a checked exception, then
+ * the exception is wrapped in a RuntimeException and rethrown.
+ */
+ void invokeEventHandlerMethod(ComponentEvent event, Object instance);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodInvoker.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java?rev=911910&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java Fri Feb 19 18:53:16 2010
@@ -0,0 +1,38 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.internal.transform;
+
+import org.apache.tapestry5.runtime.ComponentEvent;
+import org.apache.tapestry5.services.MethodAccess;
+
+/**
+ * Supplies one parameter value when invoking a component event handler method. In general,
+ * this involves extracting a value form the event's context and coercing it to a type
+ * appropriate to the parameter.
+ * <p>
+ * These values are accumulated and used to invoke the event handler method via
+ * {@link MethodAccess#invoke(Object, Object...)}.
+ *
+ * @since 5.2.0
+ */
+public interface EventHandlerMethodParameterSource
+{
+ /**
+ * Extract the value and coerce it to the correct type.
+ *
+ * @return value that can be passed as a method parameter
+ */
+ Object valueForEventHandlerMethodParameter(ComponentEvent event);
+}
Propchange: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/EventHandlerMethodParameterSource.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java?rev=911910&r1=911909&r2=911910&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java Fri Feb 19 18:53:16 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
//
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
// Licensed 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
+// 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,
@@ -14,228 +14,297 @@
package org.apache.tapestry5.internal.transform;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
import org.apache.tapestry5.EventContext;
import org.apache.tapestry5.annotations.OnEvent;
-import org.apache.tapestry5.ioc.util.BodyBuilder;
+import org.apache.tapestry5.ioc.Predicate;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.model.MutableComponentModel;
-import org.apache.tapestry5.services.*;
-
-import java.util.Arrays;
-import java.util.List;
+import org.apache.tapestry5.runtime.ComponentEvent;
+import org.apache.tapestry5.services.ClassTransformation;
+import org.apache.tapestry5.services.ComponentClassTransformWorker;
+import org.apache.tapestry5.services.ComponentMethodAdvice;
+import org.apache.tapestry5.services.ComponentMethodInvocation;
+import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformMethod;
/**
- * Provides implementations of the {@link org.apache.tapestry5.runtime.Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)}
+ * Provides implementations of the
+ * {@link org.apache.tapestry5.runtime.Component#dispatchComponentEvent(org.apache.tapestry5.runtime.ComponentEvent)}
* method, based on {@link org.apache.tapestry5.annotations.OnEvent} annotations.
*/
public class OnEventWorker implements ComponentClassTransformWorker
{
- static final String OBJECT_ARRAY_TYPE = "java.lang.Object[]";
+ /**
+ * Stores a couple of special parameter type mappings that are used when matching the entire event context
+ * (either as Object[] or EventContext).
+ */
+ private final Map<String, EventHandlerMethodParameterSource> parameterTypeToSource = CollectionFactory.newMap();
- static final String EVENT_CONTEXT_TYPE = EventContext.class.getName();
-
- static final String LIST_TYPE = List.class.getName();
-
- private final static int ANY_NUMBER_OF_PARAMETERS = -1;
-
- public void transform(final ClassTransformation transformation, MutableComponentModel model)
{
- MethodFilter filter = new MethodFilter()
+ // Object[] and List are out-dated and may be deprecated some day
+
+ parameterTypeToSource.put("java.lang.Object[]", new EventHandlerMethodParameterSource()
{
- public boolean accept(TransformMethodSignature signature)
- {
- return (hasCorrectPrefix(signature) || hasAnnotation(signature)) &&
- !transformation.isMethodOverride(signature);
- }
- private boolean hasCorrectPrefix(TransformMethodSignature signature)
+ public Object valueForEventHandlerMethodParameter(ComponentEvent event)
{
- return signature.getMethodName().startsWith("on");
+ return event.getContext();
}
+ });
+
+ parameterTypeToSource.put(List.class.getName(), new EventHandlerMethodParameterSource()
+ {
- private boolean hasAnnotation(TransformMethodSignature signature)
+ public Object valueForEventHandlerMethodParameter(ComponentEvent event)
{
- return transformation.getMethodAnnotation(signature, OnEvent.class) != null;
+ return Arrays.asList(event.getContext());
}
- };
-
- List<TransformMethodSignature> methods = transformation.findMethods(filter);
-
- // No methods, no work.
+ });
- if (methods.isEmpty()) return;
-
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
-
- builder.addln("if ($1.isAborted()) return $_;");
-
- builder.addln("try");
- builder.begin();
+ // This is better, as the EventContext maintains the original objects (or strings)
+ // and gives the event handler method access with coercion
+ parameterTypeToSource.put(EventContext.class.getName(), new EventHandlerMethodParameterSource()
+ {
- for (TransformMethodSignature method : methods)
- addCodeForMethod(builder, method, transformation, model);
+ public Object valueForEventHandlerMethodParameter(ComponentEvent event)
+ {
+ return event.getEventContext();
+ }
+ });
+ }
- builder.end(); // try
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ List<TransformMethod> methods = matchEventHandlerMethods(transformation);
- // Runtime exceptions pass right through.
+ if (methods.isEmpty())
+ return;
- builder.addln("catch (RuntimeException ex) { throw ex; }");
+ List<EventHandlerMethodInvoker> invokers = toInvokers(methods);
- // Wrap others in a RuntimeException to communicate them up.
+ updateModelWithHandledEvents(model, invokers);
- builder.addln("catch (Exception ex) { throw new RuntimeException(ex); } ");
+ adviseDispatchComponentEventMethod(transformation, invokers);
+ }
- builder.end();
+ private void adviseDispatchComponentEventMethod(ClassTransformation transformation,
+ List<EventHandlerMethodInvoker> invokers)
+ {
+ ComponentMethodAdvice advice = createDispatchComponentEventAdvice(invokers);
- transformation.extendMethod(TransformConstants.DISPATCH_COMPONENT_EVENT, builder.toString());
+ transformation.getMethod(TransformConstants.DISPATCH_COMPONENT_EVENT).addAdvice(advice);
}
-
- private void addCodeForMethod(BodyBuilder builder, TransformMethodSignature method,
- ClassTransformation transformation, MutableComponentModel model)
+ private ComponentMethodAdvice createDispatchComponentEventAdvice(final List<EventHandlerMethodInvoker> invokers)
{
- // $1 is the event
-
- int parameterCount = getParameterCount(method);
+ return new ComponentMethodAdvice()
+ {
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ // Invoke the super-class implementation first. If no super-class,
+ // this will do nothing and return false.
- OnEvent annotation = transformation.getMethodAnnotation(method, OnEvent.class);
+ invocation.proceed();
- String eventType = extractEventType(method, annotation);
+ ComponentEvent event = (ComponentEvent) invocation.getParameter(0);
- String componentId = extractComponentId(method, annotation);
+ if (invokeEventHandlers(event, invocation.getInstance()))
+ invocation.overrideResult(true);
+ }
+ private boolean invokeEventHandlers(ComponentEvent event, Object instance)
+ {
+ // If the super-class aborted the event (some super-class method return non-null),
+ // then it's all over, don't even check for handlers in this class.
- builder.addln("if ($1.matches(\"%s\", \"%s\", %d))", eventType, componentId, parameterCount);
- builder.begin();
+ if (event.isAborted())
+ return false;
- // Ensure that we return true, because *some* event handler method was invoked,
- // even if it chose not to abort the event.
+ boolean didInvokeSomeHandler = false;
- builder.addln("$_ = true;");
+ for (EventHandlerMethodInvoker invoker : invokers)
+ {
+ if (event.matches(invoker.getEventType(), invoker.getComponentId(), invoker
+ .getMinContextValueCount()))
+ {
+ didInvokeSomeHandler = true;
- builder.addln("$1.setMethodDescription(\"%s\");", transformation.getMethodIdentifier(method));
+ invoker.invokeEventHandlerMethod(event, instance);
- boolean isNonVoid = !method.getReturnType().equals("void");
+ if (event.isAborted())
+ break;
+ }
+ }
- // Store the result, converting primitives to wrappers automatically.
+ return didInvokeSomeHandler;
+ }
+ };
+ }
- if (isNonVoid) builder.add("if ($1.storeResult(($w) ");
+ private void updateModelWithHandledEvents(MutableComponentModel model,
+ final List<EventHandlerMethodInvoker> invokers)
+ {
+ for (EventHandlerMethodInvoker invoker : invokers)
+ {
+ model.addEventHandler(invoker.getEventType());
+ }
+ }
- builder.add("%s(", method.getMethodName());
+ private List<TransformMethod> matchEventHandlerMethods(ClassTransformation transformation)
+ {
+ return transformation.matchMethods(new Predicate<TransformMethod>()
+ {
+ public boolean accept(TransformMethod method)
+ {
+ return (hasCorrectPrefix(method) || hasAnnotation(method)) && !method.isOverride();
+ }
- buildMethodParameters(builder, method);
+ private boolean hasCorrectPrefix(TransformMethod method)
+ {
+ return method.getSignature().getMethodName().startsWith("on");
+ }
- if (isNonVoid) builder.addln("))) return true;");
- else builder.addln(");");
+ private boolean hasAnnotation(TransformMethod method)
+ {
+ return method.getAnnotation(OnEvent.class) != null;
+ }
+ });
+ }
- builder.end();
+ private List<EventHandlerMethodInvoker> toInvokers(List<TransformMethod> methods)
+ {
+ List<EventHandlerMethodInvoker> result = CollectionFactory.newList();
- // Indicate that the eventType is handled.
+ for (TransformMethod method : methods)
+ {
+ result.add(toInvoker(method));
+ }
- model.addEventHandler(eventType);
+ return result;
}
- private String extractComponentId(TransformMethodSignature method, OnEvent annotation)
+ private EventHandlerMethodInvoker toInvoker(TransformMethod method)
{
- if (annotation != null) return annotation.component();
-
- // Method name started with "on". Extract the component id, if present.
-
- String name = method.getMethodName();
+ OnEvent annotation = method.getAnnotation(OnEvent.class);
- int fromx = name.indexOf("From");
+ String methodName = method.getSignature().getMethodName();
- if (fromx < 0) return "";
+ String eventType = extractEventType(methodName, annotation);
+ String componentId = extractComponentId(methodName, annotation);
- return name.substring(fromx + 4);
- }
+ String[] parameterTypes = method.getSignature().getParameterTypes();
- private String extractEventType(TransformMethodSignature method, OnEvent annotation)
- {
- if (annotation != null) return annotation.value();
+ if (parameterTypes.length == 0)
+ return new BaseEventHandlerMethodInvoker(method, eventType, componentId);
- // Method name started with "on". Extract the event type.
+ final List<EventHandlerMethodParameterSource> sources = CollectionFactory.newList();
- String name = method.getMethodName();
+ // I'd refactor a bit more of this if Java had covariant return types.
- int fromx = name.indexOf("From");
+ int contextIndex = 0;
+ boolean catchAll = false;
- return fromx == -1 ? name.substring(2) : name.substring(2, fromx);
- }
+ for (final String type : parameterTypes)
+ {
+ EventHandlerMethodParameterSource source = parameterTypeToSource.get(type);
- private int getParameterCount(TransformMethodSignature method)
- {
- String[] types = method.getParameterTypes();
+ if (source != null)
+ {
+ sources.add(source);
+ catchAll = true;
+ continue;
+ }
- if (types.length == 0) return 0;
+ // Note: probably safe to do the conversion to Class early (class load time)
+ // as parameters are rarely (if ever) component classes.
- if (types.length == 1)
- {
- String soloType = types[0];
+ final int parameterIndex = contextIndex++;
- if (soloType.equals(OBJECT_ARRAY_TYPE) || soloType.equals(EVENT_CONTEXT_TYPE) || soloType.equals(LIST_TYPE))
- return ANY_NUMBER_OF_PARAMETERS;
+ sources.add(createParameterSource(type, parameterIndex));
}
- return types.length;
+ int minContextCount = catchAll ? 0 : contextIndex;
+
+ return createInvoker(method, eventType, componentId, minContextCount, sources);
}
- private void buildMethodParameters(BodyBuilder builder, TransformMethodSignature method)
+ private EventHandlerMethodInvoker createInvoker(TransformMethod method, String eventType, String componentId,
+ final int minContextCount, final List<EventHandlerMethodParameterSource> sources)
{
- int contextIndex = 0;
-
- for (int i = 0; i < method.getParameterTypes().length; i++)
+ return new BaseEventHandlerMethodInvoker(method, eventType, componentId)
{
- if (i > 0) builder.add(", ");
-
- String type = method.getParameterTypes()[i];
+ final int count = sources.size();
- // Type Object[] is a special case, it gets all of the context parameters in one go.
-
- if (type.equals(OBJECT_ARRAY_TYPE))
+ @Override
+ public int getMinContextValueCount()
{
- builder.add("$1.getContext()");
- continue;
+ return minContextCount;
}
- // Added for TAPESTRY-2177
-
- if (type.equals(EVENT_CONTEXT_TYPE))
+ @Override
+ protected Object[] constructParameters(ComponentEvent event)
{
- builder.add("$1.getEventContext()");
- continue;
- }
+ Object[] parameters = new Object[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ parameters[i] = sources.get(i).valueForEventHandlerMethodParameter(event);
+ }
- // Added for TAPESTRY-1999
+ return parameters;
+ }
+ };
+ }
- if (type.equals(LIST_TYPE))
+ private EventHandlerMethodParameterSource createParameterSource(final String type, final int parameterIndex)
+ {
+ return new EventHandlerMethodParameterSource()
+ {
+ public Object valueForEventHandlerMethodParameter(ComponentEvent event)
{
- builder.add("%s.asList($1.getContext())", Arrays.class.getName());
- continue;
+ return event.coerceContext(parameterIndex, type);
}
+ };
+ }
- boolean isPrimitive = TransformUtils.isPrimitive(type);
- String wrapperType = TransformUtils.getWrapperTypeName(type);
+ /**
+ * Returns the component id to match against, or the empty
+ * string if the component id is not specified. The component id
+ * is provided by the OnEvent annotation or (if that is not present)
+ * by the part of the method name following "From" ("onActionFromFoo").
+ */
+ private String extractComponentId(String methodName, OnEvent annotation)
+ {
+ if (annotation != null)
+ return annotation.component();
- // Add a cast to the wrapper type up front
+ // Method name started with "on". Extract the component id, if present.
- if (isPrimitive) builder.add("(");
+ int fromx = methodName.indexOf("From");
- // A cast is always needed (i.e. from java.lang.Object to, say, java.lang.String, etc.).
- // The wrapper type will be the actual type unless its a primitive, in which case it
- // really will be the wrapper type.
+ if (fromx < 0)
+ return "";
- builder.add("(%s)", wrapperType);
+ return methodName.substring(fromx + 4);
+ }
- // The strings for desired type name will likely repeat a bit; it may be
- // worth it to inject them as final fields. Could increase the number
- // of constructor parameters pretty dramatically, however, and will reduce
- // the readability of the output method bodies.
+ /**
+ * Returns the event name to match against, as specified in the annotation
+ * or (if the annotation is not present) extracted from the name of the method.
+ * "onActionFromFoo" or just "onAction".
+ */
+ private String extractEventType(String methodName, OnEvent annotation)
+ {
+ if (annotation != null)
+ return annotation.value();
- builder.add("$1.coerceContext(%d, \"%s\")", contextIndex++, wrapperType);
+ int fromx = methodName.indexOf("From");
- // and invoke a method on the cast value to get back to primitive
- if (isPrimitive) builder.add(").%s()", TransformUtils.getUnwrapperMethodName(type));
- }
+ // The first two characters are always "on" as in "onActionFromFoo".
+ return fromx == -1 ? methodName.substring(2) : methodName.substring(2, fromx);
}
}