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 2006/12/20 19:06:40 UTC
svn commit: r489162 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/ main/java/org/apache/tapestry/annotations/
main/java/org/apache/tapestry/corelib/base/
main/java/org/apache/tapestry/corelib/mixins/ main/java/org/apac...
Author: hlship
Date: Wed Dec 20 10:06:37 2006
New Revision: 489162
URL: http://svn.apache.org/viewvc?view=rev&rev=489162
Log:
Remove the PreBeginRender and PostBeginRender annotations and render phases.
Add the MixinAfter annotation and support, to allow a Mixin to operate after the component (not before) during rendering.
Add InjectComponent annotation, which allows a Mixin to see the component to which it is attached.
Create a RenderDisabled mixin, that attaches to Field components, that will render the disabled attribute if the field is disabled.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/FieldValidator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/InjectComponent.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/MixinAfter.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MixinAfterWorker.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinAfterWorkerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.html
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/PostBeginRender.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/PreBeginRender.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java
tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/FieldValidator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/FieldValidator.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/FieldValidator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/FieldValidator.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,36 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry;
+
+/**
+ * Responsible for validation of a single field.
+ *
+ * @param <T>
+ * @see Validator
+ */
+public interface FieldValidator<T>
+{
+ /**
+ * Invoked after the client-submitted value has been {@link Translator translated} to check that
+ * the value conforms to expectations (often, in terms of minimum or maximum value). If and only
+ * if the value is approved by all Validators is the value applied by the field.
+ *
+ * @param value
+ * the translated value supplied by the user
+ * @throws ValidationException
+ * if the value violates the constraint
+ */
+ void check(T value) throws ValidationException;
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/Validator.java Wed Dec 20 10:06:37 2006
@@ -14,22 +14,40 @@
package org.apache.tapestry;
-import sun.security.validator.ValidatorException;
+import org.apache.tapestry.ioc.Messages;
/**
* Used by a {@link Field} to enforce a <strong>constraint</strong> related to a form submission.
+ * Validators themselves are stateless singletons.
+ * <p>
+ * Validators are usually encapsulated inside a {@link FieldValidator}.
*/
-public interface Validator<T>
+public interface Validator<C, T>
{
/**
+ * Returns the type of constraint value used with this validator. Constraint values are used to
+ * parameterize a validator, for example a "maxLength" validator will have a constraint value of
+ * type int (the maximum length allowed). For constraints that do not have a constraint value,
+ * this method returns void.class.
+ */
+ public Class<C> getConstraintType();
+
+ /**
* Invoked after the client-submitted value has been {@link Translator translated} to check that
* the value conforms to expectations (often, in terms of minimum or maximum value). If and only
* if the value is approved by all Validators is the value applied by the field.
*
* @param field
* the field for which a client submitted value is being validated
+ * @param constraintValue
+ * the value used to constrain
+ * @param messages
+ * Validation messages, in the appropriate locale
* @param value
- * @throws ValidatorException
+ * the translated value supplied by the user
+ * @throws ValidationException
+ * if the value violates the constraint
*/
- void check(Field field, T value) throws ValidatorException;
+ void check(Field field, C constraintValue, Messages messages, T value)
+ throws ValidationException;
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/InjectComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/InjectComponent.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/InjectComponent.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/InjectComponent.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Used exclusively inside a mixin to connect the mixin to the component to which it is attached.
+ */
+@Target(FIELD)
+@Documented
+@Retention(RUNTIME)
+public @interface InjectComponent {
+
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/MixinAfter.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/MixinAfter.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/MixinAfter.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/MixinAfter.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * A marker annotation applied to a mixin to indicate that the mixin's render state behavior is
+ * deferred until after the the behavior of the component to which the mixin is attached. Normally,
+ * mixins occur before the component. This divides each phase in the render state machine into three
+ * virtual phases: before the component, the component itself, and after the component.
+ */
+@Target(TYPE)
+@Documented
+@Retention(RUNTIME)
+@Inherited
+public @interface MixinAfter {
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java Wed Dec 20 10:06:37 2006
@@ -19,14 +19,13 @@
import org.apache.tapestry.ComponentAction;
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.Field;
-import org.apache.tapestry.MarkupWriter;
import org.apache.tapestry.annotations.ComponentClass;
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.Mixin;
import org.apache.tapestry.annotations.Parameter;
-import org.apache.tapestry.annotations.PostBeginRender;
import org.apache.tapestry.annotations.SetupRender;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
import org.apache.tapestry.corelib.mixins.RenderInformals;
import org.apache.tapestry.internal.services.FormParameterLookup;
import org.apache.tapestry.ioc.internal.util.InternalUtils;
@@ -54,6 +53,10 @@
@Mixin
private RenderInformals _renderInformals;
+ @SuppressWarnings("unused")
+ @Mixin
+ private RenderDisabled _renderDisabled;
+
static class SetupAction implements ComponentAction<AbstractField>, Serializable
{
private static final long serialVersionUID = 2690270808212097020L;
@@ -113,13 +116,6 @@
_formSupport.storeAndExecute(this, new SetupAction(elementName));
_formSupport.store(this, PROCESS_SUBMISSION_ACTION);
- }
-
- @PostBeginRender
- final void renderDisabledAttribute(MarkupWriter writer)
- {
- if (_disabled)
- writer.attributes("disabled", "disabled");
}
public final String getClientId()
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderDisabled.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,37 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.mixins;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.BeginRender;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.InjectComponent;
+import org.apache.tapestry.annotations.MixinAfter;
+
+@ComponentClass
+@MixinAfter
+public class RenderDisabled
+{
+ @InjectComponent
+ private Field _field;
+
+ @BeginRender
+ void begin(MarkupWriter writer)
+ {
+ if (_field.isDisabled())
+ writer.attributes("disabled", "disabled");
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/corelib/mixins/RenderInformals.java Wed Dec 20 10:06:37 2006
@@ -21,7 +21,7 @@
import org.apache.tapestry.annotations.BeginRender;
import org.apache.tapestry.annotations.ComponentClass;
import org.apache.tapestry.annotations.Inject;
-import org.apache.tapestry.annotations.PostBeginRender;
+import org.apache.tapestry.annotations.MixinAfter;
import org.apache.tapestry.annotations.SupportsInformalParameters;
/**
@@ -38,13 +38,14 @@
* This is often used as a base class, for cases where a component doesn't have other mixins.
*/
@ComponentClass
+@MixinAfter
@SupportsInformalParameters
public class RenderInformals
{
@Inject
private ComponentResources _resources;
- @PostBeginRender
+ @BeginRender
void write(MarkupWriter writer)
{
_resources.renderInformalParameters(writer);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/InternalComponentResources.java Wed Dec 20 10:06:37 2006
@@ -12,52 +12,58 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.internal;
-
-import org.apache.tapestry.ComponentResources;
-
-/**
- * An extension of {@link org.apache.tapestry.ComponentResources} that represents additional methods
- * that are private to the framework and not exposed in any public APIs. Ideally, there will not be
- * any need for this interface (we'll see as we go).
- */
-public interface InternalComponentResources extends ComponentResources,
- InternalComponentResourcesCommon
-{
- /**
- * Reads the value of a parameter, via the parameter's {@link org.apache.tapestry.services.Binding}.
- *
- * @param <T>
- * @param parameterName
- * the name of the parameter to read
- * @param expectedType
- * the expected type of parameter
- * @return the value for the parameter, or null if the parameter is not bound.
- */
- <T> T readParameter(String parameterName, Class<T> expectedType);
-
- /**
- * Updates a parameter. It is an error to update a parameter which is not bound. The parameter
- * {@link org.apache.tapestry.services.Binding binding} may also not support updates.
- *
- * @param <T>
- * @param parameterName
- * of parameter to update
- * @param parameterValue
- * new value (which may be null)
- */
- <T> void writeParameter(String parameterName, T parameterValue);
-
- /**
- * Returns true if the named parameter's {@link org.apache.tapestry.services.Binding} is invariant, false
- * if otherwise, or if the parameter is not bound. Invariant bindings are cached more
- * aggresively than variant bindings.
- *
- * @param parameterName
- * the name of parameter to check for invariance
- * @return
- */
- boolean isInvariant(String parameterName);
-
-
-}
+package org.apache.tapestry.internal;
+
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.runtime.Component;
+
+/**
+ * An extension of {@link org.apache.tapestry.ComponentResources} that represents additional methods
+ * that are private to the framework and not exposed in any public APIs. Ideally, there will not be
+ * any need for this interface (we'll see as we go).
+ */
+public interface InternalComponentResources extends ComponentResources,
+ InternalComponentResourcesCommon
+{
+ /**
+ * Reads the value of a parameter, via the parameter's
+ * {@link org.apache.tapestry.services.Binding}.
+ *
+ * @param <T>
+ * @param parameterName
+ * the name of the parameter to read
+ * @param expectedType
+ * the expected type of parameter
+ * @return the value for the parameter, or null if the parameter is not bound.
+ */
+ <T> T readParameter(String parameterName, Class<T> expectedType);
+
+ /**
+ * Updates a parameter. It is an error to update a parameter which is not bound. The parameter
+ * {@link org.apache.tapestry.services.Binding binding} may also not support updates.
+ *
+ * @param <T>
+ * @param parameterName
+ * of parameter to update
+ * @param parameterValue
+ * new value (which may be null)
+ */
+ <T> void writeParameter(String parameterName, T parameterValue);
+
+ /**
+ * Returns true if the named parameter's {@link org.apache.tapestry.services.Binding} is
+ * invariant, false if otherwise, or if the parameter is not bound. Invariant bindings are
+ * cached more aggresively than variant bindings.
+ *
+ * @param parameterName
+ * the name of parameter to check for invariance
+ * @return
+ */
+ boolean isInvariant(String parameterName);
+
+ /**
+ * For a normal component, the same as {@link #getComponent()}, but for a mixin, returns the
+ * component to which the mixin is attached.
+ */
+ Component getCoreComponent();
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/model/MutableComponentModelImpl.java Wed Dec 20 10:06:37 2006
@@ -58,6 +58,8 @@
private boolean _informalParametersSupported;
+ private boolean _mixinAfter;
+
public MutableComponentModelImpl(String componentClassName, Log log, Resource baseResource,
ComponentModel parentModel)
{
@@ -263,6 +265,16 @@
public ComponentModel getParentModel()
{
return _parentModel;
+ }
+
+ public boolean isMixinAfter()
+ {
+ return _mixinAfter;
+ }
+
+ public void setMixinAfter(boolean mixinAfter)
+ {
+ _mixinAfter = mixinAfter;
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/InjectComponentWorker.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,88 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import java.util.List;
+
+import org.apache.tapestry.annotations.InjectComponent;
+import org.apache.tapestry.ioc.util.BodyBuilder;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+import org.apache.tapestry.services.TransformConstants;
+
+/**
+ * Identifies the {@link InjectComponent} annotation and adds code to initialize it to the core
+ * component.
+ */
+public class InjectComponentWorker implements ComponentClassTransformWorker
+{
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ List<String> names = transformation.findFieldsWithAnnotation(InjectComponent.class);
+
+ if (names.isEmpty())
+ return;
+
+ // I can't imagine a scenario where a component would have more than one
+ // field with InjectComponent, but that's the way these APIs work, lists of names.
+
+ BodyBuilder builder = new BodyBuilder();
+ builder.begin();
+
+ builder.addln("%s core = %s.getCoreComponent();", Component.class.getName(), transformation
+ .getResourcesFieldName());
+
+ for (String fieldName : names)
+ {
+ InjectComponent annotation = transformation.getFieldAnnotation(
+ fieldName,
+ InjectComponent.class);
+
+ String fieldType = transformation.getFieldType(fieldName);
+
+ builder.addln("try");
+ builder.begin();
+ builder.addln("%s = (%s) core;", fieldName, fieldType);
+ builder.end();
+ builder.addln("catch (ClassCastException ex)");
+ builder.begin();
+ builder.addln(
+ "String message = %s.buildCastExceptionMessage(core, \"%s.%s\", \"%s\");",
+ InjectComponentWorker.class.getName(),
+ model.getComponentClassName(),
+ fieldName,
+ fieldType);
+ builder.addln("throw new RuntimeException(message, ex);");
+ builder.end();
+
+ transformation.makeReadOnly(fieldName);
+ transformation.claimField(fieldName, annotation);
+ }
+
+ builder.end();
+
+ transformation.extendMethod(TransformConstants.CONTAINING_PAGE_DID_LOAD_SIGNATURE, builder
+ .toString());
+ }
+
+ public static String buildCastExceptionMessage(Component component, String fieldName,
+ String fieldType)
+ {
+ return ServicesMessages.componentNotAssignableToField(component, fieldName, fieldType);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MixinAfterWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MixinAfterWorker.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MixinAfterWorker.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/MixinAfterWorker.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,36 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotations.MixinAfter;
+import org.apache.tapestry.model.ComponentModel;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.apache.tapestry.services.ComponentClassTransformWorker;
+
+/**
+ * Looks for the {@link MixinAfter} annotatation and sets the
+ * {@link ComponentModel#isMixinAfter() mixinAfter flag} is present.
+ */
+public class MixinAfterWorker implements ComponentClassTransformWorker
+{
+
+ public void transform(ClassTransformation transformation, MutableComponentModel model)
+ {
+ if (transformation.getAnnotation(MixinAfter.class) != null)
+ model.setMixinAfter(true);
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Wed Dec 20 10:06:37 2006
@@ -265,4 +265,11 @@
{
return MESSAGES.format("wrong-asset-digest", resource.getPath());
}
+
+ static String componentNotAssignableToField(Component component, String fieldName,
+ String fieldType)
+ {
+ return MESSAGES.format("component-not-assignable-to-field", component
+ .getComponentResources().getCompleteId(), fieldName, fieldType);
+ }
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Wed Dec 20 10:06:37 2006
@@ -127,7 +127,7 @@
invoke(true, callback);
if (event.getResult())
- queue.push(_preBeginRender);
+ queue.push(_beginRender);
}
@Override
@@ -253,6 +253,7 @@
{
public void render(final MarkupWriter writer, final RenderQueue queue)
{
+
final LifecycleEvent<Boolean> event = newEvent(true);
ComponentCallback callback = new ComponentCallback()
@@ -265,8 +266,16 @@
invoke(false, callback);
+ // If the component has no template whatsoever, then a
+ // renderBody element is added as the lone element of the component's template.
+ // So every component will have a non-empty template.
+
if (event.getResult())
- queue.push(_postBeginRender);
+ {
+ queue.push(_afterRender);
+ queue.push(_beforeRenderTemplate);
+ }
+
}
@Override
@@ -324,8 +333,9 @@
private final String _completeId;
- // The user-provided class, with runtime code enhancements.
- private final Component _component;
+ // The user-provided class, with runtime code enhancements. In a component with mixins, this
+ // is the component to which the mixins are attached.
+ private final Component _coreComponent;
private final ComponentMessagesSource _messagesSource;
@@ -353,67 +363,6 @@
private final Page _page;
- private final RenderCommand _postBeginRender = new RenderCommand()
- {
- public void render(final MarkupWriter writer, final RenderQueue queue)
- {
- final LifecycleEvent<Boolean> event = newEvent(true);
-
- ComponentCallback callback = new ComponentCallback()
- {
- public void run(Component component)
- {
- component.postBeginRender(writer, event);
- }
- };
-
- invoke(false, callback);
-
- // If the component has no template whatsoever, then a
- // renderBody element is added as the lone element of the component's template.
- // So every component will have a non-empty template.
-
- if (event.getResult())
- {
- queue.push(_afterRender);
- queue.push(_beforeRenderTemplate);
- }
- }
-
- @Override
- public String toString()
- {
- return phaseToString("PostBeginRender");
- }
- };
-
- private final RenderCommand _preBeginRender = new RenderCommand()
- {
- public void render(final MarkupWriter writer, final RenderQueue queue)
- {
- final LifecycleEvent<Boolean> event = newEvent(true);
-
- ComponentCallback callback = new ComponentCallback()
- {
- public void run(Component component)
- {
- component.preBeginRender(writer, event);
- }
- };
-
- invoke(false, callback);
-
- if (event.getResult())
- queue.push(_beginRender);
- }
-
- @Override
- public String toString()
- {
- return phaseToString("PreBeginRender");
- }
- };
-
private boolean _rendering;
private final RenderCommand _setupRender = new RenderCommand()
@@ -437,7 +386,7 @@
queue.push(_cleanupRender);
if (event.getResult())
- queue.push(_preBeginRender);
+ queue.push(_beginRender);
}
@Override
@@ -490,9 +439,9 @@
_coreResources = new InternalComponentResourcesImpl(this, instantiator, _typeCoercer,
_messagesSource);
- _component = _coreResources.getComponent();
+ _coreComponent = _coreResources.getComponent();
- String componentClassName = _component.getClass().getName();
+ String componentClassName = _coreComponent.getClass().getName();
// A page (really, the root component of a page) does not have a container.
@@ -681,7 +630,35 @@
// mixins.
if (_components != null)
- _components.add(_component);
+ {
+ List<Component> ordered = newList();
+
+ Iterator<Component> i = _components.iterator();
+
+ // Add all the normal components to the final list.
+
+ while (i.hasNext())
+ {
+ Component mixin = i.next();
+
+ if (mixin.getComponentResources().getComponentModel().isMixinAfter())
+ continue;
+
+ ordered.add(mixin);
+
+ // Remove from list, leaving just the late executing mixins
+
+ i.remove();
+ }
+
+ ordered.add(_coreComponent);
+
+ // Add the remaining, late executing mixins
+
+ ordered.addAll(_components);
+
+ _components = ordered;
+ }
invoke(false, CONTAINING_PAGE_DID_LOAD);
}
@@ -711,7 +688,7 @@
public Component getComponent()
{
- return _component;
+ return _coreComponent;
}
public InternalComponentResources getComponentResources()
@@ -798,7 +775,7 @@
// Simple case: no mixins
if (_components == null)
- return _component.handleComponentEvent(event);
+ return _coreComponent.handleComponentEvent(event);
// Otherwise, iterate over mixins + core component
@@ -836,7 +813,7 @@
if (_components == null)
{
- callback.run(_component);
+ callback.run(_coreComponent);
return;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Wed Dec 20 10:06:37 2006
@@ -38,7 +38,6 @@
* resources to the component, including access to its parameters, parameter bindings, and
* persistent field data.
*/
-
public class InternalComponentResourcesImpl implements InternalComponentResources
{
private final ComponentModel _componentModel;
@@ -260,6 +259,11 @@
_messages = _messagesSource.getMessages(_componentModel, getLocale());
return _messages;
+ }
+
+ public Component getCoreComponent()
+ {
+ return _element.getComponent();
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/ComponentModel.java Wed Dec 20 10:06:37 2006
@@ -18,6 +18,7 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.MixinAfter;
import org.apache.tapestry.annotations.Persist;
import org.apache.tapestry.annotations.SupportsInformalParameters;
import org.apache.tapestry.ioc.Resource;
@@ -116,4 +117,13 @@
* component class
*/
ComponentModel getParentModel();
+
+ /**
+ * Relevant for component mixins only. Indicates that the mixin behavior should occur
+ * <em>after</em> (not before) the component. Normally, this flag is set by the presence of
+ * the {@link MixinAfter} annotation.
+ *
+ * @return true if the mixin should operate after, not before, the component
+ */
+ boolean isMixinAfter();
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/model/MutableComponentModel.java Wed Dec 20 10:06:37 2006
@@ -12,62 +12,68 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.model;
-
-import org.apache.tapestry.annotations.Persist;
-import org.apache.tapestry.internal.InternalComponentResources;
-
-/**
- * Mutable version of {@link org.apache.tapestry.model.ComponentModel} used during the
- * transformation phase.
- */
-public interface MutableComponentModel extends ComponentModel
-{
- /**
- * Adds a new parameter to the model.
- *
- * @param name
- * new, unique n`ame for the parameter
- * @param required
- * if true, the parameter must be bound
- * @throws IllegalArgumentException
- * if a parameter with the given name has already been defined for this model
- */
- void addParameter(String name, boolean required);
-
- /**
- * Defines a new embedded component.
- *
- * @param id
- * the unique id for the embedded component, which must not already exist.
- * @param type
- * the type of the component (posslibly blank)
- * @param componentClassName
- * the fully qualified class name (derived from the field), used if the type is blank
- * @return a mutable model allowing parameters to be set
- */
- MutableEmbeddedComponentModel addEmbeddedComponent(String id, String type,
- String componentClassName);
-
- /**
- * Used to define the field persistence strategy for a particular field name. Returns a logical
- * name for the field, which is guaranteed to be unique (this is necessary for handling the case
- * where a subclass has a persistent field with the same name as a persistent field from a
- * super-class).
- *
- * @param fieldName
- * the name of the field which is to be made persistent
- * @param strategy
- * the strategy for persisting the field, from {@link Persist#value()}
- * @return a logical name for the field, to be used with
- * {@link ComponentModel#getFieldPersistenceStrategy(String)}, and with
- * {@link InternalComponentResources#persistFieldChange(String, Object)}, etc.
- */
- String setFieldPersistenceStrategy(String fieldName, String strategy);
-
- /** Adds a mixin to the component's implementation. */
- void addMixinClassName(String mixinClassName);
-
- /** Sets the internal flag to indicate that this model (and all models that extend from it) support informal parameters. */
- void enableSupportsInformalParameters();
-}
+package org.apache.tapestry.model;
+
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.internal.InternalComponentResources;
+
+/**
+ * Mutable version of {@link org.apache.tapestry.model.ComponentModel} used during the
+ * transformation phase.
+ */
+public interface MutableComponentModel extends ComponentModel
+{
+ /**
+ * Adds a new parameter to the model.
+ *
+ * @param name
+ * new, unique n`ame for the parameter
+ * @param required
+ * if true, the parameter must be bound
+ * @throws IllegalArgumentException
+ * if a parameter with the given name has already been defined for this model
+ */
+ void addParameter(String name, boolean required);
+
+ /**
+ * Defines a new embedded component.
+ *
+ * @param id
+ * the unique id for the embedded component, which must not already exist.
+ * @param type
+ * the type of the component (posslibly blank)
+ * @param componentClassName
+ * the fully qualified class name (derived from the field), used if the type is blank
+ * @return a mutable model allowing parameters to be set
+ */
+ MutableEmbeddedComponentModel addEmbeddedComponent(String id, String type,
+ String componentClassName);
+
+ /**
+ * Used to define the field persistence strategy for a particular field name. Returns a logical
+ * name for the field, which is guaranteed to be unique (this is necessary for handling the case
+ * where a subclass has a persistent field with the same name as a persistent field from a
+ * super-class).
+ *
+ * @param fieldName
+ * the name of the field which is to be made persistent
+ * @param strategy
+ * the strategy for persisting the field, from {@link Persist#value()}
+ * @return a logical name for the field, to be used with
+ * {@link ComponentModel#getFieldPersistenceStrategy(String)}, and with
+ * {@link InternalComponentResources#persistFieldChange(String, Object)}, etc.
+ */
+ String setFieldPersistenceStrategy(String fieldName, String strategy);
+
+ /** Adds a mixin to the component's implementation. */
+ void addMixinClassName(String mixinClassName);
+
+ /**
+ * Sets the internal flag to indicate that this model (and all models that extend from it)
+ * support informal parameters.
+ */
+ void enableSupportsInformalParameters();
+
+ /** Changes the value of the mixinAfter flag. The default value is false. */
+ void setMixinAfter(boolean mixinAfter);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/runtime/Component.java Wed Dec 20 10:06:37 2006
@@ -12,88 +12,76 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.runtime;
-
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.annotations.OnEvent;
-
-/**
- * Interface that defining the lifecycle of a component, within a page, allowing for callbacks into
- * the component for many different events. This interface is part of the public API for Tapestry,
- * but is <em>not</em> expected to be directly implemented by component classes; it should only be
- * implemented as part of the component class transformation process.
- * <p>
- * Most of the methods are related to render phases; see the corresponding annotations and component
- * rendering documentation to see how they relate to each other.
- * <p>
- * This interface is likely to change without notice.
- */
-public interface Component extends ComponentResourcesAware, PageLifecycleListener
-{
-
- /**
- * Lifecycle method invoked at the end of the
- * {@link org.apache.tapestry.annotations.CleanupRender} render phase. There is no annotation
- * for this method, it is part of CleanupRender, but is always invoked. Its specific use is to
- * allow components to clean up cached parameter values.
- */
- void postRenderCleanup();
-
- /**
- * Invoked before rendering a component (or its template).
- */
- void setupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Invoked just before {@link #beginRender(MarkupWriter, LifecycleEvent)
- */
-
- void preBeginRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Invoked to allow a component to render its tag (start tag and attributes).
- */
- void beginRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Invoked just after {@link #beginRender(MarkupWriter, LifecycleEvent)}, typically to allow a
- * mixin to write additional attributes into the component's tag.
- */
- void postBeginRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * This phase is only invoked for components with templates.
- */
- void beforeRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /** Invoked after rendering the template for a component (only for components with a template). */
- void afterRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Invoked just before rendering the body of component.
- */
- void beforeRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /** Invoked just after rendering the body of the component. */
- void afterRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Generally used to write the close tag matching any open tag written by
- * {@link #beginRender(MarkupWriter, LifecycleEvent)}.
- */
- void afterRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Generally used to perform final cleanup of the component after rendering.
- */
- void cleanupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
-
- /**
- * Invoked to handle a component event. Methods with the {@link OnEvent} annotation will be
- * invoked until one returns a non-null value.
- *
- * @param event
- * @return true if any handler was found (and invoked), false otherwise
- */
- boolean handleComponentEvent(ComponentEvent event);
-}
+package org.apache.tapestry.runtime;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.annotations.OnEvent;
+
+/**
+ * Interface that defining the lifecycle of a component, within a page, allowing for callbacks into
+ * the component for many different events. This interface is part of the public API for Tapestry,
+ * but is <em>not</em> expected to be directly implemented by component classes; it should only be
+ * implemented as part of the component class transformation process.
+ * <p>
+ * Most of the methods are related to render phases; see the corresponding annotations and component
+ * rendering documentation to see how they relate to each other.
+ * <p>
+ * This interface is likely to change without notice.
+ */
+public interface Component extends ComponentResourcesAware, PageLifecycleListener
+{
+
+ /**
+ * Lifecycle method invoked at the end of the
+ * {@link org.apache.tapestry.annotations.CleanupRender} render phase. There is no annotation
+ * for this method, it is part of CleanupRender, but is always invoked. Its specific use is to
+ * allow components to clean up cached parameter values.
+ */
+ void postRenderCleanup();
+
+ /**
+ * Invoked before rendering a component (or its template).
+ */
+ void setupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * Invoked to allow a component to render its tag (start tag and attributes).
+ */
+ void beginRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * This phase is only invoked for components with templates.
+ */
+ void beforeRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /** Invoked after rendering the template for a component (only for components with a template). */
+ void afterRenderTemplate(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * Invoked just before rendering the body of component.
+ */
+ void beforeRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /** Invoked just after rendering the body of the component. */
+ void afterRenderBody(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * Generally used to write the close tag matching any open tag written by
+ * {@link #beginRender(MarkupWriter, LifecycleEvent)}.
+ */
+ void afterRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * Generally used to perform final cleanup of the component after rendering.
+ */
+ void cleanupRender(MarkupWriter writer, LifecycleEvent<Boolean> event);
+
+ /**
+ * Invoked to handle a component event. Methods with the {@link OnEvent} annotation will be
+ * invoked until one returns a non-null value.
+ *
+ * @param event
+ * @return true if any handler was found (and invoked), false otherwise
+ */
+ boolean handleComponentEvent(ComponentEvent event);
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Wed Dec 20 10:06:37 2006
@@ -36,8 +36,6 @@
import org.apache.tapestry.annotations.BeginRender;
import org.apache.tapestry.annotations.CleanupRender;
import org.apache.tapestry.annotations.InjectPage;
-import org.apache.tapestry.annotations.PostBeginRender;
-import org.apache.tapestry.annotations.PreBeginRender;
import org.apache.tapestry.annotations.SetupRender;
import org.apache.tapestry.internal.InternalConstants;
import org.apache.tapestry.internal.bindings.ComponentBindingFactory;
@@ -70,11 +68,13 @@
import org.apache.tapestry.internal.services.InfrastructureImpl;
import org.apache.tapestry.internal.services.InfrastructureManagerImpl;
import org.apache.tapestry.internal.services.InjectAnonymousWorker;
+import org.apache.tapestry.internal.services.InjectComponentWorker;
import org.apache.tapestry.internal.services.InjectNamedWorker;
import org.apache.tapestry.internal.services.InjectPageWorker;
import org.apache.tapestry.internal.services.InternalModule;
import org.apache.tapestry.internal.services.LinkFactory;
import org.apache.tapestry.internal.services.MarkupWriterImpl;
+import org.apache.tapestry.internal.services.MixinAfterWorker;
import org.apache.tapestry.internal.services.MixinWorker;
import org.apache.tapestry.internal.services.OnEventWorker;
import org.apache.tapestry.internal.services.PageLinkHandler;
@@ -608,6 +608,7 @@
new InjectAnonymousWorker(locator, injectionProvider),
"after:InjectNamed");
configuration.add("AssetInject", new AssetInjectWorker(assetSource), "before:InjectNamed");
+ configuration.add("MixinAfter", new MixinAfterWorker());
configuration.add("Parameter", new ParameterWorker());
configuration.add("Component", new ComponentWorker(resolver));
@@ -616,22 +617,13 @@
configuration.add("OnEvent", new OnEventWorker());
configuration.add("SupportsInformalParameters", new SupportsInformalParametersWorker());
configuration.add("InjectPage", new InjectPageWorker(requestPageCache));
+ configuration.add("InjectComponent", new InjectComponentWorker());
// Workers for the component rendering state machine methods; this is in typical
// execution order.
add(configuration, TransformConstants.SETUP_RENDER_SIGNATURE, SetupRender.class, false);
- add(
- configuration,
- TransformConstants.PRE_BEGIN_RENDER_SIGNATURE,
- PreBeginRender.class,
- false);
add(configuration, TransformConstants.BEGIN_RENDER_SIGNATURE, BeginRender.class, false);
- add(
- configuration,
- TransformConstants.POST_BEGIN_RENDER_SIGNATURE,
- PostBeginRender.class,
- false);
add(
configuration,
TransformConstants.BEFORE_RENDER_TEMPLATE_SIGNATURE,
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TransformConstants.java Wed Dec 20 10:06:37 2006
@@ -12,148 +12,131 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry.services;
-
-import java.lang.reflect.Modifier;
-
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.annotations.PostBeginRender;
-import org.apache.tapestry.annotations.PreBeginRender;
-import org.apache.tapestry.runtime.Component;
-import org.apache.tapestry.runtime.ComponentEvent;
-import org.apache.tapestry.runtime.LifecycleEvent;
-
-/**
- * Constants used by implementations of
- * {@link org.apache.tapestry.services.ComponentClassTransformWorker}.
- */
-public final class TransformConstants
-{
- // Shared parameters of a whole bunch of lifecycle methods, representing the different
- // component render states.
- private static final String[] RENDER_PHASE_METHOD_PARAMETERS =
- { MarkupWriter.class.getName(), LifecycleEvent.class.getName() };
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#handleComponentEvent(ComponentEvent event)
- *
- * @see org.apache.tapestry.annotations.OnEvent
- */
- public static final MethodSignature HANDLE_COMPONENT_EVENT = new MethodSignature(
- Modifier.PUBLIC, "boolean", "handleComponentEvent", new String[]
- { ComponentEvent.class.getName() }, null);
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()}.
- */
- public static final MethodSignature CONTAINING_PAGE_DID_LOAD_SIGNATURE = new MethodSignature(
- "containingPageDidLoad");
-
- /** Signature for {@link org.apache.tapestry.runtime.Component#postRenderCleanup()}. */
- public static final MethodSignature POST_RENDER_CLEANUP_SIGNATURE = new MethodSignature(
- "postRenderCleanup");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidDetach()}.
- */
- public static final MethodSignature CONTAINING_PAGE_DID_DETACH_SIGNATURE = new MethodSignature(
- "containingPageDidDetach");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidAttach()}.
- */
- public static final MethodSignature CONTAINING_PAGE_DID_ATTACH_SIGNATURE = new MethodSignature(
- "containingPageDidAttach");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#setupRender(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.SetupRender
- */
- public static final MethodSignature SETUP_RENDER_SIGNATURE = renderPhaseSignature("setupRender");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#beginRender(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.BeginRender
- */
- public static final MethodSignature BEGIN_RENDER_SIGNATURE = renderPhaseSignature("beginRender");
-
- /**
- * Signature for {@link Component#preBeginRender(MarkupWriter, LifecycleEvent)}.
- *
- * @see PreBeginRender
- */
- public static final MethodSignature PRE_BEGIN_RENDER_SIGNATURE = renderPhaseSignature("preBeginRender");
-
-
- /** Signature for {@link Component#postBeginRender(MarkupWriter, LifecycleEvent)}.
- *
- * @see PostBeginRender
- */
- public static final MethodSignature POST_BEGIN_RENDER_SIGNATURE = renderPhaseSignature("postBeginRender");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#beforeRenderTemplate(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.BeforeRenderTemplate
- */
- public static MethodSignature BEFORE_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature("beforeRenderTemplate");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#afterRenderTemplate(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.BeforeRenderTemplate
- */
- public static MethodSignature AFTER_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature("afterRenderTemplate");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#beforeRenderBody(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.BeforeRenderBody
- */
- public static final MethodSignature BEFORE_RENDER_BODY_SIGNATURE = renderPhaseSignature("beforeRenderBody");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#afterRenderBody(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.AfterRenderBody
- */
- public static final MethodSignature AFTER_RENDER_BODY_SIGNATURE = renderPhaseSignature("afterRenderBody");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#afterRender(MarkupWriter, LifecycleEvent)}
- *
- * @see org.apache.tapestry.annotations.AfterRender
- */
- public static final MethodSignature AFTER_RENDER_SIGNATURE = renderPhaseSignature("afterRender");
-
- /**
- * Signature for
- * {@link org.apache.tapestry.runtime.Component#cleanupRender(MarkupWriter, LifecycleEvent)}.
- *
- * @see org.apache.tapestry.annotations.CleanupRender
- */
- public static final MethodSignature CLEANUP_RENDER_SIGNATURE = renderPhaseSignature("cleanupRender");
-
- private TransformConstants()
- {
- }
-
- private static MethodSignature renderPhaseSignature(String name)
- {
- return new MethodSignature(Modifier.PUBLIC, "void", name, RENDER_PHASE_METHOD_PARAMETERS,
- null);
- }
-}
+package org.apache.tapestry.services;
+
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry.MarkupWriter;
+import org.apache.tapestry.runtime.ComponentEvent;
+import org.apache.tapestry.runtime.LifecycleEvent;
+
+/**
+ * Constants used by implementations of
+ * {@link org.apache.tapestry.services.ComponentClassTransformWorker}.
+ */
+public final class TransformConstants
+{
+ // Shared parameters of a whole bunch of lifecycle methods, representing the different
+ // component render states.
+ private static final String[] RENDER_PHASE_METHOD_PARAMETERS =
+ { MarkupWriter.class.getName(), LifecycleEvent.class.getName() };
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#handleComponentEvent(ComponentEvent event)
+ *
+ * @see org.apache.tapestry.annotations.OnEvent
+ */
+ public static final MethodSignature HANDLE_COMPONENT_EVENT = new MethodSignature(
+ Modifier.PUBLIC, "boolean", "handleComponentEvent", new String[]
+ { ComponentEvent.class.getName() }, null);
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidLoad()}.
+ */
+ public static final MethodSignature CONTAINING_PAGE_DID_LOAD_SIGNATURE = new MethodSignature(
+ "containingPageDidLoad");
+
+ /** Signature for {@link org.apache.tapestry.runtime.Component#postRenderCleanup()}. */
+ public static final MethodSignature POST_RENDER_CLEANUP_SIGNATURE = new MethodSignature(
+ "postRenderCleanup");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidDetach()}.
+ */
+ public static final MethodSignature CONTAINING_PAGE_DID_DETACH_SIGNATURE = new MethodSignature(
+ "containingPageDidDetach");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.PageLifecycleListener#containingPageDidAttach()}.
+ */
+ public static final MethodSignature CONTAINING_PAGE_DID_ATTACH_SIGNATURE = new MethodSignature(
+ "containingPageDidAttach");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#setupRender(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.SetupRender
+ */
+ public static final MethodSignature SETUP_RENDER_SIGNATURE = renderPhaseSignature("setupRender");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#beginRender(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.BeginRender
+ */
+ public static final MethodSignature BEGIN_RENDER_SIGNATURE = renderPhaseSignature("beginRender");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#beforeRenderTemplate(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.BeforeRenderTemplate
+ */
+ public static MethodSignature BEFORE_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature("beforeRenderTemplate");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#afterRenderTemplate(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.BeforeRenderTemplate
+ */
+ public static MethodSignature AFTER_RENDER_TEMPLATE_SIGNATURE = renderPhaseSignature("afterRenderTemplate");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#beforeRenderBody(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.BeforeRenderBody
+ */
+ public static final MethodSignature BEFORE_RENDER_BODY_SIGNATURE = renderPhaseSignature("beforeRenderBody");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#afterRenderBody(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.AfterRenderBody
+ */
+ public static final MethodSignature AFTER_RENDER_BODY_SIGNATURE = renderPhaseSignature("afterRenderBody");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#afterRender(MarkupWriter, LifecycleEvent)}
+ *
+ * @see org.apache.tapestry.annotations.AfterRender
+ */
+ public static final MethodSignature AFTER_RENDER_SIGNATURE = renderPhaseSignature("afterRender");
+
+ /**
+ * Signature for
+ * {@link org.apache.tapestry.runtime.Component#cleanupRender(MarkupWriter, LifecycleEvent)}.
+ *
+ * @see org.apache.tapestry.annotations.CleanupRender
+ */
+ public static final MethodSignature CLEANUP_RENDER_SIGNATURE = renderPhaseSignature("cleanupRender");
+
+ private TransformConstants()
+ {
+ }
+
+ private static MethodSignature renderPhaseSignature(String name)
+ {
+ return new MethodSignature(Modifier.PUBLIC, "void", name, RENDER_PHASE_METHOD_PARAMETERS,
+ null);
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties Wed Dec 20 10:06:37 2006
@@ -62,4 +62,5 @@
failure-reading-messages=Unable to read message catalog from %s: %s
unknown-asset-prefix=Unknown prefix for asset path '%s'.
asset-does-not-exist=Unable to locate asset '%s' (the file does not exist).
-wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests.
\ No newline at end of file
+wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests.
+component-not-assignable-to-field=Component %s is not assignable to field %s (of type %s).
\ No newline at end of file
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/index.html Wed Dec 20 10:06:37 2006
@@ -54,6 +54,9 @@
<li>
<a href="ExpansionSubclass.html">ExpansionSubclass</a> -- components can inherit templates from base classes
</li>
+ <li>
+ <a href="InjectComponentMismatch.html">InjectComponentMismatch</a> -- check error reporting when @InjectComponent doesn't match the actual field type
+ </li>
</ul>
</p>
</body>
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Dec 20 10:06:37 2006
@@ -21,6 +21,8 @@
import java.io.InputStream;
import java.net.URL;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+import org.apache.tapestry.internal.services.InjectComponentWorker;
import org.apache.tapestry.ioc.Resource;
import org.apache.tapestry.ioc.internal.util.ClasspathResource;
import org.openqa.selenium.server.SeleniumServer;
@@ -52,7 +54,7 @@
private SeleniumServer _server;
private JettyRunner _jettyRunner;
-
+
@BeforeClass
public void startupBackground() throws Exception
{
@@ -239,7 +241,7 @@
clickAndWait("link=Action Page");
assertFalse(_selenium.isTextPresent(YOU_CHOSE));
-
+
for (int i = 2; i < 5; i++)
{
clickAndWait("link=" + i);
@@ -370,6 +372,22 @@
byte[] actual = readContent(classpathResource.toURL());
assertEquals(downloaded, actual);
+ }
+
+ /**
+ * {@link InjectComponentWorker} is largely tested by the forms tests ({@link RenderDisabled}
+ * is built on it). This test is for the failure case, where a mixin class is used with the
+ * wrong type of component.
+ */
+ @Test
+ public void inject_component_failure() throws Exception
+ {
+ _selenium.open(BASE_URL);
+ clickAndWait("link=InjectComponentMismatch");
+
+ // And exception message:
+
+ assertTextPresent("Component org.apache.tapestry.integration.app1.pages.InjectComponentMismatch is not assignable to field org.apache.tapestry.corelib.mixins.RenderDisabled._field (of type org.apache.tapestry.Field).");
}
private byte[] readContent(URL url) throws Exception
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,32 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.integration.app1.pages;
+
+import org.apache.tapestry.Field;
+import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.annotations.Mixin;
+import org.apache.tapestry.corelib.mixins.RenderDisabled;
+
+@ComponentClass
+public class InjectComponentMismatch
+{
+ /**
+ * This mixin only works with components of type {@link Field}. That's the mismatch right
+ * there.
+ */
+ @SuppressWarnings("unused")
+ @Mixin
+ private RenderDisabled _renderDisabled;
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/bindings/DefaultComponent.java Wed Dec 20 10:06:37 2006
@@ -16,8 +16,8 @@
import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.runtime.ComponentEvent;
import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.runtime.ComponentEvent;
import org.apache.tapestry.runtime.LifecycleEvent;
/**
@@ -88,16 +88,4 @@
{
// TODO Auto-generated method stub
}
-
- public void postBeginRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
- {
- // TODO Auto-generated method stub
-
- }
-
- public void preBeginRender(MarkupWriter writer, LifecycleEvent<Boolean> event)
- {
- // TODO Auto-generated method stub
- }
-
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinAfterWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinAfterWorkerTest.java?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinAfterWorkerTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/MixinAfterWorkerTest.java Wed Dec 20 10:06:37 2006
@@ -0,0 +1,56 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.internal.services;
+
+import org.apache.tapestry.annotations.MixinAfter;
+import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.model.MutableComponentModel;
+import org.apache.tapestry.services.ClassTransformation;
+import org.testng.annotations.Test;
+
+public class MixinAfterWorkerTest extends InternalBaseTestCase
+{
+ @Test
+ public void annotation_not_present()
+ {
+ ClassTransformation transformation = newClassTransformation();
+ MutableComponentModel model = newMutableComponentModel();
+
+ train_getAnnotation(transformation, MixinAfter.class, null);
+
+ replay();
+
+ new MixinAfterWorker().transform(transformation, model);
+
+ verify();
+ }
+
+ @Test
+ public void annotation_present()
+ {
+ ClassTransformation transformation = newClassTransformation();
+ MutableComponentModel model = newMutableComponentModel();
+ MixinAfter annotation = newMock(MixinAfter.class);
+
+ train_getAnnotation(transformation, MixinAfter.class, annotation);
+ model.setMixinAfter(true);
+
+ replay();
+
+ new MixinAfterWorker().transform(transformation, model);
+
+ verify();
+ }
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties?view=diff&rev=489162&r1=489161&r2=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/log4j.properties Wed Dec 20 10:06:37 2006
@@ -28,4 +28,5 @@
log4j.category.app=info
log4j.category.org.apache.tapestry.integration.app1=debug
+log4j.category.org.apache.tapestry.corelib=debug
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.html?view=auto&rev=489162
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.html (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/resources/org/apache/tapestry/integration/app1/pages/InjectComponentMismatch.html Wed Dec 20 10:06:37 2006
@@ -0,0 +1,7 @@
+<t:comp type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <p>
+ This page should never be rendered because of the InjectComponent mismatch inside it.
+ </p>
+
+</t:comp>