You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by an...@apache.org on 2006/10/05 20:45:05 UTC
svn commit: r453311 - in /tapestry/tapestry4/trunk/tapestry-annotations/src:
java/org/apache/tapestry/annotations/ test/org/apache/tapestry/annotations/
Author: andyhot
Date: Thu Oct 5 11:45:05 2006
New Revision: 453311
URL: http://svn.apache.org/viewvc?view=rev&rev=453311
Log:
TAPESTRY-913: Support copyOf attribute for @Component annotation
Modified:
tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationMessages.java
tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationStrings.properties
tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationUtils.java
tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/Component.java
tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/ComponentAnnotationWorker.java
tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java
tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotationEnhancementWorkerTest.java
tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestComponentAnnotationWorker.java
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationMessages.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationMessages.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationMessages.java Thu Oct 5 11:45:05 2006
@@ -111,5 +111,15 @@
static String invalidAnnotationInClass(Class annotation, Class clazz)
{
return _formatter.format("invalid-annotation-in-class", annotation.getName(), clazz.getName());
- }
+ }
+
+ static String unableToCopy(String id)
+ {
+ return _formatter.format("unable-to-copy", id);
+ }
+
+ static String bothTypeAndCopyOf(String id)
+ {
+ return _formatter.format("both-type-and-copy-of", id);
+ }
}
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationStrings.properties?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationStrings.properties (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationStrings.properties Thu Oct 5 11:45:05 2006
@@ -29,3 +29,5 @@
no-targets-found=No targets found for annotated method {0}. You must specify at least one of targets or elements.
no-form-found=Unable to find form with id while enhancing method bound with submitForm annotation {0}: {1}
invalid-annotation-in-class=Annotation {0} is not allowed in a class (''{1}'') that implements the IPage interface.
+unable-to-copy=Unable to copy component {0}, which does not exist.
+both-type-and-copy-of=Annotation for component {0} contains both type and copy-of attributes.
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationUtils.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationUtils.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/AnnotationUtils.java Thu Oct 5 11:45:05 2006
@@ -17,10 +17,13 @@
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
+import java.util.Iterator;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
+import org.apache.tapestry.spec.IBindingSpecification;
+import org.apache.tapestry.spec.IContainedComponent;
import org.apache.tapestry.util.DescribedLocation;
/**
@@ -106,6 +109,26 @@
}
return buffer.toString();
+ }
+
+ /**
+ * Copies all bindings of a component to another one.
+ * @param source
+ * @param target
+ *
+ * @since 4.1.1
+ */
+ public static void copyBindings(IContainedComponent source, IContainedComponent target)
+ {
+ Iterator i = source.getBindingNames().iterator();
+ while (i.hasNext())
+ {
+ String bindingName = (String) i.next();
+ IBindingSpecification binding = source.getBinding(bindingName);
+ target.setBinding(bindingName, binding);
+ }
+
+ target.setType(source.getType());
}
private static void checkGetter(Method method)
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/Component.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/Component.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/Component.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/Component.java Thu Oct 5 11:45:05 2006
@@ -45,6 +45,14 @@
*/
String type() default "";
+
+ /**
+ * The name of a previously defined component.
+ * The type and bindings of that component will be copied to this component.
+ * Either type or copy-of must be specified.
+ */
+
+ String copyOf() default "";
/**
* If true, then the component inherits informal parameters from its container.
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/ComponentAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/ComponentAnnotationWorker.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/ComponentAnnotationWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/java/org/apache/tapestry/annotations/ComponentAnnotationWorker.java Thu Oct 5 11:45:05 2006
@@ -17,6 +17,7 @@
import java.lang.reflect.Method;
import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Location;
import org.apache.tapestry.enhance.EnhancementOperation;
import org.apache.tapestry.spec.BindingSpecification;
@@ -45,16 +46,30 @@
String propertyName = AnnotationUtils.getPropertyName(method);
String type = component.type();
- if (type.equals(""))
+ String copyOf = component.copyOf();
+ boolean hasCopyOf = HiveMind.isNonBlank(copyOf);
+
+ if (hasCopyOf)
{
- Class retTypeClazz = method.getReturnType();
- type = retTypeClazz.getSimpleName();
+ if (HiveMind.isNonBlank(type))
+ throw new ApplicationRuntimeException(AnnotationMessages.bothTypeAndCopyOf(propertyName));
+ type = null;
}
+ else
+ {
+ if (type.equals(""))
+ {
+ Class retTypeClazz = method.getReturnType();
+ type = retTypeClazz.getSimpleName();
+ }
+ copyOf = null;
+ }
IContainedComponent cc = new ContainedComponent();
cc.setInheritInformalParameters(component.inheritInformalParameters());
cc.setType(type);
+ cc.setCopyOf(copyOf);
cc.setPropertyName(propertyName);
cc.setLocation(location);
@@ -67,8 +82,15 @@
if (id.equals(""))
id = propertyName;
-
+
spec.addComponent(id, cc);
+
+ if (hasCopyOf)
+ {
+ IContainedComponent source = spec.getComponent(copyOf);
+ if (source != null)
+ AnnotationUtils.copyBindings(source, cc);
+ }
}
void addBinding(IContainedComponent component, String binding, Location location)
@@ -90,7 +112,7 @@
bs.setLocation(location);
component.setBinding(name, bs);
- }
+ }
private void invalidBinding(String binding)
{
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotatedPage.java Thu Oct 5 11:45:05 2006
@@ -107,6 +107,12 @@
@Component(type = "TextField", bindings =
{ "value = email", "displayName = message:email-label" })
public abstract IComponent getWhitespace();
+
+ @Component(id = "anEmailCopy", copyOf = "email", type = "Checkbox")
+ public abstract IComponent getInvalidEmailCopy();
+
+ @Component(id = "aComponentCopy", copyOf = "componentWithBindings")
+ public abstract IComponent getComponentWithBindingsCopy();
@Message
public abstract String noArgsMessage();
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotationEnhancementWorkerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotationEnhancementWorkerTest.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotationEnhancementWorkerTest.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/AnnotationEnhancementWorkerTest.java Thu Oct 5 11:45:05 2006
@@ -60,7 +60,7 @@
/**
* No method annotations registered.
*/
- public void testNoAnnotations()
+ public void test_No_Annotations()
{
EnhancementOperation op = newOp(AnnotatedPage.class);
IComponentSpecification spec = newSpec();
@@ -76,7 +76,7 @@
verify();
}
- public void testAnnotationMatch()
+ public void test_Annotation_Match()
{
ClassResolver resolver = new DefaultClassResolver();
@@ -118,7 +118,7 @@
baseClass));
}
- public void testAnnotationWithSubclass()
+ public void test_Annotation_With_Subclass()
{
ClassResolver resolver = new DefaultClassResolver();
@@ -145,7 +145,7 @@
verify();
}
- public void testAnnotationFailure()
+ public void test_Annotation_Failure()
{
ClassResolver resolver = new DefaultClassResolver();
@@ -183,7 +183,7 @@
verify();
}
- public void testClassAnnotation()
+ public void test_Class_Annotation()
{
ClassResolver resolver = new DefaultClassResolver();
@@ -208,7 +208,7 @@
verify();
}
- public void testClassAnnotationFailure()
+ public void test_Class_Annotation_Failure()
{
ClassResolver resolver = new DefaultClassResolver();
@@ -243,7 +243,7 @@
verify();
}
- public void testClassAnnotationNoMatch()
+ public void test_Class_Annotation_No_Match()
{
EnhancementOperation op = newOp(DeprecatedBean.class);
IComponentSpecification spec = newSpec();
@@ -259,7 +259,7 @@
verify();
}
- public void testSecondaryEnhancementWorker()
+ public void test_Secondary_EnhancementWorker()
{
SecondaryAnnotationWorker secondary = newSecondaryAnnotationWorker();
@@ -287,7 +287,7 @@
verify();
}
- public void testSecondaryEnhancementWorkerFailure()
+ public void test_Secondary_EnhancementWorker_Failure()
{
SecondaryAnnotationWorker secondary = newSecondaryAnnotationWorker();
Modified: tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestComponentAnnotationWorker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestComponentAnnotationWorker.java?view=diff&rev=453311&r1=453310&r2=453311
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestComponentAnnotationWorker.java (original)
+++ tapestry/tapestry4/trunk/tapestry-annotations/src/test/org/apache/tapestry/annotations/TestComponentAnnotationWorker.java Thu Oct 5 11:45:05 2006
@@ -16,6 +16,7 @@
import java.lang.reflect.Method;
+import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.tapestry.enhance.EnhancementOperation;
import org.apache.tapestry.spec.BindingType;
@@ -36,13 +37,18 @@
{
private IContainedComponent run(String id, String methodName, Location location)
{
+ IComponentSpecification spec = new ComponentSpecification();
+
+ return run(spec, id, methodName, location);
+ }
+
+ private IContainedComponent run(IComponentSpecification spec, String id, String methodName, Location location)
+ {
Method method = findMethod(AnnotatedPage.class, methodName);
EnhancementOperation op = newOp();
- replay();
-
- IComponentSpecification spec = new ComponentSpecification();
+ replay();
new ComponentAnnotationWorker().performEnhancement(op, spec, method, location);
@@ -51,7 +57,7 @@
return spec.getComponent(id);
}
- public void testSimple()
+ public void test_Simple()
{
Location l = newLocation();
@@ -65,28 +71,28 @@
assertEquals("textField", cc.getPropertyName());
}
- public void testWithoutType()
+ public void test_Without_Type()
{
IContainedComponent cc = run("usernameField", "getUsernameField", null);
assertEquals("TextField", cc.getType());
}
- public void testExplicitId()
+ public void test_Explicit_Id()
{
IContainedComponent cc = run("email", "getEmailField", null);
assertEquals("emailField", cc.getPropertyName());
}
- public void testInheritInformalParameters()
+ public void test_Inherit_Informal_Parameters()
{
IContainedComponent cc = run("inherit", "getInherit", null);
assertEquals(true, cc.getInheritInformalParameters());
}
- public void testWithBindings()
+ public void test_With_Bindings()
{
Location l = newLocation();
IContainedComponent cc = run("componentWithBindings", "getComponentWithBindings", l);
@@ -100,7 +106,7 @@
assertEquals("div", bs2.getValue());
}
- public void testBindingWhitespaceTrimmed()
+ public void test_Binding_Whitespace_Trimmed()
{
Location l = newLocation();
@@ -114,4 +120,33 @@
IBindingSpecification bs2 = cc.getBinding("displayName");
assertEquals("message:email-label", bs2.getValue());
}
+
+ public void test_With_Type_And_CopyOf()
+ {
+ try
+ {
+ run("anEmailCopy", "getInvalidEmailCopy", null);
+ unreachable();
+ }
+ catch (ApplicationRuntimeException ex)
+ {
+ assertExceptionSubstring(ex, "both type and copy-of");
+ }
+ }
+
+ public void test_CopyOf()
+ {
+ Location l = newLocation();
+ IComponentSpecification spec = new ComponentSpecification();
+ run(spec, "componentWithBindings", "getComponentWithBindings", l);
+ IContainedComponent cc = run(spec, "aComponentCopy", "getComponentWithBindingsCopy", l);
+
+ IBindingSpecification bs1 = cc.getBinding("condition");
+ assertSame(l, bs1.getLocation());
+ assertEquals(BindingType.PREFIXED, bs1.getType());
+ assertEquals("message", bs1.getValue());
+
+ IBindingSpecification bs2 = cc.getBinding("element");
+ assertEquals("div", bs2.getValue());
+ }
}