Author: hlship Date: Mon May 2 17:37:43 2011 New Revision: 1098684 URL: http://svn.apache.org/viewvc?rev=1098684&view=rev Log: TAP5-1508: Re-implement PropertyWorker as ComponentClassTransformWorker2
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java?rev=1098684&r1=1098683&r2=1098684&view=diff ============================================================================== --- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java (original) +++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java Mon May 2 17:37:43 2011 @@ -1,4 +1,4 @@ -// Copyright 2008, 2010 The Apache Software Foundation +// Copyright 2008, 2010, 2011 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,93 +14,59 @@ package org.apache.tapestry5.internal.transform; -import java.lang.reflect.Modifier; - import org.apache.tapestry5.annotations.Property; -import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.model.MutableComponentModel; -import org.apache.tapestry5.services.ClassTransformation; -import org.apache.tapestry5.services.ComponentClassTransformWorker; -import org.apache.tapestry5.services.ComponentMethodAdvice; -import org.apache.tapestry5.services.ComponentMethodInvocation; -import org.apache.tapestry5.services.FieldAccess; -import org.apache.tapestry5.services.TransformField; -import org.apache.tapestry5.services.TransformMethodSignature; +import org.apache.tapestry5.plastic.PlasticClass; +import org.apache.tapestry5.plastic.PlasticField; +import org.apache.tapestry5.plastic.PropertyAccessType; +import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2; +import org.apache.tapestry5.services.transform.TransformationSupport; /** * Provides the getter and setter methods. The methods are added as "existing", meaning that field access to them will * be transformed as necessary by other annotations. This worker needs to be scheduled before any worker that might * delete a field. - * + * * @see org.apache.tapestry5.annotations.Property */ -public class PropertyWorker implements ComponentClassTransformWorker +public class PropertyWorker implements ComponentClassTransformWorker2 { - public void transform(ClassTransformation transformation, MutableComponentModel model) + + public void transform(PlasticClass plasticClass, TransformationSupport support, MutableComponentModel model) { - for (TransformField field : transformation.matchFieldsWithAnnotation(Property.class)) + for (PlasticField field : plasticClass.getFieldsWithAnnotation(Property.class)) { - createAccessorsForField(transformation, field); + createAccessorsForField(field); } } - private void createAccessorsForField(ClassTransformation transformation, TransformField field) + private void createAccessorsForField(PlasticField field) { - Property annotation = field.getAnnotation(Property.class); - - String propertyName = InternalUtils.capitalize(InternalUtils.stripMemberName(field.getName())); + PropertyAccessType accessType = toType(field); - if (annotation.read()) - addGetter(transformation, field, propertyName); + field.createAccessors(accessType); - if (annotation.write()) - addSetter(transformation, field, propertyName); + // TODO: Change createAccessors() to do a check that the methods do not already exist. } - private void addSetter(ClassTransformation transformation, TransformField field, String propertyName) + private PropertyAccessType toType(PlasticField field) { - TransformMethodSignature setter = new TransformMethodSignature(Modifier.PUBLIC, "void", "set" + propertyName, - new String[] - { field.getType() }, null); - - ensureNotOverride(transformation, setter); - - final FieldAccess access = field.getAccess(); - - transformation.getOrCreateMethod(setter).addAdvice(new ComponentMethodAdvice() - { - public void advise(ComponentMethodInvocation invocation) - { - access.write(invocation.getInstance(), invocation.getParameter(0)); - } - }); - } + Property annotation = field.getAnnotation(Property.class); - private void ensureNotOverride(ClassTransformation transformation, TransformMethodSignature signature) - { - if (transformation.isDeclaredMethod(signature)) - throw new RuntimeException(String.format( - "Unable to create new method %s as it already exists in class %s.", signature, transformation - .getClassName())); - } + boolean read = annotation.read(); + boolean write = annotation.write(); - private void addGetter(ClassTransformation transformation, TransformField field, String propertyName) - { - final String methodSignature = field.getSignature() != null ? "()" + field.getSignature() : null; - TransformMethodSignature getter = - new TransformMethodSignature(Modifier.PUBLIC, field.getType(), methodSignature, - "get" + propertyName, null, null); + if (read && write) + return PropertyAccessType.READ_WRITE; - ensureNotOverride(transformation, getter); + if (read) + return PropertyAccessType.READ_ONLY; - final FieldAccess access = field.getAccess(); + if (write) + return PropertyAccessType.WRITE_ONLY; - transformation.getOrCreateMethod(getter).addAdvice(new ComponentMethodAdvice() - { - public void advise(ComponentMethodInvocation invocation) - { - invocation.overrideResult(access.read(invocation.getInstance())); - } - }); + throw new IllegalArgumentException(String.format( + "@Property annotation on %s.%s should have either read() or write() enabled.", field.getPlasticClass() + .getClassName(), field.getName())); } } 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=1098684&r1=1098683&r2=1098684&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 Mon May 2 17:37:43 2011 @@ -627,6 +627,19 @@ public final class TapestryModule /** * Adds a number of standard component class transform workers: + * <ul> + * <dt>Property</dt> + * <dd>Generates accessor methods if {@link org.apache.tapestry5.annotations.Property} annotation is present</dd> + * </ul> + */ + @Contribute(ComponentClassTransformWorker2.class) + public static void provideTransformWorkers(OrderedConfiguration<ComponentClassTransformWorker2> configuration) + { + configuration.add("Property", new PropertyWorker()); + } + + /** + * Adds a number of standard component class transform workers: * <dl> * <dt>Retain</dt> * <dd>Allows fields to retain their values between requests</dd> @@ -666,8 +679,6 @@ public final class TapestryModule * <dt>InvokePostRenderCleanupOnResources</dt> * <dd>Makes sure {@link org.apache.tapestry5.internal.InternalComponentResources#postRenderCleanup()} is invoked * after a component finishes rendering</dd> - * <dt>GenerateAccessors</dt> - * <dd>Generates accessor methods if {@link org.apache.tapestry5.annotations.Property} annotation is present</dd> * <dt>Cached</dt> * <dd>Checks for the {@link org.apache.tapestry5.annotations.Cached} annotation</dd> * <dt>Log</dt> @@ -680,7 +691,8 @@ public final class TapestryModule * <dd>Support for the {@link ActivationRequestParameter} annotation * </dl> */ - public static void contributeComponentClassTransformWorker( + @Contribute(ComponentClassTransformWorker2.class) + public static void provideOldStyleCassTransformWorkers( OrderedConfiguration<ComponentClassTransformWorker> configuration, MetaWorker metaWorker, @@ -739,8 +751,6 @@ public final class TapestryModule configuration.add("InvokePostRenderCleanupOnResources", new InvokePostRenderCleanupOnResourcesWorker()); - configuration.add("Property", new PropertyWorker(), "before:Inject*"); - // These must come after Property, since they actually delete fields // that may still have the annotation configuration.addInstance("ApplicationState", ApplicationStateWorker.class, "after:Property"); 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=1098684&r1=1098683&r2=1098684&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 Mon May 2 17:37:43 2011 @@ -1000,7 +1000,7 @@ public class CoreBehaviorsTests extends { openLinks("Getter Method Already Exists"); - assertTextPresent("Unable to create new method public java.lang.String getName() as it already exists in class org.apache.tapestry5.integration.app1.pages.GetterMethodAlreadyExists."); + assertTextPresent("Unable to create new accessor method public java.lang.String getName() on class org.apache.tapestry5.integration.app1.pages.GetterMethodAlreadyExists as the method is already implemented."); } /**