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 2008/06/08 21:11:58 UTC
svn commit: r664538 - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/internal/services/
main/java/org/apache/tapestry5/internal/transform/
main/java/org/apache/tapestry5/services/ site/apt/ site/apt/guide/
test/app1/ tes...
Author: hlship
Date: Sun Jun 8 12:11:57 2008
New Revision: 664538
URL: http://svn.apache.org/viewvc?rev=664538&view=rev
Log:
TAPESTRY-2311: "Parents before Child" concept for Component Rendering does not allow different rendering in subclasses
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ConstructorArg.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InjectionKey.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
- copied, changed from r664019, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SimpleBeanSubclass.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java
- copied, changed from r664019, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorkerTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/OnEventWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/event.apt
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/rendering.apt
tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventHandlerDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ConstructorArg.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ConstructorArg.java?rev=664538&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ConstructorArg.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ConstructorArg.java Sun Jun 8 12:11:57 2008
@@ -0,0 +1,51 @@
+// Copyright 2008 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.services;
+
+import javassist.CtClass;
+import org.apache.tapestry5.ioc.internal.util.Defense;
+
+/**
+ * Stores transformation type data about one argument to a class constructor. Used with {@link
+ * org.apache.tapestry5.internal.services.InternalClassTransformation}.
+ */
+public class ConstructorArg
+{
+ private final CtClass type;
+
+ private final Object value;
+
+ /**
+ * Constructs new instance.
+ *
+ * @param type type of the parameter to be created (may not be null)
+ * @param value value to be injected via the constructor (may be null)
+ */
+ ConstructorArg(CtClass type, Object value)
+ {
+ this.type = Defense.notNull(type, "type");
+ this.value = value;
+ }
+
+ public CtClass getType()
+ {
+ return type;
+ }
+
+ public Object getValue()
+ {
+ return value;
+ }
+}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InjectionKey.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InjectionKey.java?rev=664538&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InjectionKey.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InjectionKey.java Sun Jun 8 12:11:57 2008
@@ -0,0 +1,63 @@
+// Copyright 2008 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.services;
+
+/**
+ * Used with {@link org.apache.tapestry5.internal.services.InternalClassTransformation} to search for prior injections
+ * of a give type and value. Assumes the values have a reasonable hashCode() implementation.
+ */
+public final class InjectionKey
+{
+ private final Class type;
+ private final Object value;
+
+ private final int hashCode;
+
+ public InjectionKey(Class type, Object value)
+ {
+ this.type = type;
+ this.value = value;
+
+ hashCode = type.hashCode() * 31 + value.hashCode();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return hashCode;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null) return false;
+
+ if (obj instanceof InjectionKey)
+ {
+ InjectionKey other = (InjectionKey) obj;
+
+ return type.equals(other.type) &&
+ value.equals(other.value);
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format("InjectionKey[%s %s]", type.getName(), value);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformation.java Sun Jun 8 12:11:57 2008
@@ -15,7 +15,6 @@
package org.apache.tapestry5.internal.services;
import javassist.CtClass;
-import org.apache.tapestry5.internal.util.MultiKey;
import org.apache.tapestry5.ioc.internal.util.IdAllocator;
import org.apache.tapestry5.model.MutableComponentModel;
import org.apache.tapestry5.services.ClassTransformation;
@@ -53,7 +52,7 @@
/**
* Returns a copy of the list of constructor arguments for this class.
*/
- List<InternalClassTransformationImpl.ConstructorArg> getConstructorArgs();
+ List<ConstructorArg> getConstructorArgs();
/**
* Searchs for an existing injection of an object, returning the name of the protected field into which the value
@@ -62,11 +61,16 @@
* TODO: Howard sayz: Uggh! At least define a real key (MultiKey is intended for internal use, never part of an
* API). Is this necessary? The cost of re-injection is tiny.
*/
- String searchForPreviousInjection(MultiKey key);
+ String searchForPreviousInjection(InjectionKey key);
InternalClassTransformation createChildTransformation(CtClass childClass, MutableComponentModel childModel);
/**
+ * Returns the parent transformation, or null for a root class.
+ */
+ InternalClassTransformation getParentTransformation();
+
+ /**
* Creates a new method by copying the body of an existing method. This is part of the scheme for providing method
* advice.
*
@@ -75,4 +79,12 @@
* @param newMethodName name of new method to create
*/
void copyMethod(TransformMethodSignature sourceMethod, int modifiers, String newMethodName);
+
+ /**
+ * Returns true if the provided signature is a method implemented by the transformed class.
+ *
+ * @param signature
+ * @return true if implemented
+ */
+ boolean isMethod(TransformMethodSignature signature);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/InternalClassTransformationImpl.java Sun Jun 8 12:11:57 2008
@@ -19,13 +19,9 @@
import javassist.expr.FieldAccess;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.internal.InternalComponentResources;
-import org.apache.tapestry5.internal.util.MultiKey;
import org.apache.tapestry5.ioc.internal.services.CtClassSource;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.*;
import org.apache.tapestry5.ioc.internal.util.Defense;
-import static org.apache.tapestry5.ioc.internal.util.Defense.notBlank;
-import static org.apache.tapestry5.ioc.internal.util.Defense.notNull;
import org.apache.tapestry5.ioc.internal.util.IdAllocator;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.services.ClassFab;
@@ -39,7 +35,6 @@
import org.apache.tapestry5.services.*;
import org.slf4j.Logger;
-import static java.lang.String.format;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.*;
@@ -64,23 +59,24 @@
private final IdAllocator idAllocator;
/**
- * Map, keyed on InjectKey, of field name.
+ * Map, keyed on InjectKey, of field name. Injections are always added as protected (not private) fields to support
+ * sharing of injections between a base class and a sub class.
*/
- private final Map<MultiKey, String> injectionCache = newMap();
+ private final Map<InjectionKey, String> injectionCache = CollectionFactory.newMap();
/**
* Map from a field to the annotation objects for that field.
*/
- private Map<String, List<Annotation>> fieldAnnotations = newMap();
+ private Map<String, List<Annotation>> fieldAnnotations = CollectionFactory.newMap();
/**
* Used to identify fields that have been "claimed" by other annotations.
*/
- private Map<String, Object> claimedFields = newMap();
+ private Map<String, Object> claimedFields = CollectionFactory.newMap();
- private Set<String> addedFieldNames = newSet();
+ private Set<String> addedFieldNames = CollectionFactory.newSet();
- private Set<CtBehavior> addedMethods = newSet();
+ private Set<CtBehavior> addedMethods = CollectionFactory.newSet();
// Cache of class annotation
@@ -88,9 +84,9 @@
// Cache of method annotation
- private Map<CtMethod, List<Annotation>> methodAnnotations = newMap();
+ private Map<CtMethod, List<Annotation>> methodAnnotations = CollectionFactory.newMap();
- private Map<CtMethod, TransformMethodSignature> methodSignatures = newMap();
+ private Map<CtMethod, TransformMethodSignature> methodSignatures = CollectionFactory.newMap();
private Map<TransformMethodSignature, InvocationBuilder> methodToInvocationBuilder = CollectionFactory.newMap();
@@ -133,29 +129,6 @@
null);
/**
- * Stores transformation type data about one argument to a class constructor.
- */
- static class ConstructorArg
- {
- private final CtClass type;
-
- private final Object value;
-
- /**
- * Constructs new instance.
- *
- * @param type type of the parameter to be created (may not be null)
- * @param value value to be injected via the constructor (may be null)
- */
- ConstructorArg(CtClass type, Object value)
- {
- this.type = Defense.notNull(type, "type");
- this.value = value;
- }
-
- }
-
- /**
* This is a constructor for a base class.
*/
public InternalClassTransformationImpl(ClassFactory classFactory, CtClass ctClass,
@@ -176,7 +149,7 @@
preloadMemberNames();
- constructorArgs = newList();
+ constructorArgs = CollectionFactory.newList();
constructor.append("{\n");
addImplementedInterface(Component.class);
@@ -285,7 +258,7 @@
void verifyFields()
{
- List<String> names = newList();
+ List<String> names = CollectionFactory.newList();
for (CtField field : ctClass.getDeclaredFields())
{
@@ -408,7 +381,7 @@
{
try
{
- List<Annotation> result = newList();
+ List<Annotation> result = CollectionFactory.newList();
addAnnotationsToList(result, member.getAnnotations());
@@ -445,7 +418,7 @@
{
failIfFrozen();
- String memberName = InternalUtils.createMemberName(notBlank(suggested, "suggested"));
+ String memberName = InternalUtils.createMemberName(Defense.notBlank(suggested, "suggested"));
return idAllocator.allocateId(memberName);
}
@@ -564,8 +537,8 @@
public void claimField(String fieldName, Object tag)
{
- notBlank(fieldName, "fieldName");
- notNull(tag, "tag");
+ Defense.notBlank(fieldName, "fieldName");
+ Defense.notNull(tag, "tag");
failIfFrozen();
@@ -947,7 +920,7 @@
{
failIfFrozen();
- List<String> result = newList();
+ List<String> result = CollectionFactory.newList();
try
{
@@ -977,7 +950,7 @@
{
failIfFrozen();
- List<TransformMethodSignature> result = newList();
+ List<TransformMethodSignature> result = CollectionFactory.newList();
for (CtMethod method : ctClass.getDeclaredMethods())
{
@@ -997,9 +970,9 @@
public List<TransformMethodSignature> findMethods(MethodFilter filter)
{
- notNull(filter, "filter");
+ Defense.notNull(filter, "filter");
- List<TransformMethodSignature> result = newList();
+ List<TransformMethodSignature> result = CollectionFactory.newList();
for (CtMethod method : ctClass.getDeclaredMethods())
{
@@ -1052,9 +1025,9 @@
{
failIfFrozen();
- List<String> names = newList();
+ List<String> names = CollectionFactory.newList();
- Set<String> skipped = newSet();
+ Set<String> skipped = CollectionFactory.newSet();
skipped.addAll(claimedFields.keySet());
skipped.addAll(addedFieldNames);
@@ -1173,11 +1146,11 @@
public String addInjectedField(Class type, String suggestedName, Object value)
{
- notNull(type, "type");
+ Defense.notNull(type, "type");
failIfFrozen();
- MultiKey key = new MultiKey(type, value);
+ InjectionKey key = new InjectionKey(type, value);
String fieldName = searchForPreviousInjection(key);
@@ -1221,7 +1194,7 @@
return fieldName;
}
- public String searchForPreviousInjection(MultiKey key)
+ public String searchForPreviousInjection(InjectionKey key)
{
String result = injectionCache.get(key);
@@ -1248,6 +1221,39 @@
builder.addAdvice(advice);
}
+ public boolean isMethodOverride(TransformMethodSignature methodSignature)
+ {
+ Defense.notNull(methodSignature, "methodSignature");
+
+ if (!isMethod(methodSignature))
+ throw new IllegalArgumentException(String.format("Method %s is not implemented by transformed class %s.",
+ methodSignature, getClassName()));
+
+ InternalClassTransformation search = parentTransformation;
+ while (search != null)
+ {
+ if (search.isMethod(methodSignature)) return true;
+
+ search = search.getParentTransformation();
+ }
+
+ // Not found in any super-class.
+
+ return false;
+ }
+
+ public InternalClassTransformation getParentTransformation()
+ {
+ return parentTransformation;
+ }
+
+ public boolean isMethod(TransformMethodSignature signature)
+ {
+ Defense.notNull(signature, "signature");
+
+ return findDeclaredMethod(signature) != null;
+ }
+
/**
* Adds a parameter to the constructor for the class; the parameter is used to initialize the value for a field.
*
@@ -1259,12 +1265,12 @@
{
constructorArgs.add(new ConstructorArg(fieldType, value));
- extendConstructor(format(" %s = $%d;", fieldName, constructorArgs.size()));
+ extendConstructor(String.format(" %s = $%d;", fieldName, constructorArgs.size()));
}
public void injectField(String fieldName, Object value)
{
- notNull(fieldName, "fieldName");
+ Defense.notNull(fieldName, "fieldName");
failIfFrozen();
@@ -1325,7 +1331,7 @@
{
ConstructorArg arg = constructorArgs.get(i);
- types[i] = arg.type;
+ types[i] = arg.getType();
}
// Add a call to the initializer; the method converted fromt the classes default
@@ -1343,6 +1349,7 @@
try
{
CtConstructor cons = CtNewConstructor.make(types, null, constructorBody, ctClass);
+
ctClass.addConstructor(cons);
}
catch (CannotCompileException ex)
@@ -1403,7 +1410,7 @@
{
ConstructorArg arg = constructorArgs.get(i);
- CtClass argCtType = arg.type;
+ CtClass argCtType = arg.getType();
Class argType = toClass(argCtType.getName());
boolean primitive = argCtType.isPrimitive();
@@ -1413,7 +1420,7 @@
String fieldName = "_param_" + i;
constructorParameterTypes[i + 1] = argType;
- constructorParameterValues[i + 1] = arg.value;
+ constructorParameterValues[i + 1] = arg.getValue();
cf.addField(fieldName, fieldType);
@@ -1489,7 +1496,7 @@
private void assembleClassAnnotations()
{
- classAnnotations = newList();
+ classAnnotations = CollectionFactory.newList();
try
{
@@ -1553,7 +1560,7 @@
String message = ServicesMessages.readOnlyField(ctClass.getName(), fieldName);
- String body = format("throw new java.lang.RuntimeException(\"%s\");", message);
+ String body = String.format("throw new java.lang.RuntimeException(\"%s\");", message);
addMethod(sig, body);
@@ -1566,7 +1573,7 @@
// TODO: We could check that there's an existing field read and field write transform ...
- if (removedFieldNames == null) removedFieldNames = newSet();
+ if (removedFieldNames == null) removedFieldNames = CollectionFactory.newSet();
removedFieldNames.add(fieldName);
@@ -1579,7 +1586,7 @@
String body = String.format("$_ = $0.%s();", methodName);
- if (fieldReadTransforms == null) fieldReadTransforms = newMap();
+ if (fieldReadTransforms == null) fieldReadTransforms = CollectionFactory.newMap();
// TODO: Collisions?
@@ -1595,7 +1602,7 @@
String body = String.format("$0.%s($1);", methodName);
- if (fieldWriteTransforms == null) fieldWriteTransforms = newMap();
+ if (fieldWriteTransforms == null) fieldWriteTransforms = CollectionFactory.newMap();
// TODO: Collisions?
@@ -1635,9 +1642,9 @@
// Provide empty maps here, to make the code in the inner class a tad
// easier.
- if (fieldReadTransforms == null) fieldReadTransforms = newMap();
+ if (fieldReadTransforms == null) fieldReadTransforms = CollectionFactory.newMap();
- if (fieldWriteTransforms == null) fieldWriteTransforms = newMap();
+ if (fieldWriteTransforms == null) fieldWriteTransforms = CollectionFactory.newMap();
ExprEditor editor = new ExprEditor()
{
@@ -1717,7 +1724,7 @@
public void extendConstructor(String statement)
{
- notNull(statement, "statement");
+ Defense.notNull(statement, "statement");
failIfFrozen();
@@ -1727,7 +1734,7 @@
public String getMethodIdentifier(TransformMethodSignature signature)
{
- notNull(signature, "signature");
+ Defense.notNull(signature, "signature");
CtMethod method = findMethod(signature);
@@ -1735,7 +1742,7 @@
CtClass enclosingClass = method.getDeclaringClass();
String sourceFile = enclosingClass.getClassFile2().getSourceFile();
- return format("%s.%s (at %s:%d)", enclosingClass.getName(), signature
+ return String.format("%s.%s (at %s:%d)", enclosingClass.getName(), signature
.getMediumDescription(), sourceFile, lineNumber);
}
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=664538&r1=664537&r2=664538&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 Sun Jun 8 12:11:57 2008
@@ -43,8 +43,18 @@
{
public boolean accept(TransformMethodSignature signature)
{
- return signature.getMethodName().startsWith("on") || transformation.getMethodAnnotation(signature,
- OnEvent.class) != null;
+ return (hasCorrectPrefix(signature) || hasAnnotation(signature)) &&
+ !transformation.isMethodOverride(signature);
+ }
+
+ private boolean hasCorrectPrefix(TransformMethodSignature signature)
+ {
+ return signature.getMethodName().startsWith("on");
+ }
+
+ private boolean hasAnnotation(TransformMethodSignature signature)
+ {
+ return transformation.getMethodAnnotation(signature, OnEvent.class) != null;
}
};
@@ -80,6 +90,7 @@
transformation.extendMethod(TransformConstants.DISPATCH_COMPONENT_EVENT, builder.toString());
}
+
private void addCodeForMethod(BodyBuilder builder, TransformMethodSignature method,
ClassTransformation transformation)
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PageLifecycleAnnotationWorker.java Sun Jun 8 12:11:57 2008
@@ -24,8 +24,8 @@
import java.lang.annotation.Annotation;
/**
- * Similar to {@link ComponentLifecycleMethodWorker} but applies to annotations/methods related to the overall page
- * lifecycle.
+ * Similar to {@link org.apache.tapestry5.internal.transform.RenderPhaseMethodWorker} but applies to annotations/methods
+ * related to the overall page lifecycle.
*/
public class PageLifecycleAnnotationWorker implements ComponentClassTransformWorker
{
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java (from r664019, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorker.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorker.java&r1=664019&r2=664538&rev=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java Sun Jun 8 12:11:57 2008
@@ -32,7 +32,7 @@
* Converts one of the methods of {@link org.apache.tapestry5.runtime.Component} into a chain of command that, itself,
* invokes certain methods (render phase methods) marked with an annotation, or named in a specific way.
*/
-public class ComponentLifecycleMethodWorker implements ComponentClassTransformWorker
+public class RenderPhaseMethodWorker implements ComponentClassTransformWorker
{
private static final String CHECK_ABORT_FLAG = "if ($2.isAborted()) return;";
@@ -54,8 +54,8 @@
* @param methodAnnotation the class of the corresponding annotation
* @param reverse if true, the normal method invocation order is reversed
*/
- public ComponentLifecycleMethodWorker(TransformMethodSignature lifecycleMethodSignature,
- Class<? extends Annotation> methodAnnotation, boolean reverse)
+ public RenderPhaseMethodWorker(TransformMethodSignature lifecycleMethodSignature,
+ Class<? extends Annotation> methodAnnotation, boolean reverse)
{
this.lifecycleMethodSignature = lifecycleMethodSignature;
this.methodAnnotation = methodAnnotation;
@@ -72,7 +72,7 @@
@Override
public String toString()
{
- return String.format("ComponentLifecycleMethodWorker[%s]", methodAnnotation.getName());
+ return String.format("RenderPhaseMethodWorker[%s]", methodAnnotation.getName());
}
public void transform(final ClassTransformation transformation, MutableComponentModel model)
@@ -82,8 +82,7 @@
public boolean accept(TransformMethodSignature signature)
{
// These methods get added to base classes and otherwise fall into this filter. If
- // we don't
- // include this filter, then we get endless loops.
+ // we don't include this filter, then we get endless loops.
if (signature.equals(lifecycleMethodSignature)) return false;
@@ -91,8 +90,18 @@
// annotation, say @AfterRender. In that case, this code is broken, as the method
// will be invoked for both phases!
- return signature.getMethodName().equals(lifecycleMethodName)
- || transformation.getMethodAnnotation(signature, methodAnnotation) != null;
+ return (correctName(signature) || correctAnnotation(signature)) &&
+ !transformation.isMethodOverride(signature);
+ }
+
+ private boolean correctAnnotation(TransformMethodSignature signature)
+ {
+ return transformation.getMethodAnnotation(signature, methodAnnotation) != null;
+ }
+
+ private boolean correctName(TransformMethodSignature signature)
+ {
+ return signature.getMethodName().equals(lifecycleMethodName);
}
};
@@ -145,6 +154,7 @@
transformation.addMethod(lifecycleMethodSignature, builder.toString());
}
+
private void addMethodCallToBody(BodyBuilder builder, TransformMethodSignature sig,
ClassTransformation transformation)
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ClassTransformation.java Sun Jun 8 12:11:57 2008
@@ -45,8 +45,7 @@
* any fields or methods inherited from a base class.
*
* @see org.apache.tapestry5.services.TapestryModule#contributeComponentClassTransformWorker(org.apache.tapestry5.ioc.OrderedConfiguration,
- * org.apache.tapestry5.ioc.ObjectLocator, InjectionProvider, Environment, ComponentClassResolver,
- * org.apache.tapestry5.internal.services.RequestPageCache, BindingSource)
+ * org.apache.tapestry5.ioc.ObjectLocator, InjectionProvider, ComponentClassResolver)
*/
public interface ClassTransformation extends AnnotationProvider
{
@@ -376,4 +375,12 @@
* Adds method advice for the indicated method.
*/
void advise(TransformMethodSignature methodSignature, ComponentMethodAdvice advice);
+
+ /**
+ * Returns true if the method is an override of a method from the parent class.
+ *
+ * @param methodSignature signature of method to check
+ * @return true if the parent class contains a method with the name signature
+ */
+ boolean isMethodOverride(TransformMethodSignature methodSignature);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Sun Jun 8 12:11:57 2008
@@ -734,7 +734,7 @@
String name = annotationClass.getSimpleName();
- configuration.add(name, new ComponentLifecycleMethodWorker(signature, annotationClass, reverse));
+ configuration.add(name, new RenderPhaseMethodWorker(signature, annotationClass, reverse));
}
// ========================================================================
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/event.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/event.apt?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/event.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/event.apt Sun Jun 8 12:11:57 2008
@@ -34,7 +34,7 @@
Tapestry 5 introduces the concept of <event handler methods>, identified via a naming convention, or
via the
{{{../../apidocs/org/apache/tapestry5/annotations/OnEvent.html}OnEvent annotation}}. Event handler methods
- have any visibility, even private (normally they are given package private visibility, to support testing).
+ may have any visibility, even private. Normally they are given package private visibility, to support testing.
Rather than configure a component to invoke a particular method, you identify one or more
methods to listen for events from that component. A single event handler method may receive notifications from
@@ -63,11 +63,12 @@
When there are additional context values, they are appended to the path.
This demonstrates a critical difference between Tapestry and a more traditional, action oriented framework.
- This URL doesn't say what happens when the link is clicked, it identifies <which component is responsible>.
+ This URL doesn't say what happens when the link is clicked, it identifies <which component is responsible>
+ when the link is clicked.
There's no simple mapping from URL to a piece of code; instead the component sends notifications, in the form
- of invocations of event handler methods, and Tapestry ensures that the correct bit of code, that you supply,
- gts invoked.
+ of invocations of event handler methods, and Tapestry ensures that the correct bit of code, code that you supply,
+ gets invoked.
A Java method can be invoked when the link for the component is clicked by the user:
@@ -89,7 +90,7 @@
[]
In the above example, the valueChosen() method will be invoked on the default event, "action", that originates
- in component <<<choose>>> (and has at least one context value).
+ in component <<<select>>> (and has at least one context value).
Some components can emit more than one type of event, in which case you will want to be more specific:
@@ -118,7 +119,7 @@
they were annotated.
This style of event handler methods start with the prefix "on", followed by the name of the action. You may then continue by adding "From" and
- a capitalized component id.
+ a capitalized component id (remember that Tapestry is case insensitive about event names and component ids).
The previous example may be rewritten as:
@@ -133,7 +134,8 @@
Event Handler Method Return Values
- For page navigation events, the value returned from an event handler method {{{pagenav.html}determines how Tapestry will render a response}}.
+ For page navigation events (originating in components such as ActionLink and Form),
+ the value returned from an event handler method {{{pagenav.html}determines how Tapestry will render a response}}.
Multiple Method Matches
@@ -151,6 +153,10 @@
There's only rare cases where it makes sense for more than one method to handle an event.
+ When a sub-class overrides an event handler method of a base class, the event handler method is only invoked once, along with
+ any other base class methods. The subclass can change the <implementation> of the base class method via an override, but
+ can't change the <timing> of when that method is invoked. See {{{https://issues.apache.org/jira/browse/TAPESTRY-2311}TAPESTRY-2311}}.
+
Event Context
The context values (the context parameter to the ActionLink component) can be any object.
@@ -178,7 +184,7 @@
* Collections
To designate that an event handler method should be invoked regardless of how many context parameters are available,
- change the method to accept a <single> parameter of type Object[], type List, or
+ change the method to accept a <single> parameter of type Object[], type List, or type
{{{../../apidocs/org/apache/tapestry5/EventContext.html}EventContext}}.
Event Bubbling
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/rendering.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/rendering.apt?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/rendering.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/rendering.apt Sun Jun 8 12:11:57 2008
@@ -299,7 +299,12 @@
Ordering is always parent-first. Methods defined in the parent class are always invoked
before methods defined in the child class.
-
+
+ When a sub-class overrides an render phase method of a base class, the
+ method is only invoked once, along with
+ any other base class methods. The subclass can change the <implementation> of the base class method via an override, but
+ can't change the <timing> of when that method is invoked. See {{{https://issues.apache.org/jira/browse/TAPESTRY-2311}TAPESTRY-2311}}.
+
* Reverse Ordering for AfterXXX and CleanupRender
The After<XXX> phases exists to balance the Begin<XXX> and Before<XXX> phases. Often elements will
Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt Sun Jun 8 12:11:57 2008
@@ -12,6 +12,12 @@
You should also check the {{{../release-notes.html}project-wide release notes}} for information
about bugs fixes and other improvements.
+Release 5.0.13
+
+ As part of {{{https://issues.apache.org/jira/browse/TAPESTRY-2311}TAPESTRY-2311}}, there have been
+ subtle changes to how event handler and render phase methods are invoked, when the methods are
+ overrides of base class methods.
+
Release 5.0.12
* ReorderProperties annotation
@@ -23,9 +29,11 @@
* {{{https://issues.apache.org/jira/browse/TAPESTRY-2421}TAPESTRY-2421}}
- To enable deployment compatibility between Tapestry 4 and Tapestry 5, a
- small number of classes
- had to be renamed or refactored.
+ The root package for all Tapestry code was changed from
+ org.apache.tapestry to org.apache.tapestry<<5>>. This will make it reasonable to deploy Tapestry 3 or Tapestry 4
+ applications side-by-side with a Tapestry 5 application.
+
+ In addition, a number of classes were refactored.
PageRenderSupport has been renamed to just
{{{../apidocs/org/apache/tapestry5/RenderSupport.html}RenderSupport}}.
@@ -37,18 +45,6 @@
{{{../apidocs/org/apache/tapestry5/MarkupUtils.html}MarkupUtils}} and
{{{../apidocs/org/apache/tapestry5/VersionUtils.html}VersionUtils}}.
- Because of naming conflicts, several classes and interfaces were moved under an
- org.apache.tapestry5 package:
-
- * {{{../apidocs/org/apache/tapestry5/services/ApplicationInitializer.html}ApplicationInitializer}} and
- {{{../apidocs/org/apache/tapestry5/services/ApplicationInitializerFilter.html}ApplicationInitializerFilter}}.
-
- * {{{../apidocs/org/apache/tapestry5/services/ComponentMessagesSource.html}ComponentMessagesSource}}.
-
- * {{{../apidocs/org/apache/tapestry5/services/RequestGlobals.html}RequestGlobals}}.
-
- * {{{../apidocs/org/apache/tapestry5/json/JSONObject.html}JSONObject}} (and the other JSON classes).
-
[]
* TapestryModule
@@ -74,7 +70,7 @@
* Loop element parameter
- The Loop components' elementName parameter was renamed to simply element (to be consistent
+ The Loop component's elementName parameter was renamed to simply element (to be consistent
with element parameters added to the Any and FormInjector components).
Release 5.0.11
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventHandlerDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventHandlerDemo.tml?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventHandlerDemo.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventHandlerDemo.tml Sun Jun 8 12:11:57 2008
@@ -1,29 +1,32 @@
<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
- <h1>EventHandler Demo</h1>
+ <h1>EventHandler Demo</h1>
- <t:if test="methodNames">
- <p> Event method names: ${methodNames} </p>
- </t:if>
-
-
- <p> [<t:pagelink page="eventhandlerdemo" context="'anything'">clear</t:pagelink>] </p>
-
-
- <ul>
- <li>
- <t:actionlink t:id="wilma">No Context</t:actionlink>
- </li>
- <li>
- <t:actionlink t:id="barney" context="literal:one">Single context value</t:actionlink>
- </li>
- <li>
- <t:actionlink t:id="betty" context="twoContext">Two value context</t:actionlink>
- </li>
- <li>
- <t:actionlink context="'two'" t:id="fred">Two value context (from fred)</t:actionlink>
- </li>
- </ul>
+ <t:if test="methodNames">
+ <p>Event method names:
+ <span id="methodNames">${methodNames}</span>
+ </p>
+ </t:if>
+
+
+ <p>[<t:pagelink page="eventhandlerdemo" context="'anything'">clear</t:pagelink>]
+ </p>
+
+
+ <ul>
+ <li>
+ <t:actionlink t:id="wilma">No Context</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink t:id="barney" context="literal:one">Single context value</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink t:id="betty" context="twoContext">Two value context</t:actionlink>
+ </li>
+ <li>
+ <t:actionlink context="'two'" t:id="fred">Two value context (from fred)</t:actionlink>
+ </li>
+ </ul>
</html>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Sun Jun 8 12:11:57 2008
@@ -885,25 +885,26 @@
clickAndWait(clear);
clickAndWait("link=No Context");
- assertTextPresent(
- "[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild(), child.onAction()]");
+ assertText("methodNames",
+ "[parent.eventHandlerZero(), parent.onAction(), child.eventHandlerZeroChild()]");
clickAndWait(clear);
clickAndWait("link=Single context value");
- assertTextPresent(
- "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction()]");
+ assertText("methodNames",
+ "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild()]");
clickAndWait(clear);
clickAndWait("link=Two value context");
- assertTextPresent(
- "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction()]");
+
+ assertText("methodNames",
+ "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerOneChild(), child.eventHandlerZeroChild()]");
clickAndWait(clear);
clickAndWait("link=Two value context (from fred)");
- assertTextPresent(
- "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerForFred(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onAction(String), child.onAction(), child.onActionFromFred(String), child.onActionFromFred()]");
+ assertText("methodNames",
+ "[parent.eventHandlerOne(String), parent.eventHandlerZero(), parent.onAction(String), parent.onAction(), child.eventHandlerForFred(), child.eventHandlerOneChild(), child.eventHandlerZeroChild(), child.onActionFromFred(String), child.onActionFromFred()]");
}
@Test
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java?rev=664538&r1=664537&r2=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/InternalClassTransformationImplTest.java Sun Jun 8 12:11:57 2008
@@ -171,11 +171,16 @@
{
CtClass ctClass = findCtClass(targetClass);
- MutableComponentModel model = new MutableComponentModelImpl("unknown-class", logger, null, null);
+ MutableComponentModel model = stubMutableComponentModel(logger);
return new InternalClassTransformationImpl(classFactory, ctClass, null, model, null);
}
+ private MutableComponentModel stubMutableComponentModel(Logger logger)
+ {
+ return new MutableComponentModelImpl("unknown-class", logger, null, null);
+ }
+
@Test
public void find_annotation_on_unknown_field() throws Exception
{
@@ -1169,5 +1174,84 @@
verify();
}
+ @Test
+ public void base_class_methods_are_never_overridden() throws Exception
+ {
+ Logger logger = mockLogger();
+
+ replay();
+
+ MethodFilter filter = new MethodFilter()
+ {
+ public boolean accept(TransformMethodSignature signature)
+ {
+ return true;
+ }
+ };
+
+ ClassTransformation ct = createClassTransformation(SimpleBean.class, logger);
+
+ List<TransformMethodSignature> methods = ct.findMethods(filter);
+
+ assertFalse(methods.isEmpty());
+
+ for (TransformMethodSignature sig : methods)
+ {
+ assertFalse(ct.isMethodOverride(sig));
+ }
+
+
+ verify();
+ }
+
+ @Test
+ public void check_for_method_override_on_non_declared_method() throws Exception
+ {
+ Logger logger = mockLogger();
+
+ replay();
+
+ ClassTransformation ct = createClassTransformation(SimpleBean.class, logger);
+
+ TransformMethodSignature sig = new TransformMethodSignature("methodDoesNotExist");
+
+ try
+ {
+ ct.isMethodOverride(sig);
+ unreachable();
+ }
+ catch (IllegalArgumentException ex)
+ {
+ assertEquals(ex.getMessage(),
+ "Method public void methodDoesNotExist() is not implemented by transformed class org.apache.tapestry5.internal.services.SimpleBean.");
+ }
+
+ verify();
+
+ }
+
+ @Test
+ public void check_for_overridden_methods() throws Exception
+ {
+ Logger logger = mockLogger();
+
+ replay();
+
+ InternalClassTransformation parentTransform = createClassTransformation(SimpleBean.class, logger);
+
+ parentTransform.finish();
+
+ CtClass childClass = findCtClass(SimpleBeanSubclass.class);
+
+ ClassTransformation childTransform = parentTransform.createChildTransformation(childClass,
+ stubMutableComponentModel(
+ logger));
+
+ assertFalse(childTransform.isMethodOverride(new TransformMethodSignature("notOverridden")));
+
+ assertTrue(childTransform.isMethodOverride(
+ new TransformMethodSignature(Modifier.PUBLIC, "void", "setAge", new String[] { "int" }, null)));
+ }
+
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SimpleBeanSubclass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SimpleBeanSubclass.java?rev=664538&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SimpleBeanSubclass.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/SimpleBeanSubclass.java Sun Jun 8 12:11:57 2008
@@ -0,0 +1,28 @@
+// Copyright 2008 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.services;
+
+public class SimpleBeanSubclass extends SimpleBean
+{
+ public void notOverridden()
+ {
+ }
+
+ @Override
+ public void setAge(int age)
+ {
+ super.setAge(age);
+ }
+}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java (from r664019, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorkerTest.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorkerTest.java&r1=664019&r2=664538&rev=664538&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/ComponentLifecycleMethodWorkerTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorkerTest.java Sun Jun 8 12:11:57 2008
@@ -27,7 +27,7 @@
* Of course, we're committing the cardinal sin of testing the code that's generated, rather than the *behavior* of the
* generated code. Fortunately, we back all this up with lots and lots of integration testing.
*/
-public class ComponentLifecycleMethodWorkerTest extends TapestryTestCase
+public class RenderPhaseMethodWorkerTest extends TapestryTestCase
{
@Test
public void no_methods_with_annotation()
@@ -43,7 +43,7 @@
replay();
- ComponentClassTransformWorker worker = new ComponentLifecycleMethodWorker(
+ ComponentClassTransformWorker worker = new RenderPhaseMethodWorker(
TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
worker.transform(tf, model);
@@ -61,7 +61,7 @@
replay();
- ComponentClassTransformWorker worker = new ComponentLifecycleMethodWorker(
+ ComponentClassTransformWorker worker = new RenderPhaseMethodWorker(
TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
worker.transform(tf, model);