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 2011/05/02 19:37:38 UTC
svn commit: r1098683 - in /tapestry/tapestry5/trunk/plastic/src:
main/java/org/apache/tapestry5/internal/plastic/
main/java/org/apache/tapestry5/plastic/
test/groovy/org/apache/tapestry5/plastic/ test/java/testsubjects/
Author: hlship
Date: Mon May 2 17:37:38 2011
New Revision: 1098683
URL: http://svn.apache.org/viewvc?rev=1098683&view=rev
Log:
TAP5-853: Change PlasticField.createAccessors() to check for existing accessor methods and fail if they are present
Also, add test that checks that the generics signature propagates to the getter/setter methods
Added:
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AccessorsAlreadyExistSubject.java
tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/GenericCreateAccessorsSubject.java
Modified:
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java
tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1098683&r1=1098682&r2=1098683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java Mon May 2 17:37:38 2011
@@ -769,7 +769,9 @@ public class PlasticClassImpl extends Lo
if (accessType != PropertyAccessType.WRITE_ONLY)
{
- introduceMethod(new MethodDescription(getTypeName(), "get" + capitalized, null)).changeImplementation(
+ String signature = node.signature == null ? null : "()" + node.signature;
+
+ introduceAccessorMethod(getTypeName(), "get" + capitalized, null, signature,
new InstructionBuilderCallback()
{
public void doBuild(InstructionBuilder builder)
@@ -781,21 +783,39 @@ public class PlasticClassImpl extends Lo
if (accessType != PropertyAccessType.READ_ONLY)
{
- introduceMethod(new MethodDescription("void", "set" + capitalized, getTypeName()))
- .changeImplementation(new InstructionBuilderCallback()
- {
- public void doBuild(InstructionBuilder builder)
- {
- builder.loadThis().loadArgument(0);
- builder.putField(className, node.name, getTypeName());
- builder.returnResult();
- }
- });
+ String signature = node.signature == null ? null : "(" + node.signature + ")V";
+
+ introduceAccessorMethod("void", "set" + capitalized, new String[]
+ { getTypeName() }, node.signature, new InstructionBuilderCallback()
+ {
+ public void doBuild(InstructionBuilder builder)
+ {
+ builder.loadThis().loadArgument(0);
+ builder.putField(className, node.name, getTypeName());
+ builder.returnResult();
+ }
+ });
}
return this;
}
+ private void introduceAccessorMethod(String returnType, String name, String[] parameterTypes, String signature,
+ InstructionBuilderCallback callback)
+ {
+ MethodDescription description = new MethodDescription(ACC_PUBLIC, returnType, name, parameterTypes,
+ signature, null);
+
+ String desc = nameCache.toDesc(description);
+
+ if (methodBundle.isImplemented(name, desc))
+ throw new IllegalArgumentException(String.format(
+ "Unable to create new accessor method %s on class %s as the method is already implemented.",
+ description.toString(), className));
+
+ introduceMethod(description, callback);
+ }
+
private void replaceFieldWriteAccess(String conduitFieldName)
{
String setAccessName = makeUnique(methodNames, "set_" + node.name);
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java?rev=1098683&r1=1098682&r2=1098683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/plastic/PlasticField.java Mon May 2 17:37:38 2011
@@ -126,25 +126,28 @@ public interface PlasticField extends An
* Creates access to the field, using the default property name derived from the name of the field.
* The default property name is the same as the name of the field, but with any leading or trailing underscore
* characters removed (a common convention among some programmers). Also, strips leading "m_" from the field name
- * (another
- * common convention).
+ * (another common convention).
*
* @param accessType
* which methods to create
* @return the field for further manipulation
+ * @throws IllegalArgumentException
+ * if an accessor method to be created already exists (possibly inherited from a base class)
*/
PlasticField createAccessors(PropertyAccessType accessType);
/**
* Creates accessors, possibly replacing existing methods (or overriding methods from a super class).
* The method names consist of the property name, with its first character converted to upper-case, prefixed
- * with "get" or "set".
+ * with "get" or "set". The accessor methods must not already exist.
*
* @param accessType
* which methods to create
* @param propertyName
* the name of the property (from which the names of the methods are generated)
* @return the field for further manipulation
+ * @throws IllegalArgumentException
+ * if an accessor method to be created already exists (possibly inherited from a base class)
*/
PlasticField createAccessors(PropertyAccessType accessType, String propertyName);
Added: tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AccessorsAlreadyExistSubject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AccessorsAlreadyExistSubject.java?rev=1098683&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AccessorsAlreadyExistSubject.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/AccessorsAlreadyExistSubject.java Mon May 2 17:37:38 2011
@@ -0,0 +1,19 @@
+package org.apache.tapestry5.plastic;
+
+import testannotations.Property;
+
+public class AccessorsAlreadyExistSubject
+{
+ @Property
+ private String value;
+
+ public String getValue()
+ {
+ return value;
+ }
+
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+}
Modified: tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy?rev=1098683&r1=1098682&r2=1098683&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy (original)
+++ tapestry/tapestry5/trunk/plastic/src/test/groovy/org/apache/tapestry5/plastic/FieldPropertyMethodCreation.groovy Mon May 2 17:37:38 2011
@@ -14,23 +14,29 @@
package org.apache.tapestry5.plastic
-import org.apache.tapestry5.plastic.PlasticManager;
-import org.apache.tapestry5.plastic.PropertyAccessType;
+import java.util.concurrent.atomic.AtomicReference
-import spock.lang.Specification;
-import testannotations.Property;
+import spock.lang.Specification
+import testannotations.Property
+import testsubjects.CreateAccessorsSubject
+import testsubjects.GenericCreateAccessorsSubject
class FieldPropertyMethodCreation extends Specification
{
- def "create accessors for fields"() {
- setup:
-
+ def withAccessors(Class subject, PropertyAccessType accessType) {
def mgr = new PlasticManager()
- def pc = mgr.getPlasticClass ("testsubjects.CreateAccessorsSubject")
+ def pc = mgr.getPlasticClass (subject.name)
- pc.getFieldsWithAnnotation(Property.class).each { f -> f.createAccessors(PropertyAccessType.READ_WRITE) }
+ pc.getFieldsWithAnnotation(Property.class).each { f ->
+ f.createAccessors(accessType)
+ }
def o = pc.createInstantiator().newInstance()
+ }
+
+ def "create accessors for fields"() {
+
+ def o = withAccessors(CreateAccessorsSubject.class, PropertyAccessType.READ_WRITE)
when:
@@ -62,4 +68,45 @@ class FieldPropertyMethodCreation extend
then: "Setting primitive property reflected in original field"
assert o.m_count == o.count
}
+
+ def "create accessors for generic fields"() {
+
+ def o = withAccessors(GenericCreateAccessorsSubject.class, PropertyAccessType.READ_WRITE)
+
+ def ref = new AtomicReference<String>("Plastic")
+
+ o.ref = ref
+
+ expect:
+
+ assert o.ref == ref
+ assert o.refValue == "Plastic"
+
+ o.class.getMethod("getRef").signature == "()Ljava/util/concurrent/atomic/AtomicReference<Ljava/lang/String;>;"
+ o.class.getMethod("setRef", AtomicReference.class).signature == "Ljava/util/concurrent/atomic/AtomicReference<Ljava/lang/String;>;"
+ }
+
+ def "create getter that already exists"() {
+ when:
+
+ withAccessors(AccessorsAlreadyExistSubject.class, PropertyAccessType.READ_ONLY)
+
+ then:
+
+ def e = thrown(IllegalArgumentException)
+
+ assert e.message == "Unable to create new accessor method public java.lang.String getValue() on class org.apache.tapestry5.plastic.AccessorsAlreadyExistSubject as the method is already implemented."
+ }
+
+ def "create setter that already exists"() {
+ when:
+
+ withAccessors(AccessorsAlreadyExistSubject.class, PropertyAccessType.WRITE_ONLY)
+
+ then:
+
+ def e = thrown(IllegalArgumentException)
+
+ assert e.message == "Unable to create new accessor method public void setValue(java.lang.String) on class org.apache.tapestry5.plastic.AccessorsAlreadyExistSubject as the method is already implemented."
+ }
}
Added: tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/GenericCreateAccessorsSubject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/GenericCreateAccessorsSubject.java?rev=1098683&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/GenericCreateAccessorsSubject.java (added)
+++ tapestry/tapestry5/trunk/plastic/src/test/java/testsubjects/GenericCreateAccessorsSubject.java Mon May 2 17:37:38 2011
@@ -0,0 +1,16 @@
+package testsubjects;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import testannotations.Property;
+
+public class GenericCreateAccessorsSubject
+{
+ @Property
+ private AtomicReference<String> m_ref;
+
+ public String getRefValue()
+ {
+ return m_ref.get();
+ }
+}