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:54:29 UTC
svn commit: r911931 [2/3] - in /tapestry/tapestry5/trunk: src/site/apt/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/
tapestry-core/src/main/java/org/apache/tapestry5/internal/services/
tapestry-core/src/main/java/org/apache/tape...
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/ParameterWorker.java Fri Feb 19 18:54:27 2010
@@ -14,7 +14,6 @@
package org.apache.tapestry5.internal.transform;
-import java.util.Iterator;
import java.util.List;
import org.apache.tapestry5.Binding;
@@ -23,19 +22,14 @@
import org.apache.tapestry5.internal.InternalComponentResources;
import org.apache.tapestry5.internal.bindings.LiteralBinding;
import org.apache.tapestry5.internal.services.ComponentClassCache;
+import org.apache.tapestry5.ioc.Predicate;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.ioc.services.TypeCoercer;
import org.apache.tapestry5.model.MutableComponentModel;
-import org.apache.tapestry5.services.BindingSource;
-import org.apache.tapestry5.services.ClassTransformation;
-import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.ComponentDefaultProvider;
-import org.apache.tapestry5.services.ComponentValueProvider;
-import org.apache.tapestry5.services.MethodFilter;
-import org.apache.tapestry5.services.TransformConstants;
-import org.apache.tapestry5.services.TransformField;
-import org.apache.tapestry5.services.TransformMethodSignature;
+import org.apache.tapestry5.services.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Responsible for identifying parameters via the {@link org.apache.tapestry5.annotations.Parameter} annotation on
@@ -43,6 +37,69 @@
*/
public class ParameterWorker implements ComponentClassTransformWorker
{
+ private final Logger logger = LoggerFactory.getLogger(ParameterWorker.class);
+
+ private final class InvokeResetOnParameterConduit implements ComponentMethodAdvice
+ {
+ private final FieldAccess conduitAccess;
+
+ private InvokeResetOnParameterConduit(FieldAccess conduitAccess)
+ {
+ this.conduitAccess = conduitAccess;
+ }
+
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ getConduit(invocation, conduitAccess).reset();
+
+ invocation.proceed();
+ }
+ }
+
+ private final class InvokeParameterDefaultMethod implements ComponentMethodAdvice
+ {
+ private final FieldAccess conduitAccess;
+
+ private final MethodAccess defaultMethodAccess;
+
+ private InvokeParameterDefaultMethod(FieldAccess conduitAccess, MethodAccess defaultMethodAccess)
+ {
+ this.conduitAccess = conduitAccess;
+ this.defaultMethodAccess = defaultMethodAccess;
+ }
+
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ logger.debug(String.format("%s invoking default method %s", invocation.getComponentResources()
+ .getCompleteId(), defaultMethodAccess));
+
+ MethodInvocationResult result = defaultMethodAccess.invoke(invocation.getInstance());
+
+ result.rethrow();
+
+ getConduit(invocation, conduitAccess).setDefault(result.getReturnValue());
+
+ invocation.proceed();
+ }
+ }
+
+ private final class InvokeLoadOnParmeterConduit implements ComponentMethodAdvice
+ {
+ private final FieldAccess conduitAccess;
+
+ private InvokeLoadOnParmeterConduit(FieldAccess conduitAccess)
+ {
+ this.conduitAccess = conduitAccess;
+ }
+
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ getConduit(invocation, conduitAccess).load();
+
+ invocation.proceed();
+ }
+ }
+
private final ComponentClassCache classCache;
private final BindingSource bindingSource;
@@ -62,57 +119,90 @@
public void transform(ClassTransformation transformation, MutableComponentModel model)
{
- List<String> fieldNames = transformation.findFieldsWithAnnotation(Parameter.class);
+ transformFields(transformation, model, true);
+ transformFields(transformation, model, false);
+ }
- for (int pass = 0; pass < 2; pass++)
+ private void transformFields(ClassTransformation transformation, MutableComponentModel model, boolean principal)
+ {
+ for (TransformField field : matchParameterFields(transformation, principal))
{
- Iterator<String> i = fieldNames.iterator();
+ convertFieldIntoParameter(transformation, model, field);
+ }
+ }
- while (i.hasNext())
+ private List<TransformField> matchParameterFields(ClassTransformation transformation, final boolean principal)
+ {
+ Predicate<TransformField> predicate = new Predicate<TransformField>()
+ {
+ public boolean accept(TransformField field)
{
- String fieldName = i.next();
+ Parameter annotation = field.getAnnotation(Parameter.class);
+
+ return annotation != null && annotation.principal() == principal;
+ }
+ };
+
+ return transformation.matchFields(predicate);
+ }
- Parameter annotation = transformation
- .getFieldAnnotation(fieldName, Parameter.class);
+ private void convertFieldIntoParameter(ClassTransformation transformation, MutableComponentModel model,
+ TransformField field)
+ {
+ Parameter annotation = field.getAnnotation(Parameter.class);
- // Process the principal annotations on the first pass, handle the others
- // on the second pass.
+ String fieldType = field.getType();
- boolean process = pass == 0 ? annotation.principal() : true;
+ String parameterName = getParameterName(field.getName(), annotation.name());
- if (process)
- {
- convertFieldIntoParameter(fieldName, annotation, transformation, model);
+ field.claim(annotation);
- i.remove();
- }
- }
- }
+ model.addParameter(parameterName, annotation.required(), annotation.allowNull(), annotation.defaultPrefix(),
+ annotation.cache());
+
+ ComponentValueProvider<ParameterConduit> provider = createParameterConduitProvider(parameterName, fieldType,
+ annotation);
+
+ TransformField conduitField = transformation.addIndirectInjectedField(ParameterConduit.class, parameterName
+ + "$conduit", provider);
+
+ FieldAccess conduitAccess = conduitField.getAccess();
+ addCodeForParameterDefaultMethod(transformation, parameterName, conduitAccess);
+
+ field.replaceAccess(conduitField);
+
+ invokeLoadOnParameterConduitAtPageLoad(transformation, conduitAccess);
+
+ invokeResetOnParameterConduitAtPostRenderCleanup(transformation, conduitAccess);
}
- private void convertFieldIntoParameter(String fieldName, final Parameter annotation,
- ClassTransformation transformation, MutableComponentModel model)
+ private void invokeResetOnParameterConduitAtPostRenderCleanup(ClassTransformation transformation,
+ final FieldAccess conduitAccess)
{
- final String fieldTypeName = transformation.getFieldType(fieldName);
+ ComponentMethodAdvice advice = new InvokeResetOnParameterConduit(conduitAccess);
- final String parameterName = getParameterName(fieldName, annotation.name());
+ addMethodAdvice(transformation, TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, advice);
+ }
- final boolean enableCaching = annotation.cache();
+ private void addMethodAdvice(ClassTransformation transformation, TransformMethodSignature methodSignature,
+ ComponentMethodAdvice advice)
+ {
+ transformation.getOrCreateMethod(methodSignature).addAdvice(advice);
+ }
- model.addParameter(parameterName, annotation.required(), annotation.allowNull(), annotation
- .defaultPrefix(), enableCaching);
+ private void invokeLoadOnParameterConduitAtPageLoad(ClassTransformation transformation, FieldAccess conduitAccess)
+ {
+ ComponentMethodAdvice pageLoadAdvice = new InvokeLoadOnParmeterConduit(conduitAccess);
- transformation.claimField(fieldName, annotation);
+ addPageLoadAdvice(transformation, pageLoadAdvice);
+ }
- ComponentValueProvider<ParameterConduit> provider = new ComponentValueProvider<ParameterConduit>()
+ private ComponentValueProvider<ParameterConduit> createParameterConduitProvider(final String parameterName,
+ final String fieldTypeName, final Parameter annotation)
+ {
+ return new ComponentValueProvider<ParameterConduit>()
{
- // Invoked from the components' constructor. This causes a few issues (it would be
- // better
- // if there was a way to defer until the component's page loaded lifecycle method). The
- // issues
- // are addressed by deferring some behaviors until the load() method.
-
public ParameterConduit get(ComponentResources resources)
{
final InternalComponentResources icr = (InternalComponentResources) resources;
@@ -130,7 +220,7 @@
// Default value for parameter, computed *once* at
// page load time.
- private Object defaultValue;
+ private Object defaultValue = classCache.defaultValueForType(fieldTypeName);
private Binding parameterBinding;
@@ -142,17 +232,9 @@
// value field?
private boolean cached = false;
- // If the field is a primitive type, set its default value to false
- // or zero. For non-primitives, null until we know better.
-
{
- Class javaType = classCache.forName(fieldTypeName);
-
- if (javaType.isPrimitive())
- {
- // Reminder: 0 coerces to false
- defaultValue = typeCoercer.coerce(0l, javaType);
- }
+ // Inform the ComponentResources about the parameter conduit, so it can be
+ // shared with mixins.
icr.setParameterConduit(parameterName, this);
}
@@ -170,6 +252,7 @@
if (!loaded)
{
+ value = newValue;
defaultValue = newValue;
return;
}
@@ -182,10 +265,10 @@
// If caching is enabled for the parameter (the typical case) and the
// component is currently rendering, then the result
- // can be cached in the ParameterConduit (until the component finishes
+ // can be cached in this ParameterConduit (until the component finishes
// rendering).
- cached = enableCaching && icr.isRendering();
+ cached = annotation.cache() && icr.isRendering();
}
private Object readFromBinding()
@@ -200,10 +283,9 @@
}
catch (RuntimeException ex)
{
- throw new TapestryException(String
- .format("Failure reading parameter '%s' of component %s: %s",
- parameterName, icr.getCompleteId(), InternalUtils
- .toMessage(ex)), parameterBinding, ex);
+ throw new TapestryException(String.format(
+ "Failure reading parameter '%s' of component %s: %s", parameterName, icr
+ .getCompleteId(), InternalUtils.toMessage(ex)), parameterBinding, ex);
}
if (result != null || annotation.allowNull())
@@ -213,8 +295,7 @@
String
.format(
"Parameter '%s' of component %s is bound to null. This parameter is not allowed to be null.",
- parameterName, icr.getCompleteId()),
- parameterBinding, null);
+ parameterName, icr.getCompleteId()), parameterBinding, null);
}
@SuppressWarnings("unchecked")
@@ -228,17 +309,15 @@
try
{
- Object coerced = typeCoercer.coerce(newValue, parameterBinding
- .getBindingType());
+ Object coerced = typeCoercer.coerce(newValue, parameterBinding.getBindingType());
parameterBinding.set(coerced);
}
catch (RuntimeException ex)
{
- throw new TapestryException(String
- .format("Failure writing parameter '%s' of component %s: %s",
- parameterName, icr.getCompleteId(), InternalUtils
- .toMessage(ex)), icr, ex);
+ throw new TapestryException(String.format(
+ "Failure writing parameter '%s' of component %s: %s", parameterName, icr
+ .getCompleteId(), InternalUtils.toMessage(ex)), icr, ex);
}
}
@@ -253,16 +332,24 @@
public void load()
{
+ logger.debug(String.format("%s loading parameter %s", icr.getCompleteId(), parameterName));
+
// If it's bound at this point, that's because of an explicit binding
// in the template or @Component annotation.
if (!icr.isBound(parameterName))
{
+ logger.debug(String.format("%s parameter %s not yet bound", icr.getCompleteId(),
+ parameterName));
+
// Otherwise, construct a default binding, or use one provided from
// the component.
Binding binding = getDefaultBindingForParameter();
+ logger.debug(String.format("%s parameter %s bound to default %s", icr.getCompleteId(),
+ parameterName, binding));
+
if (binding != null)
icr.bindParameter(parameterName, binding);
}
@@ -276,22 +363,6 @@
value = defaultValue;
}
- private Binding getDefaultBindingForParameter()
- {
- if (InternalUtils.isNonBlank(annotation.value()))
- return bindingSource.newBinding("default " + parameterName, icr,
- annotation.defaultPrefix(), annotation.value());
-
- if (annotation.autoconnect())
- return defaultProvider.defaultBinding(parameterName, icr);
-
- // Return (if not null) the binding from the setDefault() method which is
- // set via a default method on the component, or from the field's initial
- // value.
-
- return parameterBinding;
- }
-
public boolean isBound()
{
return parameterBinding != null;
@@ -313,7 +384,7 @@
// we may want to cache it for the remainder of the component render (if the
// component is currently rendering).
- if (invariant || (enableCaching && icr.isRendering()))
+ if (invariant || (annotation.cache() && icr.isRendering()))
{
value = result;
cached = true;
@@ -322,6 +393,22 @@
return result;
}
+ private Binding getDefaultBindingForParameter()
+ {
+ if (InternalUtils.isNonBlank(annotation.value()))
+ return bindingSource.newBinding("default " + parameterName, icr,
+ annotation.defaultPrefix(), annotation.value());
+
+ if (annotation.autoconnect())
+ return defaultProvider.defaultBinding(parameterName, icr);
+
+ // Return (if not null) the binding from the setDefault() method which is
+ // set via a default method on the component, or from the field's initial
+ // value.
+
+ return parameterBinding;
+ }
+
public void setDefault(Object value)
{
if (value == null)
@@ -333,59 +420,58 @@
return;
}
- parameterBinding = new LiteralBinding(null, "default " + parameterName,
- value);
+ parameterBinding = new LiteralBinding(null, "default " + parameterName, value);
}
};
}
-
};
+ }
- // This has to be done in the constructor, to handle any field initializations
-
- TransformField conduitField = transformation.addIndirectInjectedField(
- ParameterConduit.class, parameterName + "$conduit", provider);
-
- String conduitFieldName = conduitField.getName();
-
- addCodeForParameterDefaultMethod(transformation, parameterName, conduitFieldName);
-
- transformation.getField(fieldName).replaceAccess(conduitField);
-
- transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, String
- .format("%s.load();", conduitFieldName));
-
- transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, String
- .format("%s.reset();", conduitFieldName));
-
+ private ParameterConduit getConduit(ComponentMethodInvocation invocation, FieldAccess access)
+ {
+ return (ParameterConduit) access.read(invocation.getInstance());
}
- private void addCodeForParameterDefaultMethod(ClassTransformation transformation,
- final String parameterName, String conduitFieldName)
+ private void addCodeForParameterDefaultMethod(ClassTransformation transformation, final String parameterName,
+ final FieldAccess conduitAccess)
{
final String methodName = "default" + parameterName;
- MethodFilter filter = new MethodFilter()
+ Predicate<TransformMethod> predicate = new Predicate<TransformMethod>()
{
- public boolean accept(TransformMethodSignature signature)
+ public boolean accept(TransformMethod method)
{
- return signature.getParameterTypes().length == 0
- && signature.getMethodName().equalsIgnoreCase(methodName);
+ return method.getSignature().getParameterTypes().length == 0
+ && method.getName().equalsIgnoreCase(methodName);
}
};
- // This will match exactly 0 or 1 methods, and if it matches, we know the name
- // of the method.
+ List<TransformMethod> matches = transformation.matchMethods(predicate);
- List<TransformMethodSignature> signatures = transformation.findMethods(filter);
+ // This will match exactly 0 or 1 (unless the user does something really silly)
+ // methods, and if it matches, we know the name of the method.
- if (signatures.isEmpty())
+ if (matches.isEmpty())
return;
- String actualMethodName = signatures.get(0).getMethodName();
+ TransformMethod defaultMethod = matches.get(0);
- transformation.extendExistingMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
- String.format("%s.setDefault(($w) %s());", conduitFieldName, actualMethodName));
+ captureDefaultValueFromDefaultMethod(transformation, defaultMethod, conduitAccess);
+ }
+
+ private void captureDefaultValueFromDefaultMethod(ClassTransformation transformation,
+ TransformMethod defaultMethod, final FieldAccess conduitAccess)
+ {
+ final MethodAccess access = defaultMethod.getAccess();
+
+ ComponentMethodAdvice advice = new InvokeParameterDefaultMethod(conduitAccess, access);
+
+ addPageLoadAdvice(transformation, advice);
+ }
+
+ private void addPageLoadAdvice(ClassTransformation transformation, ComponentMethodAdvice advice)
+ {
+ addMethodAdvice(transformation, TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, advice);
}
private static String getParameterName(String fieldName, String annotatedName)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PersistWorker.java Fri Feb 19 18:54:27 2010
@@ -136,8 +136,6 @@
@SuppressWarnings("unchecked")
private Object determineDefaultValueFromFieldType(TransformField field)
{
- Class javaType = classCache.forName(field.getType());
-
- return javaType.isPrimitive() ? typeCoercer.coerce(0, javaType) : null;
+ return classCache.defaultValueForType(field.getType());
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java Fri Feb 19 18:54:27 2010
@@ -63,9 +63,11 @@
new String[]
{ field.getType() }, null);
+ ensureNotOverride(transformation, setter);
+
final FieldAccess access = field.getAccess();
- transformation.createMethod(setter).addAdvice(new ComponentMethodAdvice()
+ transformation.getOrCreateMethod(setter).addAdvice(new ComponentMethodAdvice()
{
public void advise(ComponentMethodInvocation invocation)
{
@@ -74,14 +76,24 @@
});
}
+ private void ensureNotOverride(ClassTransformation transformation, TransformMethodSignature signature)
+ {
+ if (transformation.isDeclaredMethod(signature))
+ throw new RuntimeException(String.format(
+ "Unable to create new method %s as it already exists in class %s.", signature, transformation
+ .getClassName()));
+ }
+
private void addGetter(ClassTransformation transformation, TransformField field, String propertyName)
{
TransformMethodSignature getter = new TransformMethodSignature(Modifier.PUBLIC, field.getType(), "get"
+ propertyName, null, null);
+ ensureNotOverride(transformation, getter);
+
final FieldAccess access = field.getAccess();
- transformation.createMethod(getter).addAdvice(new ComponentMethodAdvice()
+ transformation.getOrCreateMethod(getter).addAdvice(new ComponentMethodAdvice()
{
public void advise(ComponentMethodInvocation invocation)
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderCommandWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderCommandWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderCommandWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderCommandWorker.java Fri Feb 19 18:54:27 2010
@@ -58,6 +58,6 @@
transformation.addImplementedInterface(RenderCommand.class);
- transformation.getMethod(RENDER_SIGNATURE).addAdvice(advice);
+ transformation.getOrCreateMethod(RENDER_SIGNATURE).addAdvice(advice);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/RenderPhaseMethodWorker.java Fri Feb 19 18:54:27 2010
@@ -15,7 +15,7 @@
package org.apache.tapestry5.internal.transform;
import java.lang.annotation.Annotation;
-import java.util.Iterator;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -30,15 +30,19 @@
import org.apache.tapestry5.annotations.BeginRender;
import org.apache.tapestry5.annotations.CleanupRender;
import org.apache.tapestry5.annotations.SetupRender;
-import org.apache.tapestry5.internal.util.MethodInvocationBuilder;
+import org.apache.tapestry5.ioc.Predicate;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.util.BodyBuilder;
import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.Event;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.MethodFilter;
+import org.apache.tapestry5.services.ComponentMethodAdvice;
+import org.apache.tapestry5.services.ComponentMethodInvocation;
+import org.apache.tapestry5.services.MethodAccess;
+import org.apache.tapestry5.services.MethodInvocationResult;
import org.apache.tapestry5.services.TransformConstants;
+import org.apache.tapestry5.services.TransformMethod;
import org.apache.tapestry5.services.TransformMethodSignature;
/**
@@ -50,33 +54,92 @@
@SuppressWarnings("unchecked")
public class RenderPhaseMethodWorker implements ComponentClassTransformWorker
{
- private static final String CHECK_ABORT_FLAG = "if ($2.isAborted()) return;";
+ private final class RenderPhaseMethodAdvice implements ComponentMethodAdvice
+ {
+ private final boolean reverse;
+
+ private final List<Invoker> invokers;
+
+ private RenderPhaseMethodAdvice(boolean reverse, List<Invoker> invokers)
+ {
+ this.reverse = reverse;
+ this.invokers = invokers;
+ }
+
+ public void advise(ComponentMethodInvocation invocation)
+ {
+ if (!reverse)
+ invocation.proceed();
+
+ // All render phase methods take the same two parameters (writer and event)
+
+ Event event = (Event) invocation.getParameter(1);
+
+ if (event.isAborted())
+ return;
+
+ Object instance = invocation.getInstance();
+ MarkupWriter writer = (MarkupWriter) invocation.getParameter(0);
+
+ for (Invoker invoker : invokers)
+ {
+ invoker.invoke(instance, writer, event);
+
+ if (event.isAborted())
+ return;
+ }
+
+ // Parent class implementation goes last.
+
+ if (reverse)
+ invocation.proceed();
+ }
+ }
- private final MethodInvocationBuilder invocationBuilder = new MethodInvocationBuilder();
+ private class Invoker
+ {
+ private final String methodIdentifier;
+
+ private final MethodAccess access;
+
+ Invoker(String methodIdentifier, MethodAccess access)
+ {
+ this.methodIdentifier = methodIdentifier;
+ this.access = access;
+ }
+
+ void invoke(Object instance, MarkupWriter writer, Event event)
+ {
+ event.setMethodDescription(methodIdentifier);
+
+ // As currently implemented, MethodAccess objects ignore excess parameters.
+
+ MethodInvocationResult result = access.invoke(instance, writer);
+
+ result.rethrow();
+
+ event.storeResult(result.getReturnValue());
+ }
+
+ }
private final Map<Class<? extends Annotation>, TransformMethodSignature> annotationToSignature = CollectionFactory
.newMap();
- private final Map<String, Class<? extends Annotation>> nameToAnnotation = CollectionFactory
- .newCaseInsensitiveMap();
+ private final Map<String, Class<? extends Annotation>> nameToAnnotation = CollectionFactory.newCaseInsensitiveMap();
- private final Set<Class<? extends Annotation>> reverseAnnotations = CollectionFactory.newSet(
- AfterRenderBody.class, AfterRenderTemplate.class, AfterRender.class,
- CleanupRender.class);
+ private final Set<Class<? extends Annotation>> reverseAnnotations = CollectionFactory.newSet(AfterRenderBody.class,
+ AfterRenderTemplate.class, AfterRender.class, CleanupRender.class);
private final Set<TransformMethodSignature> lifecycleMethods = CollectionFactory.newSet();
{
annotationToSignature.put(SetupRender.class, TransformConstants.SETUP_RENDER_SIGNATURE);
annotationToSignature.put(BeginRender.class, TransformConstants.BEGIN_RENDER_SIGNATURE);
- annotationToSignature.put(BeforeRenderTemplate.class,
- TransformConstants.BEFORE_RENDER_TEMPLATE_SIGNATURE);
- annotationToSignature.put(BeforeRenderBody.class,
- TransformConstants.BEFORE_RENDER_BODY_SIGNATURE);
- annotationToSignature.put(AfterRenderBody.class,
- TransformConstants.AFTER_RENDER_BODY_SIGNATURE);
- annotationToSignature.put(AfterRenderTemplate.class,
- TransformConstants.AFTER_RENDER_TEMPLATE_SIGNATURE);
+ annotationToSignature.put(BeforeRenderTemplate.class, TransformConstants.BEFORE_RENDER_TEMPLATE_SIGNATURE);
+ annotationToSignature.put(BeforeRenderBody.class, TransformConstants.BEFORE_RENDER_BODY_SIGNATURE);
+ annotationToSignature.put(AfterRenderBody.class, TransformConstants.AFTER_RENDER_BODY_SIGNATURE);
+ annotationToSignature.put(AfterRenderTemplate.class, TransformConstants.AFTER_RENDER_TEMPLATE_SIGNATURE);
annotationToSignature.put(AfterRender.class, TransformConstants.AFTER_RENDER_SIGNATURE);
annotationToSignature.put(CleanupRender.class, TransformConstants.CLEANUP_RENDER_SIGNATURE);
@@ -85,145 +148,128 @@
nameToAnnotation.put(me.getValue().getMethodName(), me.getKey());
lifecycleMethods.add(me.getValue());
}
-
- // If we ever add more parameters to the methods, then we can add more to the invocation
- // builder. *Never* expose the Event parameter ($2), it is for internal use only.
-
- invocationBuilder.addParameter(MarkupWriter.class.getName(), "$1");
}
- public void transform(final ClassTransformation transformation, MutableComponentModel model)
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
{
- Map<Class, List<TransformMethodSignature>> methods = CollectionFactory.newMap();
-
- MethodFilter filter = new MethodFilter()
- {
- public boolean accept(TransformMethodSignature signature)
- {
- return !transformation.isMethodOverride(signature)
- && !lifecycleMethods.contains(signature);
- }
- };
+ Map<Class, List<TransformMethod>> methods = mapRenderPhaseAnnotationToMethods(transformation);
- for (TransformMethodSignature sig : transformation.findMethods(filter))
+ for (Class renderPhaseAnnotation : methods.keySet())
{
- Class categorized = null;
+ mapMethodsToRenderPhase(transformation, model, renderPhaseAnnotation, methods.get(renderPhaseAnnotation));
+ }
+ }
- for (Class annotationClass : annotationToSignature.keySet())
- {
- if (transformation.getMethodAnnotation(sig, annotationClass) != null)
- {
- categorized = annotationClass;
- break;
- }
- }
+ private void mapMethodsToRenderPhase(ClassTransformation transformation, MutableComponentModel model,
+ Class annotationType, List<TransformMethod> methods)
+ {
+ ComponentMethodAdvice renderPhaseAdvice = createAdviceForMethods(annotationType, methods);
- // If no annotation, see if the method name maps to an annotation class
- // and use that. Thus explicit annotations always override method name matching
- // as per TAP5-266
+ TransformMethodSignature renderPhaseSignature = annotationToSignature.get(annotationType);
- if (categorized == null)
- categorized = nameToAnnotation.get(sig.getMethodName());
+ transformation.getOrCreateMethod(renderPhaseSignature).addAdvice(renderPhaseAdvice);
- if (categorized != null)
- {
- InternalUtils.addToMapList(methods, categorized, sig);
- }
- }
-
- if (methods.isEmpty())
- return;
+ model.addRenderPhase(annotationType);
+ }
- for (Map.Entry<Class, List<TransformMethodSignature>> me : methods.entrySet())
- {
- Class annotationClass = me.getKey();
+ private ComponentMethodAdvice createAdviceForMethods(Class annotationType, List<TransformMethod> methods)
+ {
+ boolean reverse = reverseAnnotations.contains(annotationType);
- model.addRenderPhase(annotationClass);
+ List<Invoker> invokers = toInvokers(annotationType, methods, reverse);
- linkMethodsToRenderPhase(transformation, model, annotationToSignature
- .get(annotationClass), reverseAnnotations.contains(annotationClass), me
- .getValue());
- }
+ return new RenderPhaseMethodAdvice(reverse, invokers);
}
- public void linkMethodsToRenderPhase(ClassTransformation transformation,
- MutableComponentModel model, TransformMethodSignature lifecycleMethodSignature,
- boolean reverse, List<TransformMethodSignature> methods)
+ private List<Invoker> toInvokers(Class annotationType, List<TransformMethod> methods, boolean reverse)
{
- String lifecycleMethodName = lifecycleMethodSignature.getMethodName();
+ List<Invoker> result = CollectionFactory.newList();
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
+ for (TransformMethod method : methods)
+ {
+ MethodAccess methodAccess = toMethodAccess(method);
- // If in a subclass, and in normal order mode, invoke the super class version first.
+ Invoker invoker = new Invoker(method.getMethodIdentifier(), methodAccess);
- if (!(reverse || model.isRootClass()))
- {
- builder.addln("super.%s($$);", lifecycleMethodName);
- builder.addln(CHECK_ABORT_FLAG);
+ result.add(invoker);
}
- Iterator<TransformMethodSignature> i = reverse ? InternalUtils.reverseIterator(methods)
- : methods.iterator();
+ if (reverse)
+ Collections.reverse(result);
- builder.addln("try");
- builder.begin();
+ return result;
+ }
- while (i.hasNext())
- addMethodCallToBody(builder, i.next(), transformation);
+ private MethodAccess toMethodAccess(TransformMethod method)
+ {
+ validateAsRenderPhaseMethod(method);
- // In reverse order in a a subclass, invoke the super method last.
+ return method.getAccess();
+ }
- if (reverse && !model.isRootClass())
- builder.addln("super.%s($$);", lifecycleMethodName);
+ private void validateAsRenderPhaseMethod(TransformMethod method)
+ {
+ String[] parameterTypes = method.getSignature().getParameterTypes();
- builder.end(); // try
+ switch (parameterTypes.length)
+ {
+ case 0:
+ break;
- // Let runtime exceptions work up (they'll be caught at a higher level.
- // Wrap checked exceptions for later reporting.
+ case 1:
+ if (parameterTypes[0].equals(MarkupWriter.class.getName()))
+ break;
+ default:
+ throw new RuntimeException(
+ String
+ .format(
+ "Method %s is not a valid render phase method: it should take no parameters, or take a single parameter of type MarkupWriter.",
+ method.getMethodIdentifier()));
+ }
+ }
- builder.addln("catch (RuntimeException ex) { throw ex; }");
- builder.addln("catch (Exception ex) { throw new RuntimeException(ex); }");
+ private Map<Class, List<TransformMethod>> mapRenderPhaseAnnotationToMethods(final ClassTransformation transformation)
+ {
+ Map<Class, List<TransformMethod>> map = CollectionFactory.newMap();
- builder.end();
+ List<TransformMethod> matches = matchAllMethodsNotOverriddenFromBaseClass(transformation);
- // Let's see if this works; for base classes, we are adding an empty method then adding a
- // non-empty method "on top of it".
+ for (TransformMethod method : matches)
+ {
+ addMethodToRenderPhaseCategoryMap(map, method);
+ }
- transformation.addMethod(lifecycleMethodSignature, builder.toString());
+ return map;
}
- private void addMethodCallToBody(BodyBuilder builder, TransformMethodSignature sig,
- ClassTransformation transformation)
+ private void addMethodToRenderPhaseCategoryMap(Map<Class, List<TransformMethod>> map, TransformMethod method)
{
- boolean isVoid = sig.getReturnType().equals("void");
+ Class categorized = categorizeMethod(method);
- builder.addln("$2.setMethodDescription(\"%s\");", transformation.getMethodIdentifier(sig));
+ if (categorized != null)
+ InternalUtils.addToMapList(map, categorized, method);
+ }
- if (!isVoid)
+ private Class categorizeMethod(TransformMethod method)
+ {
+ for (Class annotationClass : annotationToSignature.keySet())
{
- // If we're not going to invoke storeResult(), then there's no reason to invoke
- // setMethodDescription().
-
- builder.add("if ($2.storeResult(($w) ");
+ if (method.getAnnotation(annotationClass) != null)
+ return annotationClass;
}
- // This is the best part; the method can even be private and this still works. It's a lot
- // like how javac enables access to private members for inner classes (by introducing
- // synthetic, static methods).
-
- builder.add(invocationBuilder.buildMethodInvocation(sig, transformation));
-
- // Now, if non void ...
+ return nameToAnnotation.get(method.getName());
+ }
- if (!isVoid)
+ private List<TransformMethod> matchAllMethodsNotOverriddenFromBaseClass(final ClassTransformation transformation)
+ {
+ return transformation.matchMethods(new Predicate<TransformMethod>()
{
- // Complete the call to storeResult(). If storeResult() returns true, then
- // the event is aborted and no further processing is required.
+ public boolean accept(TransformMethod method)
+ {
+ return !method.isOverride() && !lifecycleMethods.contains(method.getSignature());
+ }
+ });
- builder.addln(")) return;");
- }
- else
- builder.addln(";");
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorker.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/UnclaimedFieldWorker.java Fri Feb 19 18:54:27 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 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,53 +14,107 @@
package org.apache.tapestry5.internal.transform;
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.internal.InternalComponentResources;
+import org.apache.tapestry5.internal.services.ComponentClassCache;
+import org.apache.tapestry5.ioc.services.FieldValueConduit;
import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.runtime.PageLifecycleAdapter;
import org.apache.tapestry5.services.ClassTransformation;
import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import static org.apache.tapestry5.services.TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE;
-import static org.apache.tapestry5.services.TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE;
-
-import java.lang.reflect.Modifier;
-import java.util.List;
+import org.apache.tapestry5.services.ComponentValueProvider;
+import org.apache.tapestry5.services.TransformField;
/**
* Designed to be just about the last worker in the pipeline. Its job is to add cleanup code that restores transient
- * fields back to their initial (null) value. Fields that have been previously {@link
- * org.apache.tapestry5.services.ClassTransformation#claimField(String, Object) claimed} are ignored, as are fields that
- * are final.
+ * fields back to their initial (null) value. Fields that have been previously {@linkplain TransformField#claim(Object)
+ * claimed} are ignored, as are fields that are final.
*/
public final class UnclaimedFieldWorker implements ComponentClassTransformWorker
{
+ private final ComponentClassCache classCache;
- public void transform(ClassTransformation transformation, MutableComponentModel model)
+ public class UnclaimedFieldConduit implements FieldValueConduit
{
- List<String> fieldNames = transformation.findUnclaimedFields();
+ private final InternalComponentResources resources;
+
+ private Object fieldValue, fieldDefaultValue;
+
+ private UnclaimedFieldConduit(InternalComponentResources resources, Object fieldDefaultValue)
+ {
+ this.resources = resources;
- for (String fieldName : fieldNames)
+ this.fieldValue = fieldDefaultValue;
+ this.fieldDefaultValue = fieldDefaultValue;
+
+ resources.addPageLifecycleListener(new PageLifecycleAdapter()
+ {
+ @Override
+ public void containingPageDidDetach()
+ {
+ reset();
+ }
+ });
+ }
+
+ public Object get()
+ {
+ return fieldValue;
+ }
+
+ public void set(Object newValue)
{
- transformField(fieldName, transformation);
+ fieldValue = newValue;
+
+ if (!resources.isLoaded())
+ fieldDefaultValue = newValue;
+ }
+
+ public void reset()
+ {
+ fieldValue = fieldDefaultValue;
}
}
- private void transformField(String fieldName, ClassTransformation transformation)
+ public UnclaimedFieldWorker(ComponentClassCache classCache)
{
- int modifiers = transformation.getFieldModifiers(fieldName);
+ this.classCache = classCache;
+ }
- if (Modifier.isFinal(modifiers))
- return;
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ for (TransformField field : transformation.matchUnclaimedFields())
+ {
+ transformField(field);
+ }
+ }
- String type = transformation.getFieldType(fieldName);
+ private void transformField(TransformField field)
+ {
+ int modifiers = field.getModifiers();
- String defaultFieldName = transformation.addField(Modifier.PRIVATE, type, fieldName
- + "_default");
+ if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers))
+ return;
- transformation.extendMethod(CONTAINING_PAGE_DID_LOAD_SIGNATURE, defaultFieldName + " = "
- + fieldName + ";");
+ ComponentValueProvider<FieldValueConduit> provider = createFieldValueConduitProvider(field);
- // At the end of the request, we want to move the default value back over the
- // active field value. This will most often be null.
+ field.replaceAccess(provider);
+ }
- transformation.extendMethod(CONTAINING_PAGE_DID_DETACH_SIGNATURE, fieldName + " = "
- + defaultFieldName + ";");
+ private ComponentValueProvider<FieldValueConduit> createFieldValueConduitProvider(TransformField field)
+ {
+ final String fieldType = field.getType();
+
+ return new ComponentValueProvider<FieldValueConduit>()
+ {
+ public FieldValueConduit get(ComponentResources resources)
+ {
+ Object fieldDefaultValue = classCache.defaultValueForType(fieldType);
+
+ return new UnclaimedFieldConduit((InternalComponentResources) resources, fieldDefaultValue);
+ }
+ };
}
}
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=911931&r1=911930&r2=911931&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 Fri Feb 19 18:54:27 2010
@@ -20,12 +20,11 @@
import javassist.CtBehavior;
import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.internal.transform.ReadOnlyFieldValueConduit;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.Predicate;
import org.slf4j.Logger;
-import sun.awt.ComponentFactory;
-
/**
* Contains class-specific information used when transforming a raw component class into an
* executable component class.
@@ -37,6 +36,8 @@
* {@link ComponentClassTransformWorker}.
* <p/>
* Much of this information is somewhat like ordinary reflection, but applies to a class that has not yet been loaded.
+ * Field types, return types, parameter types and exception types are represented as string names, since any of them may
+ * be a class that has not yet been loaded and transformed as well.
* <p/>
* Transformation is primarily about identifying annotations on fields and on methods and changing the class, adding new
* interfaces, fields and methods, and deleting some existing fields.
@@ -81,7 +82,7 @@
* @param prefix
* for the generated name
* @param baseName
- * an name, often of an existing field or method
+ * a name, often of an existing field or method
* @return a unique name
*/
String newMemberName(String prefix, String baseName);
@@ -206,6 +207,7 @@
* @return the annotation if present, or null otherwise
* @throws IllegalArgumentException
* if the method signature does not correspond to a declared method
+ * @deprecated Use {@link TransformMethod#getAnnotation(Class)} instead
*/
<T extends Annotation> T getMethodAnnotation(TransformMethodSignature method, Class<T> annotationClass);
@@ -228,6 +230,7 @@
* if the fieldName does not correspond to a declared instance field
* @throws IllegalStateException
* if the field is already claimed for some other tag
+ * @deprecated Use {@link TransformField#claim(Object)} instead
*/
void claimField(String fieldName, Object tag);
@@ -237,21 +240,25 @@
*
* @param fieldName
* name of field to so change
+ * @deprecated Use {@link TransformField#replaceAccess(TransformField)} instead
+ * @see ReadOnlyFieldValueConduit
*/
void makeReadOnly(String fieldName);
/**
* Finds any declared <em>instance</em> fields that have not been claimed (via {@link #claimField(String, Object)})
- * and have not been either added or deleted, and returns the names of those fields. May return an empty array.
+ * and have not been added , and returns the names of those fields. May return an empty array.
*
* @deprecated Use {@link #matchUnclaimedFields()} instead
*/
List<String> findUnclaimedFields();
/**
- * Matches all fields that are not claimed (or added or removed).
+ * Matches all fields that are not claimed. This may include static fields and final fields, but will not
+ * include fields that have been added as part of the transformation.
*
* @since 5.2.0
+ * @return sorted list of unclaimed fields
*/
List<TransformField> matchUnclaimedFields();
@@ -339,7 +346,7 @@
* @param provider
* injected into the component to provide the value
* @return the actual name of the injected field
- * @since 5.2
+ * @since 5.2.0
*/
<T> TransformField addIndirectInjectedField(Class<T> type, String suggestedName, ComponentValueProvider<T> provider);
@@ -394,7 +401,7 @@
* the body of code
* @throws org.apache.tapestry5.internal.services.MethodCompileException
* if the provided Javassist method body can not be compiled
- * @deprecated Use {@link TransformMethod#extend(String)} instead
+ * @deprecated Use {@link TransformMethod#extend(String)} instead. This method is non-functional as of Tapestry 5.2.
*/
void extendMethod(TransformMethodSignature methodSignature, String methodBody);
@@ -411,7 +418,7 @@
* @throws org.apache.tapestry5.internal.services.MethodCompileException
* if the provided method body can not be compiled
* @see #prefixMethod(TransformMethodSignature, String)
- * @deprecated Use {@link TransformMethod#extend(String) instead}
+ * @deprecated Use {@link TransformMethod#extend(String) instead}. This method is non-functional as of Tapestry 5.2.
*/
void extendExistingMethod(TransformMethodSignature methodSignature, String methodBody);
@@ -422,7 +429,6 @@
* is added that first invokes the super implementation. Use {@link #addMethod(TransformMethodSignature, String)}
* when it is necessary to control when the super-class method is invoked.
* <p/>
- * <p/>
* Like {@link #extendExistingMethod(TransformMethodSignature, String)}, this method is generally used to "wrap" an
* existing method adding additional functionality such as caching or transaction support.
*
@@ -430,6 +436,8 @@
* @param methodBody
* @throws org.apache.tapestry5.internal.services.MethodCompileException
* if the provided method body can not be compiled
+ * @deprecated Use {@link TransformMethod#addAdvice(ComponentMethodAdvice)} instead. This method is non-functional
+ * as of Tapestry 5.2.
*/
void prefixMethod(TransformMethodSignature methodSignature, String methodBody);
@@ -452,22 +460,17 @@
* the super-class
* implementation is invoked.
*
- * @deprecated Use {@link #createMethod(TransformMethodSignature)} instead
+ * @deprecated Use {@link #getOrCreateMethod(TransformMethodSignature)} instead. This method is non-functional as of
+ * Tapestry 5.2.
*/
void addMethod(TransformMethodSignature signature, String methodBody);
/**
- * Creates a new method as a declared method of the class, with an empty (default) body that
- * does nothing. Non-void methods will return null, false or 0. The method must not yet exist.
- *
- * @param signature
- * defines the method to create
- */
- TransformMethod createMethod(TransformMethodSignature signature);
-
- /**
* As with {@link #addMethod(TransformMethodSignature, String)}, but field references inside the
* method <em>will</em> be transformed, and the method <em>must not already exist</em>.
+ *
+ * @deprecated Use {@link #getOrCreateMethod(TransformMethodSignature)} instead. This method is non-functional as of
+ * Tapestry 5.2.
*/
void addTransformedMethod(TransformMethodSignature methodSignature, String methodBody);
@@ -476,6 +479,8 @@
*
* @param statement
* the statement to add, which should end with a semicolon
+ * @deprecated Use methods that create or inject fields (directly or indirectly)
+ * @see ComponentValueProvider
*/
void extendConstructor(String statement);
@@ -508,7 +513,7 @@
* the name of the field to remove
* @see #replaceReadAccess(String, String)
* @see #replaceWriteAccess(String, String)
- * @deprecated Use {@link TransformField#remove()} instead
+ * @deprecated This method is non-functional as of Tapestry 5.2
*/
void removeField(String fieldName);
@@ -564,6 +569,8 @@
* fully qualified class name of exception
* @param body
* code to execute
+ * @deprecated Use {@link TransformMethod#addAdvice(ComponentMethodAdvice)} instead. This method is non-functional
+ * as of Tapestry 5.2.
*/
void addCatch(TransformMethodSignature methodSignature, String exceptionType, String body);
@@ -585,16 +592,26 @@
boolean isMethodOverride(TransformMethodSignature methodSignature);
/**
- * Locates and returns the method if declared in this class; if not, locates
- * a super-class method that is implemented into this class. In the latter
- * case, the method will be considered "new" (i.e., no field transformations),
- * as with {@link #extendMethod(TransformMethodSignature, String)}).
+ * Locates and returns the method if declared in this class; If not,
+ * the method is added to the class. If the method is an override
+ * of a base class method, then the method will delegate to the base
+ * class method (invoke it, return its value). If the method is entirely
+ * new, it will ignore its parameters and return a default value (null, 0 or false).
*
* @param signature
- * identifies the method to obtain
- * @throw RuntimeException if the signature does not match a declared method of this
- * class, or a overridable method of a superclass
+ * identifies the method to locate, override or create
* @since 5.2.0
*/
- TransformMethod getMethod(TransformMethodSignature signature);
+ TransformMethod getOrCreateMethod(TransformMethodSignature signature);
+
+ /**
+ * Determines if the class being transformed includes a declared (not inherited) method
+ * with the provided signature.
+ *
+ * @since 5.2.0
+ * @param signature
+ * identifies method to search for
+ * @return true if a such a method exists
+ */
+ boolean isDeclaredMethod(TransformMethodSignature signature);
}
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=911931&r1=911930&r2=911931&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 Fri Feb 19 18:54:27 2010
@@ -607,7 +607,7 @@
// annotated will
// be converted to clear out at the end of the request.
- configuration.add("UnclaimedField", new UnclaimedFieldWorker(), "after:*");
+ configuration.addInstance("UnclaimedField", UnclaimedFieldWorker.class, "after:*");
configuration.add("PageActivationContext", new PageActivationContextWorker(), "before:OnEvent");
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformField.java Fri Feb 19 18:54:27 2010
@@ -83,35 +83,6 @@
*/
void replaceAccess(FieldValueConduit conduit);
- /**
- * Extends the indicated method to add an assignment of the field with
- * the value obtained by the provider. This is used when a value
- * to be provided can not be provided from within the transformed class'
- * constructor.
- *
- * @param <T>
- * @param method
- * identifies the method where the assignment will occur, often this is
- * {@link TransformConstants#CONTAINING_PAGE_DID_LOAD_SIGNATURE}
- * @param provider
- * provides the value of the field
- */
- <T> void assignIndirect(TransformMethod method, ComponentValueProvider<T> provider);
-
- /**
- * Alternate version of {@link #assignIndirect(TransformMethod, ComponentValueProvider)} that operates using a
- * method signature.
- */
- <T> void assignIndirect(TransformMethodSignature signature, ComponentValueProvider<T> provider);
-
- /**
- * Marks the field for removal (at the end of the class transformation). Often, a field is deleted
- * after access to the field is {@linkplain #replaceAccess(ComponentValueProvider) replaced}.
- *
- * @throws IllegalStateException
- * if the field has already been marked for deletion
- */
- void remove();
/** Returns the modifiers for the field. */
int getModifiers();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TransformMethod.java Fri Feb 19 18:54:27 2010
@@ -36,28 +36,6 @@
String getName();
/**
- * Extends an existing method. The provided method body is inserted at the end of the existing
- * method (i.e. {@link javassist.CtBehavior#insertAfter(java.lang.String)}). To access or change
- * the return value, use the <code>$_</code> pseudo variable.
- * <p/>
- * The method may be declared in the class, or may be inherited from a super-class. For inherited methods, a method
- * body is added that first invokes the super implementation.
- * <p/>
- * The extended method is considered <em>new</em>. New methods <em>are not</em> scanned for removed fields, field
- * access changes, etc.
- * <p>
- * This method will eventually be removed, using {@link #addAdvice(ComponentMethodAdvice)} or some other alternative
- * is preferred.
- *
- * @param body
- * the body of Javassist psuedo-code
- * @throws RuntimeException
- * if the provided Javassist method body can not be compiled
- * @deprecated Use {@link #addAdvice(ComponentMethodAdvice)} instead
- */
- void extend(String body);
-
- /**
* Returns an object that can be used to invoke the method on an instance of the component class (regardless
* of the actual visibility of the method).
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java Fri Feb 19 18:54:27 2010
@@ -4,7 +4,7 @@
// 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,
@@ -353,7 +353,8 @@
long newModified = f.lastModified();
- if (newModified != startModified) return;
+ if (newModified != startModified)
+ return;
// Sleep 1/20 second and try again
@@ -362,25 +363,19 @@
}
protected final void train_addField(ClassTransformation transformation, int modifiers, String type,
- String suggestedName, String actualName)
+ String suggestedName, String actualName)
{
expect(transformation.addField(modifiers, type, suggestedName)).andReturn(actualName);
}
protected final void train_addInjectedField(ClassTransformation ct, Class type, String suggestedName, Object value,
- String fieldName)
+ String fieldName)
{
expect(ct.addInjectedField(type, suggestedName, value)).andReturn(fieldName);
}
- protected final void train_addMethod(ClassTransformation transformation, TransformMethodSignature signature,
- String... body)
- {
- transformation.addMethod(eq(signature), codeEq(join(body)));
- }
-
protected final void train_buildConstraints(ValidationConstraintGenerator generator, Class propertyType,
- AnnotationProvider provider, String... constraints)
+ AnnotationProvider provider, String... constraints)
{
expect(generator.buildConstraints(propertyType, provider)).andReturn(Arrays.asList(constraints));
}
@@ -396,11 +391,10 @@
}
protected final void train_createValidator(FieldValidatorSource source, Field field, String validatorType,
- String constraintValue, String overrideId, Messages overrideMessages,
- Locale locale, FieldValidator result)
+ String constraintValue, String overrideId, Messages overrideMessages, Locale locale, FieldValidator result)
{
- expect(source.createValidator(field, validatorType, constraintValue, overrideId, overrideMessages,
- locale)).andReturn(result);
+ expect(source.createValidator(field, validatorType, constraintValue, overrideId, overrideMessages, locale))
+ .andReturn(result);
}
protected final void train_encodeRedirectURL(Response response, String URI, String encoded)
@@ -414,43 +408,30 @@
}
protected final <T> void train_exists(ApplicationStatePersistenceStrategy strategy, Class<T> asoClass,
- boolean exists)
+ boolean exists)
{
expect(strategy.exists(asoClass)).andReturn(exists);
}
- protected final void train_extendConstructor(ClassTransformation transformation, String... body)
- {
- transformation.extendConstructor(codeEq(join(body)));
- }
-
- protected final void train_extendMethod(ClassTransformation transformation, TransformMethodSignature signature,
- String... body)
- {
- transformation.extendMethod(eq(signature), codeEq(join(body)));
- }
-
protected final void train_getAsset(AssetSource source, Resource root, String path, Locale locale, Asset asset)
{
expect(source.getAsset(root, path, locale)).andReturn(asset);
}
protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
- Class<? extends Annotation> annotationClass,
- List<String> fieldNames)
+ Class<? extends Annotation> annotationClass, List<String> fieldNames)
{
expect(transformation.findFieldsWithAnnotation(annotationClass)).andReturn(fieldNames);
}
protected final void train_findFieldsWithAnnotation(ClassTransformation transformation,
- Class<? extends Annotation> annotationClass,
- String... fieldNames)
+ Class<? extends Annotation> annotationClass, String... fieldNames)
{
train_findFieldsWithAnnotation(transformation, annotationClass, Arrays.asList(fieldNames));
}
protected final void train_findMethods(ClassTransformation transformation,
- final TransformMethodSignature... signatures)
+ final TransformMethodSignature... signatures)
{
IAnswer<List<TransformMethodSignature>> answer = new IAnswer<List<TransformMethodSignature>>()
{
@@ -464,7 +445,8 @@
for (TransformMethodSignature sig : signatures)
{
- if (filter.accept(sig)) result.add(sig);
+ if (filter.accept(sig))
+ result.add(sig);
}
// We don't have to sort them for testing purposes. Usually there's just going to be
@@ -478,8 +460,7 @@
}
protected final void train_findMethodsWithAnnotation(ClassTransformation tf,
- Class<? extends Annotation> annotationType,
- List<TransformMethodSignature> sigs)
+ Class<? extends Annotation> annotationType, List<TransformMethodSignature> sigs)
{
expect(tf.findMethodsWithAnnotation(annotationType)).andReturn(sigs);
}
@@ -495,13 +476,13 @@
}
protected final <T> void train_get(ApplicationStatePersistenceStrategy strategy, Class<T> asoClass,
- ApplicationStateCreator<T> creator, T aso)
+ ApplicationStateCreator<T> creator, T aso)
{
expect(strategy.get(asoClass, creator)).andReturn(aso);
}
protected final void train_get(ApplicationStatePersistenceStrategySource source, String strategyName,
- ApplicationStatePersistenceStrategy strategy)
+ ApplicationStatePersistenceStrategy strategy)
{
expect(source.get(strategyName)).andReturn(strategy).atLeastOnce();
}
@@ -586,8 +567,7 @@
expect(resources.getContainerMessages()).andReturn(containerMessages).atLeastOnce();
}
- protected final void train_getContainerResources(ComponentResources resources,
- ComponentResources containerResources)
+ protected final void train_getContainerResources(ComponentResources resources, ComponentResources containerResources)
{
expect(resources.getContainerResources()).andReturn(containerResources).atLeastOnce();
}
@@ -598,8 +578,7 @@
}
protected final <T extends Annotation> void train_getFieldAnnotation(ClassTransformation transformation,
- String fieldName, Class<T> annotationClass,
- T annotation)
+ String fieldName, Class<T> annotationClass, T annotation)
{
expect(transformation.getFieldAnnotation(fieldName, annotationClass)).andReturn(annotation);
}
@@ -650,15 +629,13 @@
}
protected final <T extends Annotation> void train_getMethodAnnotation(ClassTransformation ct,
- TransformMethodSignature signature,
- Class<T> annotationClass, T annotation)
+ TransformMethodSignature signature, Class<T> annotationClass, T annotation)
{
- expect(ct.getMethodAnnotation(signature, annotationClass)).andReturn(annotation)
- .atLeastOnce();
+ expect(ct.getMethodAnnotation(signature, annotationClass)).andReturn(annotation).atLeastOnce();
}
protected final void train_getMethodIdentifier(ClassTransformation transformation,
- TransformMethodSignature signature, String id)
+ TransformMethodSignature signature, String id)
{
expect(transformation.getMethodIdentifier(signature)).andReturn(id);
}
@@ -681,7 +658,7 @@
}
protected final void train_getParameterModel(ComponentModel model, String parameterName,
- ParameterModel parameterModel)
+ ParameterModel parameterModel)
{
expect(model.getParameterModel(parameterName)).andReturn(parameterModel).atLeastOnce();
}
@@ -732,7 +709,7 @@
}
protected final void train_getValidationMessages(ValidationMessagesSource messagesSource, Locale locale,
- Messages messages)
+ Messages messages)
{
expect(messagesSource.getValidationMessages(locale)).andReturn(messages).atLeastOnce();
}
@@ -743,8 +720,7 @@
}
@SuppressWarnings("unchecked")
- protected final void train_handleResult(ComponentEventCallback handler, Object result,
- boolean abort)
+ protected final void train_handleResult(ComponentEventCallback handler, Object result, boolean abort)
{
expect(handler.handleResult(result)).andReturn(abort);
}
@@ -780,14 +756,13 @@
}
protected final void train_newBinding(BindingFactory factory, String description, ComponentResources container,
- ComponentResources component, String expression, Location l, Binding binding)
+ ComponentResources component, String expression, Location l, Binding binding)
{
expect(factory.newBinding(description, container, component, expression, l)).andReturn(binding);
}
protected void train_newBinding(BindingSource bindingSource, String description,
- ComponentResources componentResources, String defaultBindingPrefix,
- String expression, Binding binding)
+ ComponentResources componentResources, String defaultBindingPrefix, String expression, Binding binding)
{
expect(bindingSource.newBinding(description, componentResources, defaultBindingPrefix, expression)).andReturn(
binding);
@@ -799,7 +774,7 @@
}
protected final void train_newMemberName(ClassTransformation transformation, String prefix, String baseName,
- String name)
+ String name)
{
expect(transformation.newMemberName(prefix, baseName)).andReturn(name);
}
@@ -815,16 +790,14 @@
}
protected final void train_provideInjection(InjectionProvider provider, String fieldName, Class fieldType,
- ObjectLocator locator, ClassTransformation transformation,
- MutableComponentModel model, boolean result)
+ ObjectLocator locator, ClassTransformation transformation, MutableComponentModel model, boolean result)
{
- expect(provider.provideInjection(fieldName, fieldType, locator, transformation, model))
- .andReturn(result);
+ expect(provider.provideInjection(fieldName, fieldType, locator, transformation, model)).andReturn(result);
}
@SuppressWarnings("unchecked")
protected final void train_renderInformalParameters(ComponentResources resources, final MarkupWriter writer,
- final Object... informals)
+ final Object... informals)
{
resources.renderInformalParameters(writer);
IAnswer answer = new IAnswer()
@@ -902,7 +875,7 @@
}
protected final void train_create(BeanModelSource source, Class beanClass, boolean filterReadOnly,
- Messages messages, BeanModel model)
+ Messages messages, BeanModel model)
{
expect(source.create(beanClass, filterReadOnly, messages)).andReturn(model);
}
@@ -955,8 +928,9 @@
/**
* Provides access to component messages, suitable for testing. Reads the associated .properties file for the class
* (NOT any localization of it). Only the messages directly in the .properties file is available.
- *
- * @param componentClass component class whose messages are needed *
+ *
+ * @param componentClass
+ * component class whose messages are needed *
* @return the Messages instance
*/
protected final Messages messagesFor(Class componentClass) throws IOException
@@ -971,8 +945,9 @@
{
is = componentClass.getResourceAsStream(file);
- if (is == null) throw new RuntimeException(
- String.format("Class %s does not have a message catalog.", componentClass.getName()));
+ if (is == null)
+ throw new RuntimeException(String.format("Class %s does not have a message catalog.", componentClass
+ .getName()));
properties.load(is);
}
@@ -1035,7 +1010,7 @@
}
protected final void train_service(HttpServletRequestHandler handler, HttpServletRequest request,
- HttpServletResponse response, boolean result) throws IOException
+ HttpServletResponse response, boolean result) throws IOException
{
expect(handler.service(request, response)).andReturn(result);
}
@@ -1080,8 +1055,8 @@
expect(valueEncoder.toValue(clientValue)).andReturn(value);
}
- protected <T> void train_findMeta(MetaDataLocator locator, String key,
- ComponentResources resources, Class<T> expectedType, T value)
+ protected <T> void train_findMeta(MetaDataLocator locator, String key, ComponentResources resources,
+ Class<T> expectedType, T value)
{
expect(locator.findMeta(key, resources, expectedType)).andReturn(value).atLeastOnce();
}
@@ -1156,7 +1131,6 @@
return newMock(FieldTranslator.class);
}
-
protected final Translator mockTranslator(String name, Class type)
{
Translator translator = mockTranslator();
@@ -1178,7 +1152,7 @@
}
protected final void train_createDefaultTranslator(FieldTranslatorSource source, ComponentResources resources,
- String parameterName, FieldTranslator translator)
+ String parameterName, FieldTranslator translator)
{
expect(source.createDefaultTranslator(resources, parameterName)).andReturn(translator);
}
@@ -1209,7 +1183,7 @@
}
protected final void train_createEditModel(BeanModelSource source, Class beanClass, Messages messages,
- BeanModel model)
+ BeanModel model)
{
expect(source.createEditModel(beanClass, messages)).andReturn(model);
}
@@ -1278,18 +1252,18 @@
protected final Asset mockAsset(String assetURL)
{
Asset asset = mockAsset();
-
+
train_toClientURL(asset, assetURL);
-
+
return asset;
}
protected final Link mockLink(String absoluteURI)
{
Link link = mockLink();
-
+
expect(link.toAbsoluteURI()).andReturn(absoluteURI).atLeastOnce();
-
+
return link;
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/linksubmit.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/linksubmit.js?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/linksubmit.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/linksubmit.js Fri Feb 19 18:54:27 2010
@@ -1,4 +1,4 @@
-// Copyright 2008 The Apache Software Foundation
+// Copyright 2008, 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.
@@ -14,10 +14,10 @@
Tapestry.LinkSubmit = Class.create({
- initialize: function(formId, clientId)
+ initialize: function(spec)
{
- this.form = $(formId);
- this.element = $(clientId);
+ this.form = $(spec.form);
+ this.element = $(spec.clientId);
this.element.observe("click", this.onClick.bindAsEventListener(this));
},
@@ -52,7 +52,7 @@
}
});
-Tapestry.Initializer.linkSubmit = function(formId, clientId)
+Tapestry.Initializer.linkSubmit = function(spec)
{
- new Tapestry.LinkSubmit(formId, clientId);
+ new Tapestry.LinkSubmit(spec);
}
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java?rev=911931&r1=911930&r2=911931&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/FormTests.java Fri Feb 19 18:54:27 2010
@@ -4,7 +4,7 @@
// 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,
@@ -37,17 +37,13 @@
{
clickThru("Page Context in Form");
- assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces",
- "context/with/slashes");
- assertFieldValue("t:ac",
- "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
+ assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
+ assertFieldValue("t:ac", "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
clickAndWait(SUBMIT);
- assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces",
- "context/with/slashes");
- assertFieldValue("t:ac",
- "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
+ assertTextSeries("//li[%d]", 1, "betty", "wilma", "context with spaces", "context/with/slashes");
+ assertFieldValue("t:ac", "betty/wilma/context$0020with$0020spaces/context$002fwith$002fslashes");
}
@Test
@@ -153,7 +149,7 @@
assertTextPresent("Howard", "Lewis Ship", "1966", "U.S. Citizen");
}
-
+
@Test
public void cancel_button()
{
@@ -165,7 +161,7 @@
clickAndWait("link=Clear Data");
clickAndWait("//input[@value='Cancel']");
-
+
assertText("message", "Form was cancelled.");
}
@@ -226,8 +222,7 @@
click("birthday-trigger");
- waitForCondition(
- "selenium.browserbot.getCurrentWindow().$$('DIV.datePicker').first().isDeepVisible() == true",
+ waitForCondition("selenium.browserbot.getCurrentWindow().$$('DIV.datePicker').first().isDeepVisible() == true",
PAGE_LOAD_TIMEOUT);
assertText("//A[@class='topLabel']", "1966 d\u00e9cembre");
@@ -457,8 +452,7 @@
waitForElementToAppear("amount:errorpopup");
waitForElementToAppear("quantity:errorpopup");
- assertText("//div[@id='amount:errorpopup']/span",
- "You must provide a numeric value for Amount.");
+ assertText("//div[@id='amount:errorpopup']/span", "You must provide a numeric value for Amount.");
assertText("//div[@id='quantity:errorpopup']/span", "Provide quantity as a number.");
}
@@ -635,8 +629,7 @@
waitForElementToAppear("longValue:errorpopup");
- assertText("//div[@id='longValue:errorpopup']/span",
- "You must provide an integer value for Long Value.");
+ assertText("//div[@id='longValue:errorpopup']/span", "You must provide an integer value for Long Value.");
type("longValue", "37");
@@ -689,11 +682,15 @@
public void link_submit_component()
{
clickThru("LinkSubmit Demo");
-
+
+ // Wait a moment for the page to initialize.
+
+ sleep(250);
+
+ //
click("link=Fred");
- waitForCondition("selenium.browserbot.getCurrentWindow().$('name:errorpopup')",
- PAGE_LOAD_TIMEOUT);
+ waitForCondition("selenium.browserbot.getCurrentWindow().$('name:errorpopup')", PAGE_LOAD_TIMEOUT);
assertTextPresent("You must provide a value for Name.");
@@ -782,13 +779,12 @@
// Tried to use "email:" and "exact:email:" but Selenium 0.8.1 doesn't
// seem to accept that.
- assertTextPresent("[foo@bar.baz]", "[Message for you, sir!]", "[false]", "[winnt]",
- "[RESEARCH_AND_DESIGN]");
+ assertTextPresent("[foo@bar.baz]", "[Message for you, sir!]", "[false]", "[winnt]", "[RESEARCH_AND_DESIGN]");
// Haven't figured out how to get selenium to check that fields are
// disabled.
}
-
+
/**
* TAP5-915
*/
@@ -798,12 +794,12 @@
open(getBaseURL() + "overridedatefieldmessagecatalogdemo");
type("birthday", "aaaaa");
-
+
clickAndWait("//input[@type='submit' and @value='Go']");
-
+
assertTextPresent("The input 'aaaaa' is not a valid date");
}
-
+
/**
* TAP5-52.
*/
@@ -811,23 +807,23 @@
public void single_error_message()
{
open(getBaseURL() + "singleerrordemo");
-
+
clickAndWait(SUBMIT);
-
+
assertTextPresent("You must provide a value for Username");
assertTextPresent("You must provide a value for Password");
type("username", "Igor");
-
+
clickAndWait(SUBMIT);
-
+
assertFalse(isTextPresent("You must provide a value for Username"));
assertTextPresent("You must provide a value for Password");
-
+
type("password", "secret");
-
+
clickAndWait(SUBMIT);
-
+
assertFalse(isTextPresent("You must provide a value for Username"));
assertFalse(isTextPresent("You must provide a value for Password"));
}