You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2010/01/22 17:31:49 UTC
svn commit: r902157 [2/2] - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/annotations/
main/java/org/apache/tapestry5/internal/
main/java/org/apache/tapestry5/internal/model/ main/java/or...
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=902157&r1=902156&r2=902157&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 Jan 22 16:31:47 2010
@@ -14,29 +14,27 @@
package org.apache.tapestry5.internal.transform;
-import java.lang.reflect.Modifier;
import java.util.Iterator;
import java.util.List;
import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.internal.InternalComponentResources;
import org.apache.tapestry5.internal.ParameterAccess;
-import org.apache.tapestry5.internal.ParameterChangeListener;
-import org.apache.tapestry5.internal.ParameterChangedEvent;
-import org.apache.tapestry5.internal.TapestryInternalUtils;
import org.apache.tapestry5.internal.bindings.LiteralBinding;
+import org.apache.tapestry5.internal.services.ComponentClassCache;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
-import org.apache.tapestry5.ioc.util.BodyBuilder;
+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.TransformMethodSignature;
-import org.apache.tapestry5.services.TransformUtils;
/**
* Responsible for identifying parameters via the {@link org.apache.tapestry5.annotations.Parameter} annotation on
@@ -44,20 +42,25 @@
*/
public class ParameterWorker implements ComponentClassTransformWorker
{
- private static final String BIND_METHOD_NAME = ParameterWorker.class.getName() + ".bind";
- private static final String EQUAL_METHOD_NAME = ParameterWorker.class.getName() + ".equal";
+ private final ComponentClassCache classCache;
private final BindingSource bindingSource;
- private ComponentDefaultProvider defaultProvider;
+ private final ComponentDefaultProvider defaultProvider;
- public ParameterWorker(BindingSource bindingSource, ComponentDefaultProvider defaultProvider)
+ private final TypeCoercer typeCoercer;
+
+ public ParameterWorker(ComponentClassCache classCache, BindingSource bindingSource,
+ ComponentDefaultProvider defaultProvider, TypeCoercer typeCoercer)
{
+ this.classCache = classCache;
this.bindingSource = bindingSource;
this.defaultProvider = defaultProvider;
+ this.typeCoercer = typeCoercer;
}
- public void transform(final ClassTransformation transformation, MutableComponentModel model)
+ @Override
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
{
List<String> fieldNames = transformation.findFieldsWithAnnotation(Parameter.class);
@@ -69,14 +72,13 @@
{
String fieldName = i.next();
- Parameter annotation = transformation.getFieldAnnotation(fieldName, Parameter.class);
+ Parameter annotation = transformation
+ .getFieldAnnotation(fieldName, Parameter.class);
// Process the principal annotations on the first pass, handle the others
// on the second pass.
- boolean process = pass == 0
- ? annotation.principal()
- : true;
+ boolean process = pass == 0 ? annotation.principal() : true;
if (process)
{
@@ -86,135 +88,236 @@
}
}
}
- }
-
- private void convertFieldIntoParameter(String name, Parameter annotation, ClassTransformation transformation,
- MutableComponentModel model)
- {
- transformation.claimField(name, annotation);
-
- String parameterName = getParameterName(name, annotation.name());
-
- boolean cache = annotation.cache();
-
- model.addParameter(parameterName, annotation.required(), annotation.allowNull(), annotation.defaultPrefix(),cache);
-
- String type = transformation.getFieldType(name);
-
- String cachedFieldName = transformation.addField(Modifier.PRIVATE, "boolean", name + "_cached");
-
- String resourcesFieldName = transformation.getResourcesFieldName();
-
- String accessFieldName = addParameterSetup(name, annotation.defaultPrefix(), annotation.value(),
- parameterName, cachedFieldName, cache, type, resourcesFieldName,
- transformation, annotation.autoconnect());
-
- addReaderMethod(name, cachedFieldName, accessFieldName, cache, parameterName, type, resourcesFieldName,
- transformation);
- addWriterMethod(name, cachedFieldName, accessFieldName, cache, parameterName, type, resourcesFieldName,
- transformation);
}
- /**
- * Returns the name of a field that stores whether the parameter binding is invariant.
- */
- private String addParameterSetup(String fieldName, String defaultPrefix, String defaultBinding,
- String parameterName, String cachedFieldName, boolean cache, String fieldType,
- String resourcesFieldName, ClassTransformation transformation, boolean autoconnect)
+ private void convertFieldIntoParameter(String fieldName, final Parameter annotation,
+ ClassTransformation transformation, MutableComponentModel model)
{
+ final String fieldTypeName = transformation.getFieldType(fieldName);
- String accessFieldName = transformation.addField(Modifier.PRIVATE, ParameterAccess.class.getName(),
- fieldName + "_access");
+ final String parameterName = getParameterName(fieldName, annotation.name());
- String defaultFieldName = transformation.addField(Modifier.PRIVATE, fieldType, fieldName + "_default");
+ final boolean enableCaching = annotation.cache();
- BodyBuilder builder = new BodyBuilder().begin();
+ model.addParameter(parameterName, annotation.required(), annotation.allowNull(), annotation
+ .defaultPrefix(), enableCaching);
- addDefaultBindingSetup(parameterName, defaultPrefix, defaultBinding, resourcesFieldName,
- transformation,
- builder, autoconnect);
-
- // Order is (alas) important here: must invoke getParameterAccess() after the binding setup, as
- // that code may invoke InternalComponentResources.bindParameter().
+ transformation.claimField(fieldName, annotation);
+
+ ComponentValueProvider<ParameterConduit> provider = 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.
- builder.addln("%s = %s.getParameterAccess(\"%s\");", accessFieldName, resourcesFieldName, parameterName);
+ @Override
+ public ParameterConduit get(ComponentResources resources)
+ {
+ final InternalComponentResources icr = (InternalComponentResources) resources;
- // Store the current value of the field into the default field. This value will
- // be used to reset the field after rendering.
+ final Class fieldType = classCache.forName(fieldTypeName);
- builder.addln("%s = %s;", defaultFieldName, fieldName);
+ // Rely on some code generation in the component to set the default binding from
+ // the field, or from a default method.
- addListenerSetup(fieldName, fieldType, parameterName, accessFieldName, builder, transformation);
+ return new ParameterConduit()
+ {
+ // Current cached value for the parameter.
+ private Object value;
- builder.end();
+ // Default value for parameter, computed *once* at
+ // page load time.
- transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
- .toString());
+ private Object defaultValue;
- // Now, when the component completes rendering, ensure that any variant parameters are
- // are returned to default value. This isn't necessary when the parameter is not cached,
- // because (unless the binding is invariant), there's no value to get rid of (and if it is
- // invariant, there's no need to get rid of it).
+ private ParameterAccess parameterAccess;
+
+ private Binding defaultBinding;
+
+ boolean loaded = false;
+
+ // Is the current value of the binding cached in the
+ // 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);
+ }
+
+ icr.setParameterConduit(parameterName, this);
+ }
+
+ private boolean isInvariant()
+ {
+ return parameterAccess.isInvariant();
+ }
+
+ private boolean isLoaded()
+ {
+ return loaded;
+ }
+
+ @Override
+ public void set(Object newValue)
+ {
+ // Assignments before the page is loaded ultimately exist to set the
+ // default value for the field. Often this is from the (original)
+ // constructor method,
+ // which is converted to a real method as part of the transformation.
+
+ if (!loaded)
+ {
+ defaultValue = newValue;
+ return;
+ }
+
+ // This will catch read-only or unbound parameters.
+
+ parameterAccess.write(newValue);
+
+ value = newValue;
+
+ // 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
+ // rendering).
+
+ cached = enableCaching && icr.isRendering();
+ }
+
+ @Override
+ public void reset()
+ {
+ if (!isInvariant())
+ {
+ value = defaultValue;
+ cached = false;
+ }
+ }
+
+ @Override
+ public void load()
+ {
+ // If it's bound at this point, that's because of an explicit binding
+ // in the template or @Component annotation.
+
+ if (!icr.isBound(parameterName))
+ {
+ // Otherwise, construct a default binding, or use one provided from
+ // the component.
+
+ Binding binding = getDefaultBindingForParameter();
+
+ if (binding != null)
+ icr.bindParameter(parameterName, binding);
+
+ defaultBinding = null;
+ }
+
+ parameterAccess = icr.getParameterAccess(parameterName);
+
+ loaded = true;
+
+ 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 defaultBinding;
+ }
+
+ @Override
+ public boolean isBound()
+ {
+ return parameterAccess.isBound();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object get()
+ {
+ if (!isLoaded()) { return defaultValue; }
+
+ if (cached || !isBound()) { return value; }
+
+ // Read the parameter's binding and cast it to the
+ // field's type.
+ Object result = parameterAccess.read(fieldType);
+
+ // If the value is invariant, we can cache it forever. Otherwise, we
+ // we may want to cache it for the remainder of the component render (if the
+ // component is currently rendering).
+
+ if (isInvariant() || (enableCaching && icr.isRendering()))
+ {
+ value = result;
+ cached = true;
+ }
+
+ return result;
+ }
+
+ @Override
+ public void setDefault(Object value)
+ {
+ if (value == null)
+ return;
+
+ if (value instanceof Binding)
+ {
+ defaultBinding = (Binding) value;
+ return;
+ }
+
+ defaultBinding = new LiteralBinding(null, "default " + parameterName, value);
+ }
+ };
+ }
- if (cache)
- {
- builder.clear();
+ };
- builder.addln("if (! %s.isInvariant())", accessFieldName);
- builder.begin();
- builder.addln("%s = %s;", fieldName, defaultFieldName);
- builder.addln("%s = false;", cachedFieldName);
- builder.end();
+ // This has to be done in the constructor, to handle any field initializations
- // Clean up after the component renders.
+ String conduitFieldName = transformation.addIndirectInjectedField(ParameterConduit.class,
+ parameterName + "$conduit", provider);
- String body = builder.toString();
+ addCodeForParameterDefaultMethod(transformation, parameterName, conduitFieldName);
- transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, body);
+ transformation.replaceFieldAccess(fieldName, conduitFieldName);
- // And again, when the page is detached (TAPESTRY-2460)
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, String
+ .format("%s.load();", conduitFieldName));
- transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_DETACH_SIGNATURE, builder.toString());
- }
+ transformation.extendMethod(TransformConstants.POST_RENDER_CLEANUP_SIGNATURE, String
+ .format("%s.reset();", conduitFieldName));
- return accessFieldName;
}
- private void addDefaultBindingSetup(String parameterName, String defaultPrefix, String defaultBinding,
- String resourcesFieldName,
- ClassTransformation transformation,
- BodyBuilder builder, boolean autoconnect)
+ private void addCodeForParameterDefaultMethod(ClassTransformation transformation,
+ final String parameterName, String conduitFieldName)
{
- if (InternalUtils.isNonBlank(defaultBinding))
- {
- builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
-
- String bindingFactoryFieldName = transformation.addInjectedField(BindingSource.class, "bindingSource",
- bindingSource);
-
- builder
- .addln(" %s.bindParameter(\"%s\", %s.newBinding(\"default %2$s\", %1$s, \"%s\", \"%s\"));",
- resourcesFieldName, parameterName, bindingFactoryFieldName, defaultPrefix, defaultBinding);
-
- return;
- }
-
- if (autoconnect)
- {
- String defaultProviderFieldName = transformation.addInjectedField(ComponentDefaultProvider.class,
- "defaultProvider", defaultProvider);
-
- builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
-
- builder.addln(" %s.bindParameter(\"%s\", %s.defaultBinding(\"%s\", %s));", resourcesFieldName,
- parameterName, defaultProviderFieldName, parameterName, resourcesFieldName);
- return;
- }
-
- // If no default binding expression provided in the annotation, then look for a default
- // binding method to provide the binding.
-
final String methodName = "default" + parameterName;
MethodFilter filter = new MethodFilter()
@@ -231,187 +334,20 @@
List<TransformMethodSignature> signatures = transformation.findMethods(filter);
- if (signatures.isEmpty()) return;
-
- // Because the check was case-insensitive, we need to determine the actual
- // name.
+ if (signatures.isEmpty())
+ return;
String actualMethodName = signatures.get(0).getMethodName();
- builder.addln("if (! %s.isBound(\"%s\"))", resourcesFieldName, parameterName);
- builder.addln(" %s(\"%s\", %s, ($w) %s());",
- BIND_METHOD_NAME,
- parameterName,
- resourcesFieldName,
- actualMethodName);
- }
-
- private void addListenerSetup(
- String fieldName,
- String fieldType,
- String parameterName,
- String accessFieldName,
- BodyBuilder builder,
- ClassTransformation transformation)
- {
- transformation.addImplementedInterface(ParameterChangeListener.class);
- builder.addln("%s.registerParameterChangeListener($0);",accessFieldName);
-
- TransformMethodSignature signature = new TransformMethodSignature(Modifier.PUBLIC, "void", "parameterChanged",
- new String[] {ParameterChangedEvent.class.getName()}, null);
-
- BodyBuilder changedBody = new BodyBuilder();
- changedBody.begin();
-
- changedBody.addln("if (%s($1, \"%s\"))",EQUAL_METHOD_NAME,parameterName);
- changedBody.begin();
-
- String cast = TransformUtils.getWrapperTypeName(fieldType);
-
- if (TransformUtils.isPrimitive(fieldType))
- changedBody.addln("%s = ((%s) $1.getNewValue()).%s();",
- fieldName, cast, TransformUtils.getUnwrapperMethodName(fieldType));
- else
- changedBody.addln("%s = (%s) $1.getNewValue();",fieldName, cast);
-
- changedBody.addln("return;");
- changedBody.end();
-
- changedBody.end();
-
- transformation.extendMethod(signature,changedBody.toString());
-
- }
-
- private void addWriterMethod(String fieldName, String cachedFieldName, String accessFieldName, boolean cache,
- String parameterName, String fieldType, String resourcesFieldName,
- ClassTransformation transformation)
- {
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
-
- // Before the component is loaded, updating the property sets the default value
- // for the parameter. The value is stored in the field, but will be
- // rolled into default field inside containingPageDidLoad().
-
- builder.addln("if (! %s.isLoaded())", resourcesFieldName);
- builder.begin();
- builder.addln("%s = $1;", fieldName);
- builder.addln("return;");
- builder.end();
-
- // Always start by updating the parameter; this will implicitly check for
- // read-only or unbound parameters. $1 is the single parameter
- // to the method.
- builder.addln("%s.unregisterParameterChangeListener($0);",accessFieldName);
- builder.addln("%s.write(($w)$1);", accessFieldName);
- builder.addln("%s.registerParameterChangeListener($0);",accessFieldName);
- builder.addln("%s = $1;", fieldName);
- if (cache) builder.addln("%s = %s.isRendering();", cachedFieldName, resourcesFieldName);
-
- builder.end();
-
- String methodName = transformation.newMemberName("update_parameter", parameterName);
-
- TransformMethodSignature signature = new TransformMethodSignature(Modifier.PRIVATE, "void", methodName,
- new String[] {fieldType}, null);
-
- transformation.addMethod(signature, builder.toString());
-
- builder.clear();
-
- //add the catch because if we don't re-register the class as a parameter change listener, it's value
- //could wind up stale, and write can throw an exception.
- builder.begin();
- builder.addln("%s.registerParameterChangeListener($0);",accessFieldName);
- builder.addln("throw $e;");
- builder.end();
-
- transformation.addCatch(signature,Exception.class.getName(),builder.toString());
-
- transformation.replaceWriteAccess(fieldName, methodName);
- }
-
- /**
- * Adds a private method that will be the replacement for read-access to the field.
- */
- private void addReaderMethod(String fieldName, String cachedFieldName, String accessFieldName, boolean cache,
- String parameterName, String fieldType, String resourcesFieldName,
- ClassTransformation transformation)
- {
- BodyBuilder builder = new BodyBuilder();
- builder.begin();
-
- // While the component is still loading, or when the value for the component is cached,
- // or if the value is not bound, then return the current value of the field.
-
- builder.addln("if (%s || ! %s.isLoaded() || ! %s.isBound()) return %s;", cachedFieldName,
- resourcesFieldName, accessFieldName, fieldName);
-
- String cast = TransformUtils.getWrapperTypeName(fieldType);
-
- // The ($r) cast will convert the result to the method return type; generally
- // this does nothing. but for primitive types, it will unwrap
- // the wrapper type back to a primitive. We pass the desired type name
- // to readParameter(), since its easier to convert it properly to
- // a type on that end than in the generated code.
-
- builder.addln("%s result = ($r) ((%s) %s.read(\"%2$s\"));", fieldType, cast, accessFieldName);
-
- // If the binding is invariant, then it's ok to cache. Othewise, its only
- // ok to cache if a) the @Parameter says to cache and b) the component
- // is rendering at the point when field is accessed.
-
- builder.add("if (%s.isInvariant()", accessFieldName);
-
- if (cache) builder.add(" || %s.isRendering()", resourcesFieldName);
-
- builder.addln(")");
- builder.begin();
- builder.addln("%s = result;", fieldName);
- builder.addln("%s = true;", cachedFieldName);
- builder.end();
-
- builder.addln("return result;");
- builder.end();
-
- String methodName = transformation.newMemberName("read_parameter", parameterName);
-
- TransformMethodSignature signature = new TransformMethodSignature(Modifier.PRIVATE, fieldType, methodName, null,
- null);
-
- transformation.addMethod(signature, builder.toString());
-
- transformation.replaceReadAccess(fieldName, methodName);
+ transformation.extendExistingMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE,
+ String.format("%s.setDefault(($w) %s());", conduitFieldName, actualMethodName));
}
- private String getParameterName(String fieldName, String annotatedName)
+ private static String getParameterName(String fieldName, String annotatedName)
{
- if (InternalUtils.isNonBlank(annotatedName)) return annotatedName;
+ if (InternalUtils.isNonBlank(annotatedName))
+ return annotatedName;
return InternalUtils.stripMemberName(fieldName);
}
-
- /**
- * Invoked from generated code as part of the handling of parameter default methods.
- */
- public static void bind(String parameterName, InternalComponentResources resources, Object value)
- {
- if (value == null) return;
-
- if (value instanceof Binding)
- {
- Binding binding = (Binding) value;
-
- resources.bindParameter(parameterName, binding);
- return;
- }
-
- resources.bindParameter(parameterName, new LiteralBinding(null, "default " + parameterName, value));
- }
-
- public static <T> boolean equal(T left, T right)
- {
- return TapestryInternalUtils.isEqual(left,right);
- }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/TransformMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/TransformMessages.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/TransformMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/TransformMessages.java Fri Jan 22 16:31:47 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,
@@ -16,7 +16,9 @@
import java.util.List;
+import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.annotations.MixinClasses;
+import org.apache.tapestry5.internal.structure.InternalComponentResourcesImpl;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.MessagesImpl;
@@ -43,12 +45,22 @@
static String illegalNumberOfPageActivationContextHandlers(List<String> fields)
{
- return MESSAGES.format("illegal-number-of-page-activation-context-handlers", InternalUtils.joinSorted(fields));
+ return MESSAGES.format("illegal-number-of-page-activation-context-handlers", InternalUtils
+ .joinSorted(fields));
}
-
public static String badMixinConstraintLength(MixinClasses mixin, String fieldName)
{
- return MESSAGES.format("bad-mixin-constraint-length",mixin.value().length,fieldName,mixin.order().length);
+ return MESSAGES.format("bad-mixin-constraint-length", mixin.value().length, fieldName,
+ mixin.order().length);
}
+
+ /** @since 5.2.0 */
+ public static String bindParameterOnlyOnMixin(String boundParameterName,
+ ComponentResources resources)
+ {
+ return MESSAGES.format("bind-parameter-only-on-mixin", boundParameterName,
+ resources.getComponentModel().getComponentClassName());
+ }
+
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/ComponentModel.java Fri Jan 22 16:31:47 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -39,7 +39,7 @@
Resource getBaseResource();
/**
- * The FQCN of the component.
+ * The fully qualified class name of the component.
*/
String getComponentClassName();
@@ -79,13 +79,21 @@
List<String> getMixinClassNames();
/**
- * Return a single parameter model by parameter name, or null if the parameter is not defined.
+ * Return a single parameter model by parameter name, or null if the parameter is not defined (is not
+ * a formal parameter).
*
* @param parameterName the name of the parameter (case is ignored)
*/
ParameterModel getParameterModel(String parameterName);
/**
+ * Returns true if the named parameter is formally defined (there's a ParameterModel).
+ * @param parameterName name of the parameter (case is ignored)
+ * @since 5.2.0
+ */
+ boolean isFormalParameter(String parameterName);
+
+ /**
* Returns an alphabetically sorted list of the names of all formal parameters. This includes parameters defined by
* a base class.
*/
@@ -171,7 +179,7 @@
/**
* @param mixinClassName class name of the mixin for which the ordering is desired
* @return the ordering constraint(s) for the mixin, potentially null.
- * @since 5.2.0.0
+ * @since 5.2.0
*/
String[] getOrderForMixin(String mixinClassName);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/model/MutableComponentModel.java Fri Jan 22 16:31:47 2010
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007, 2008, 2009 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
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=902157&r1=902156&r2=902157&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 Jan 22 16:31:47 2010
@@ -546,9 +546,8 @@
// make sure
// that Parameter fields are processed after injections.
- // configuration.addInstance("Parameter", ParameterWorker.class, "after:Inject*");
- configuration.addInstance("Parameter", ParameterWorker2.class, "after:Inject*");
-
+ configuration.addInstance("Parameter", ParameterWorker.class, "after:Inject*");
+
// bind parameter should always go after parameter to make sure all
// parameters
// have been properly setup.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/structure/StructureStrings.properties Fri Jan 22 16:31:47 2010
@@ -36,7 +36,3 @@
render-variable-set-when-not-rendering=Component %s is not rendering, so render variable '%s' may not be updated.
persist-change-before-load-complete=Persistent fields may not be updated until after the page has finished loading. \
This may be due to a persistent field with a default value. The default value should be removed.
-no-such-core-component-parameter=Failed to BindParameter '%s' in mixin '%s': component '%s' does not provide a matching \
- parameter (looking for: %s). Available parameters: %s
-bind-parameter-only-on-mixin=@BindParameter was used on '%s' in component class '%s', but @BindParameter should \
- only be used in mixins.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/transform/TransformStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/transform/TransformStrings.properties?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/transform/TransformStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/transform/TransformStrings.properties Fri Jan 22 16:31:47 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.
@@ -18,3 +18,6 @@
illegal-number-of-page-activation-context-handlers=Illegal number of fields annotated with @PageActivationContext: %s. Only one field is allowed.
bad-mixin-constraint-length=%d mixins defined via @MixinClasses on field '%s', but %d ordering constraints \
specified (expected 0 or %1$d).
+bind-parameter-only-on-mixin=@BindParameter was used on field '%s' of component class '%s', but @BindParameter should \
+ only be used in mixins.
+
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java Fri Jan 22 16:31:47 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,
@@ -1321,10 +1321,8 @@
assertTextPresent(
"An unexpected application exception has occurred.",
- "Failed to BindParameter 'boundParameter' in mixin 'org.apache.tapestry5.integration.app1.mixins.EchoValue2': "
- + "component 'org.apache.tapestry5.corelib.components.Any' does not provide a matching parameter "
- + "(looking for: value). Available parameters: [clientId, element]");
+ "Failed to bind parameter of mixin BindParameterNoSuchParameter:throwexception$echovalue2 (type org.apache.tapestry5.integration.app1.mixins.EchoValue2). Containing component org.apache.tapestry5.corelib.components.Any does not contain a formal parameter matching any of boundParameter, value. Formal parameters: clientId, element.");
}
@Test
@@ -1334,7 +1332,7 @@
assertTextPresent(
"An unexpected application exception has occurred.",
- "@BindParameter was used on 'value' in component class 'org.apache.tapestry5.integration.app1.components.BindParameterComponent', but @BindParameter should only be used in mixins");
+ "@BindParameter was used on field 'value' of component class 'org.apache.tapestry5.integration.app1.components.BindParameterComponent', but @BindParameter should only be used in mixins.");
}
@Test
@@ -1364,8 +1362,7 @@
* there's warnings that pop up about
* certificates.
* <p/>
- * Verified: Selenium can't handle this, even with a user manually OK-ing the certificate
- * warning dialogs.
+ * Verified: Selenium can't handle this, even with a user manually OK-ing the certificate warning dialogs.
*/
@Test(enabled = false)
public void secure_page_access()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/mixins/TextOnlyOnDisabled.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/mixins/TextOnlyOnDisabled.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/mixins/TextOnlyOnDisabled.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/mixins/TextOnlyOnDisabled.java Fri Jan 22 16:31:47 2010
@@ -1,10 +1,10 @@
-// Copyright 2009 The Apache Software Foundation
+// Copyright 2009, 2010 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
-// http://www.apache.org/licenses/LICENSE-2.0
+// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,16 +14,17 @@
package org.apache.tapestry5.integration.app1.mixins;
+import org.apache.tapestry5.ClientElement;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.FieldTranslator;
+import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.BindParameter;
import org.apache.tapestry5.annotations.InjectContainer;
-import org.apache.tapestry5.*;
-import org.apache.tapestry5.internal.InternalComponentResources;
-import org.apache.tapestry5.internal.ParameterAccess;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.services.TypeCoercer;
/**
- * Renders a plain-text version of a value where
+ * Renders a plain-text version of a value where
*/
public class TextOnlyOnDisabled
{
@@ -33,7 +34,6 @@
@BindParameter
private boolean disabled;
-
@BindParameter
private FieldTranslator translate;
@@ -48,15 +48,14 @@
Boolean beginRender(MarkupWriter writer)
{
- InternalComponentResources res = (InternalComponentResources) resources;
- ParameterAccess acc = res.getContainerBoundParameterAccess("translate","translate");
if (disabled)
{
- //We can short-circuit the text field's beginRender phase, but
- //not it's afterRender phase, and TextField calls writer.end()
- //in end render. So we add a dummy element to provide an element to end.
- writer.element("span","id",field.getClientId());
+ // We can short-circuit the text field's beginRender phase, but
+ // not it's afterRender phase, and TextField calls writer.end()
+ // in end render. So we add a dummy element to provide an element to end.
+ writer.element("span", "id", field.getClientId());
writer.write(translate.toClient(value));
+
return false;
}
return null;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImplTest.java?rev=902157&r1=902156&r2=902157&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImplTest.java Fri Jan 22 16:31:47 2010
@@ -44,7 +44,7 @@
replay();
InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null,
- null, ins);
+ null, ins, false);
resources.renderInformalParameters(writer);
@@ -69,7 +69,7 @@
replay();
InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null,
- null, ins);
+ null, ins, false);
resources.bindParameter("fred", binding);
@@ -105,7 +105,7 @@
InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null,
componentPageElementResources,
- null, null, ins);
+ null, null, ins, false);
resources.bindParameter("fred", binding);
@@ -130,7 +130,7 @@
replay();
- ComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null, null, ins);
+ ComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, null, null, ins, false);
resources.storeRenderVariable("myRenderVar", value);
@@ -160,7 +160,7 @@
replay();
ComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar", null,
- ins);
+ ins, false);
resources.storeRenderVariable("fred", "FRED");
resources.storeRenderVariable("barney", "BARNEY");
@@ -195,7 +195,7 @@
replay();
InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar",
- null, ins);
+ null, ins, false);
resources.storeRenderVariable("fred", "FRED");
resources.storeRenderVariable("barney", "BARNEY");
@@ -231,7 +231,7 @@
replay();
InternalComponentResources resources = new InternalComponentResourcesImpl(null, element, null, null, "Foo.bar",
- null, ins);
+ null, ins, false);
try
@@ -265,7 +265,7 @@
replay();
InternalComponentResources resources = new InternalComponentResourcesImpl(page, element, null, null, null,
- null, ins);
+ null, ins, false);
resources.addPageLifecycleListener(listener);