You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by uk...@apache.org on 2014/05/19 22:41:55 UTC

[1/2] git commit: TAP5-1213 - Access generic type for bound parameters

Repository: tapestry-5
Updated Branches:
  refs/heads/master b452c6fcd -> 737ebd64c


TAP5-1213 - Access generic type for bound parameters


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/daa27902
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/daa27902
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/daa27902

Branch: refs/heads/master
Commit: daa279024e6b66c6c6b2c77e279f42fee50c8dc5
Parents: b452c6f
Author: uklance <uk...@gmail.com>
Authored: Sat May 17 18:48:27 2014 +0100
Committer: uklance <uk...@gmail.com>
Committed: Mon May 19 21:34:49 2014 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/tapestry5/Binding.java |  9 ++++
 .../apache/tapestry5/ComponentResources.java    | 13 +++++
 .../org/apache/tapestry5/PropertyConduit.java   | 13 +++++
 .../internal/TapestryInternalUtils.java         |  6 +++
 .../internal/bindings/AbstractBinding.java      | 10 ++++
 .../internal/bindings/PropBinding.java          | 11 ++++
 .../CoercingPropertyConduitWrapper.java         |  6 +++
 .../services/LiteralPropertyConduit.java        |  6 +++
 .../services/PropertyConduitSourceImpl.java     | 57 ++++++++++++++++++--
 .../InternalComponentResourcesImpl.java         |  9 ++++
 .../integration/app1/CoreBehaviorsTests.java    | 16 ++++++
 .../app1/components/GenericTypeDisplay.java     | 45 ++++++++++++++++
 .../integration/app1/pages/EmptyGrid.java       |  6 +++
 .../integration/app1/pages/GenericTypeDemo.java | 33 ++++++++++++
 .../tapestry5/integration/app1/pages/Index.java |  4 +-
 .../services/PropertyConduitSourceImplTest.java | 27 ++++++++++
 .../integration/app1/pages/GenericTypeDemo.tml  | 12 +++++
 17 files changed, 278 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
index 8a99914..711c748 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry5;
 
+import java.lang.reflect.Type;
+
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -53,4 +55,11 @@ public interface Binding extends AnnotationProvider
      * bound.
      */
     Class getBindingType();
+    
+    /**
+     * Returns the generic type of the binding, either the generic type of resource exposed by the binding, or the 
+     * generic type of the property bound.
+     * @since 5.4
+     */
+    Type getBindingGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/ComponentResources.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/ComponentResources.java b/tapestry-core/src/main/java/org/apache/tapestry5/ComponentResources.java
index 137c43d..5c51903 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/ComponentResources.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/ComponentResources.java
@@ -23,6 +23,7 @@ import org.apache.tapestry5.runtime.PageLifecycleCallbackHub;
 import org.apache.tapestry5.runtime.PageLifecycleListener;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.util.List;
 
 /**
@@ -128,6 +129,18 @@ public interface ComponentResources extends ComponentResourcesCommon
      * @see Binding#getBindingType()
      */
     Class getBoundType(String parameterName);
+    
+    
+    /**
+     * Returns the generic type of the bound parameter, or null if the parameter is not bound. This is useful
+     * for when the parameter is bound to a generic property (eg java.util.List) to determine the element type.
+     * 
+     * @param parameterName
+     *        used to select the parameter (case is ignored)
+     * @return the generic type of the bound parameter, or null if the parameter is not bound
+     * @see Binding#getBindingGenericType()
+     */
+    Type getBoundGenericType(String parameterName);
 
     /**
      * Returns an annotation provider, used to obtain annotations related to the parameter.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
index 3dbb0c0..b28293a 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
@@ -14,6 +14,8 @@
 
 package org.apache.tapestry5;
 
+import java.lang.reflect.Type;
+
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -42,4 +44,15 @@ public interface PropertyConduit extends AnnotationProvider
      * Returns the type of the property read or updated by the conduit.
      */
     Class getPropertyType();
+    
+    /**
+     * Returns a Type object that represents the declared type for the property.
+     * If the Type is a parameterized type, the Type object returned must accurately 
+     * reflect the actual type parameters used in the source code. If the type of the
+     * underlying property is a type variable or a parameterized type, it is created.
+     * Otherwise, it is resolved.
+     * 
+     * @since 5.4
+     */
+    Type getPropertyGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
index 7c6e8b0..45da70b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
@@ -32,6 +32,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.annotation.Annotation;
 import java.lang.ref.Reference;
+import java.lang.reflect.Type;
 import java.util.List;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -491,6 +492,11 @@ public class TapestryInternalUtils
                 return conduit.getPropertyType();
             }
 
+            public Type getPropertyGenericType()
+            {
+                return conduit.getPropertyGenericType();
+            }
+            
             public Object get(Object instance)
             {
                 return conduit.get(instance);

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
index a2478b5..12885e1 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
@@ -20,6 +20,7 @@ import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 /**
  * Abstract base class for bindings. Assumes that the binding is read only and invariant. Subclasses must provide an
@@ -62,6 +63,15 @@ public abstract class AbstractBinding extends BaseLocatable implements Binding
     {
         return get().getClass();
     }
+    
+    /**
+     * Passes straight through to {@link AbstractBinding#getBindingType()}. Subclasses may override this method to
+     * return the generic type if it is available
+     */
+    public Type getBindingGenericType()
+    {
+    	return getBindingType();
+    }
 
     /**
      * Always returns null. Bindings that provide access to a method or field will override this method to return the

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
index e7802bc..55ea9d8 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
@@ -21,6 +21,7 @@ import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 /**
  * Base class for bindings created by the {@link org.apache.tapestry5.internal.bindings.PropBindingFactory}. A subclass
@@ -100,6 +101,16 @@ public class PropBinding extends AbstractBinding implements InternalPropBinding
     {
         return conduit.getPropertyType();
     }
+    
+    /**
+     * Get the generic type from the underlying field or getter.
+     * @see PropertyConduit#getPropertyGenericType()
+     */
+    @Override
+    public Type getBindingGenericType()
+    {
+    	return conduit.getPropertyGenericType();
+    }
 
     @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
index e1135bf..158d4a4 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
@@ -18,6 +18,7 @@ import org.apache.tapestry5.PropertyConduit;
 import org.apache.tapestry5.ioc.services.TypeCoercer;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 public class CoercingPropertyConduitWrapper implements PropertyConduit
 {
@@ -45,6 +46,11 @@ public class CoercingPropertyConduitWrapper implements PropertyConduit
     {
         return conduit.getPropertyType();
     }
+    
+    public Type getPropertyGenericType()
+    {
+    	return conduit.getPropertyGenericType();
+    }
 
     @SuppressWarnings("unchecked")
     public void set(Object instance, Object value)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LiteralPropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LiteralPropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LiteralPropertyConduit.java
index bc2eb12..1fffd4f 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LiteralPropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/LiteralPropertyConduit.java
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.internal.services;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 
 import org.apache.tapestry5.internal.InternalPropertyConduit;
 import org.apache.tapestry5.ioc.AnnotationProvider;
@@ -59,6 +60,11 @@ public class LiteralPropertyConduit extends PropertyConduitDelegate implements I
     {
         return propertyType;
     }
+    
+    public Type getPropertyGenericType()
+    {
+    	return propertyType;
+    }
 
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
index 5f41fb1..6dab120 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
@@ -63,9 +63,12 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
         private static final MethodDescription GET_PROPERTY_TYPE = getMethodDescription(PropertyConduit.class,
                 "getPropertyType");
 
+        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit.class,
+                "getPropertyGenericType");
+        
         private static final MethodDescription GET_PROPERTY_NAME = getMethodDescription(InternalPropertyConduit.class,
                 "getPropertyName");
-
+        
         private static final MethodDescription GET_ANNOTATION = getMethodDescription(AnnotationProvider.class,
                 "getAnnotation", Class.class);
 
@@ -245,6 +248,8 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
         private Class conduitPropertyType;
 
+        private Type conduitPropertyGenericType;
+
         private String conduitPropertyName;
 
         private AnnotationProvider annotationProvider = nullAnnotationProvider;
@@ -302,6 +307,16 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
                 }
             });
 
+            final PlasticField propertyGenericTypeField = plasticClass.introduceField(Type.class, "propertyGenericType").inject(
+                    conduitPropertyGenericType);
+
+            plasticClass.introduceMethod(ConduitMethods.GET_PROPERTY_GENERIC_TYPE, new InstructionBuilderCallback()
+            {
+                public void doBuild(InstructionBuilder builder)
+                {
+                    builder.loadThis().getField(propertyGenericTypeField).returnResult();
+                }
+            });
         }
 
         /**
@@ -424,6 +439,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
                     implementNoOpSetter();
 
                     conduitPropertyType = IntegerRange.class;
+                    conduitPropertyGenericType = IntegerRange.class;
 
                     return;
 
@@ -433,7 +449,8 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
                     implementNoOpSetter();
 
                     conduitPropertyType = List.class;
-
+                    conduitPropertyGenericType = List.class;
+                    
                     return;
 
                 case MAP:
@@ -441,6 +458,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
                     implementNoOpSetter();
 
                     conduitPropertyType = Map.class;
+                    conduitPropertyGenericType = Map.class;
 
                     return;
 
@@ -450,6 +468,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
                     implementNoOpSetter();
 
                     conduitPropertyType = boolean.class;
+                    conduitPropertyGenericType = boolean.class;
 
                     return;
 
@@ -466,6 +485,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
             conduitPropertyName = term.description;
             conduitPropertyType = term.genericType;
+            conduitPropertyGenericType = term.genericType;
             annotationProvider = term.annotationProvider;
 
             plasticClass.introduceMethod(ConduitMethods.GET, new InstructionBuilderCallback()
@@ -491,15 +511,39 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
 
             PropertyAdapter adapter = findPropertyAdapter(activeType, propertyName);
 
-            conduitPropertyType = adapter.getType();
             conduitPropertyName = propertyName;
+            conduitPropertyType = adapter.getType();
+            conduitPropertyGenericType = getGenericType(adapter);
             annotationProvider = adapter;
 
             implementGetter(adapter);
             implementSetter(adapter);
         }
 
-        private void implementSetter(PropertyAdapter adapter)
+        private Type getGenericType(PropertyAdapter adapter)
+        {
+        	Type genericType = null;
+        	if (adapter.getField() != null)
+        	{
+        		genericType = adapter.getField().getGenericType();
+        	}
+        	else if (adapter.getReadMethod() != null)
+        	{
+        		genericType = adapter.getReadMethod().getGenericReturnType(); 
+        	}
+        	else if (adapter.getWriteMethod() != null)
+        	{
+        		genericType = adapter.getWriteMethod().getGenericParameterTypes()[0];
+        	}
+        	else
+        	{
+        		throw new RuntimeException("Could not find accessor for property " + adapter.getName());
+        	}
+        	
+        	return genericType == null ? adapter.getType() : genericType;
+		}
+
+		private void implementSetter(PropertyAdapter adapter)
         {
             if (adapter.getWriteMethod() != null)
             {
@@ -1439,6 +1483,11 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
             {
                 return rootClass;
             }
+            
+            public Type getPropertyGenericType()
+            {
+            	return rootClass;
+            }
 
             public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
             {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
index 39defda..5e0e440 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
@@ -41,6 +41,7 @@ import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
 import org.slf4j.Logger;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -344,6 +345,14 @@ public class InternalComponentResourcesImpl extends LockSupport implements Inter
 
         return binding == null ? null : binding.getBindingType();
     }
+    
+    public Type getBoundGenericType(String parameterName)
+    {
+        Binding binding = getBinding(parameterName);
+
+        return binding == null ? null : binding.getBindingGenericType();
+    }
+    
 
     public Binding getBinding(String parameterName)
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index 2179b98..afdc002 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -1720,4 +1720,20 @@ public class CoreBehaviorsTests extends App1TestCase
         
         assertTextPresent("This page throws an exception");
     }
+    
+    @Test
+    public void bound_generic_types()
+    {
+    	openLinks("Generic bound type demo");
+    	
+		assertTextPresent("clientId=one,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
+		assertTextPresent("clientId=two,type=java.lang.String,genericType=class java.lang.String");
+		assertTextPresent("clientId=three,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
+		assertTextPresent("clientId=four,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
+		assertTextPresent("clientId=five,type=java.util.List,genericType=interface java.util.List");
+		assertTextPresent("clientId=six,type=java.util.Date,genericType=class java.util.Date");
+		assertTextPresent("clientId=seven,type=java.util.List,genericType=interface java.util.List");
+		assertTextPresent("clientId=eight,type=java.util.Map,genericType=interface java.util.Map");
+		assertTextPresent("clientId=nine,type=java.lang.String,genericType=class java.lang.String");
+    }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
new file mode 100644
index 0000000..ab95807
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
@@ -0,0 +1,45 @@
+// Copyright 2006-2014 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.tapestry5.integration.app1.components;
+
+import java.lang.reflect.Type;
+
+import org.apache.tapestry5.BindingConstants;
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.MarkupWriter;
+import org.apache.tapestry5.annotations.Parameter;
+import org.apache.tapestry5.ioc.annotations.Inject;
+
+/**
+ * Outputs the type and genericType of the 'value' parameter in a div
+ */
+public class GenericTypeDisplay {
+	@Inject
+	private ComponentResources resources;
+	
+	@Parameter(required=true, defaultPrefix=BindingConstants.LITERAL)
+	private String clientId;
+	
+	@Parameter(required=true)
+	private Object value;
+	
+	void afterRender(MarkupWriter writer) {
+		writer.element("div", "id", clientId);
+		Class<?> type = resources.getBoundType("value");
+		Type genericType = resources.getBoundGenericType("value");
+		String text = String.format("clientId=%s,type=%s,genericType=%s", clientId, type.getName(), genericType.toString());
+		writer.write(text);
+		writer.end();
+	}
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EmptyGrid.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EmptyGrid.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EmptyGrid.java
index 522fa6a..a89c039 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EmptyGrid.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/EmptyGrid.java
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.integration.app1.pages;
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
 import java.util.Collections;
 import java.util.List;
 import java.util.Random;
@@ -66,6 +67,11 @@ public class EmptyGrid
       {
         return Long.class;
       }
+
+      public Type getPropertyGenericType()
+      {
+        return Long.class;
+      }
       
       public Object get(Object instance)
       {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
new file mode 100644
index 0000000..80bf40a
--- /dev/null
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
@@ -0,0 +1,33 @@
+package org.apache.tapestry5.integration.app1.pages;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.annotations.SetupRender;
+
+public class GenericTypeDemo {
+	private Set<Long> setOfLongs;
+	
+	@Property
+	private Map<String, String> mapOfStrings;
+	
+	public List<List<Date>> getListOfListOfDates() {
+		List<Date> dates = Arrays.asList(new Date(Long.MIN_VALUE), new Date(0), new Date(Long.MAX_VALUE));
+		return Arrays.asList(dates);
+	}
+	
+	public void setSetOfLongs(Set<Long> setOfLongs) {
+		this.setOfLongs = setOfLongs;
+	}
+	
+	@SetupRender
+	void setupRender() {
+		mapOfStrings = new HashMap<String,String>();
+		mapOfStrings.put("foo", "bar");
+	}
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
index 009a97d..99f2a16 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
@@ -566,7 +566,9 @@ public class Index
 
                     new Item("nested/PageThatThrowsException", "Reload on nested page", "Tests a page reload from a nested page's exception report"),
                     
-                    new Item("inplacegridinloopdemo", "In-Place Grid in a Loop Demo", "In-place grid in a loop")
+                    new Item("inplacegridinloopdemo", "In-Place Grid in a Loop Demo", "In-place grid in a loop"),
+                    
+                    new Item("GenericTypeDemo", "Generic bound type demo", "Tests that generic type info is available for generic bindings")
 
             );
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
index 1f550cd..5c9f88a 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
@@ -29,6 +29,8 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -161,6 +163,31 @@ public class PropertyConduitSourceImplTest extends InternalBaseTestCase
         smart.set(bean, "Howard");
     }
 
+    static class GenericBean {
+    	public List<Date> dates;
+    	public List<GenericBean> genericBeans;
+    	
+    	public List<Long> getLongs() {
+    		return Collections.emptyList();
+    	}
+    	
+    	public void setMap(Map<String, Integer> map) {
+    	}
+    }
+    
+    @Test
+    public void generic_types_are_determined()
+    {
+        PropertyConduit datesConduit = source.create(GenericBean.class, "dates");
+        PropertyConduit longsConduit = source.create(GenericBean.class, "longs");
+        PropertyConduit nestedDatesConduit = source.create(GenericBean.class, "genericBeans.get(0).dates");
+        PropertyConduit mapConduit = source.create(GenericBean.class, "map");
+        assertEquals(datesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
+        assertEquals(longsConduit.getPropertyGenericType().toString(), "java.util.List<java.lang.Long>");
+        assertEquals(nestedDatesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
+        assertEquals(mapConduit.getPropertyGenericType().toString(), "java.util.Map<java.lang.String, java.lang.Integer>");
+    }
+    
     @Test
     public void method_names_are_matched_caselessly()
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/daa27902/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
new file mode 100644
index 0000000..c9f4b78
--- /dev/null
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
@@ -0,0 +1,12 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+	<h1>Generic Type Tests</h1>
+	<t:genericTypeDisplay clientId="one" value="mapOfStrings" />
+	<t:genericTypeDisplay clientId="two" value="mapOfStrings.get('foo')" />
+	<t:genericTypeDisplay clientId="three" value="setOfLongs" />
+	<t:genericTypeDisplay clientId="four" value="listOfListOfDates" />
+	<t:genericTypeDisplay clientId="five" value="listOfListOfDates.get(0)" />
+	<t:genericTypeDisplay clientId="six" value="listOfListOfDates.get(0).get(0)" />
+	<t:genericTypeDisplay clientId="seven" value="[1,2,3]" />
+	<t:genericTypeDisplay clientId="eight" value="{'foo':'bar'}" />
+	<t:genericTypeDisplay clientId="nine" value="literal:aaa" />
+</html>


[2/2] git commit: TAP5-1213 - Refactor public API changes to be backwards compatible

Posted by uk...@apache.org.
TAP5-1213 - Refactor public API changes to be backwards compatible


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/737ebd64
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/737ebd64
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/737ebd64

Branch: refs/heads/master
Commit: 737ebd64cf8f1607b5c755c7967260e1e755633d
Parents: daa2790
Author: uklance <uk...@gmail.com>
Authored: Mon May 19 21:33:03 2014 +0100
Committer: uklance <uk...@gmail.com>
Committed: Mon May 19 21:34:52 2014 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/tapestry5/Binding.java |  9 -----
 .../java/org/apache/tapestry5/Binding2.java     | 38 +++++++++++++++++++
 .../org/apache/tapestry5/PropertyConduit.java   | 13 -------
 .../org/apache/tapestry5/PropertyConduit2.java  | 40 ++++++++++++++++++++
 .../internal/InternalPropertyConduit.java       |  6 +--
 .../internal/TapestryInternalUtils.java         |  6 ++-
 .../internal/bindings/AbstractBinding.java      |  3 +-
 .../internal/bindings/InternalPropBinding.java  |  4 +-
 .../internal/bindings/PropBinding.java          | 17 ++++++---
 .../CoercingPropertyConduitWrapper.java         | 14 ++++---
 .../services/PropertyConduitSourceImpl.java     |  3 +-
 .../InternalComponentResourcesImpl.java         |  9 ++++-
 .../integration/app1/CoreBehaviorsTests.java    | 18 ++++-----
 .../app1/components/GenericTypeDisplay.java     |  8 ++--
 .../integration/app1/pages/GenericTypeDemo.java | 14 +------
 .../services/PropertyConduitSourceImplTest.java | 19 +++++-----
 .../integration/app1/pages/GenericTypeDemo.tml  | 18 ++++-----
 17 files changed, 153 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
index 711c748..8a99914 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5;
 
-import java.lang.reflect.Type;
-
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -55,11 +53,4 @@ public interface Binding extends AnnotationProvider
      * bound.
      */
     Class getBindingType();
-    
-    /**
-     * Returns the generic type of the binding, either the generic type of resource exposed by the binding, or the 
-     * generic type of the property bound.
-     * @since 5.4
-     */
-    Type getBindingGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java b/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
new file mode 100644
index 0000000..7569a8c
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
@@ -0,0 +1,38 @@
+// Copyright 2006-2013 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.tapestry5;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.apache.tapestry5.services.BindingFactory;
+
+/**
+ * Extension to {@link Binding} that adds a method to access the generic property type.
+ * {@link BindingFactory} instances should ideally return Binding2 objects, not Binding.
+ * This is only primarily of interest to {@link ComponentResources}.
+ * 
+ * @since 5.4
+ */
+public interface Binding2 extends Binding
+{
+    /**
+     * Returns the generic type of the binding
+     * 
+     * @see Method#getGenericReturnType()
+     * @see java.lang.reflect.Field#getGenericType()
+     */
+    Type getBindingGenericType();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
index b28293a..3dbb0c0 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5;
 
-import java.lang.reflect.Type;
-
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -44,15 +42,4 @@ public interface PropertyConduit extends AnnotationProvider
      * Returns the type of the property read or updated by the conduit.
      */
     Class getPropertyType();
-    
-    /**
-     * Returns a Type object that represents the declared type for the property.
-     * If the Type is a parameterized type, the Type object returned must accurately 
-     * reflect the actual type parameters used in the source code. If the type of the
-     * underlying property is a type variable or a parameterized type, it is created.
-     * Otherwise, it is resolved.
-     * 
-     * @since 5.4
-     */
-    Type getPropertyGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
new file mode 100644
index 0000000..839d70f
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
@@ -0,0 +1,40 @@
+// Copyright 2007 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.tapestry5;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.apache.tapestry5.services.PropertyConduitSource;
+
+
+/**
+ * Extension to {@link PropertyConduit} that adds a method to access the generic property type.
+ * {@link PropertyConduitSource} instances should ideally return PropertyConduit2 objects, not PropertyConduit.
+ * This is only primarily of interest to {@link Binding2}.
+ * 
+ * @since 5.4
+ */
+public interface PropertyConduit2 extends PropertyConduit
+{
+    /**
+     * Returns the generic type of the property
+     * 
+     * @see Method#getGenericReturnType()
+     * @see java.lang.reflect.Field#getGenericType()
+     * 
+     */
+	Type getPropertyGenericType();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
index 5e19e5b..315b372 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
@@ -14,16 +14,16 @@
 
 package org.apache.tapestry5.internal;
 
-import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 
 
 /**
- * Extension to {@link org.apache.tapestry5.PropertyConduit} that adds a method to determine the name of the property.
+ * Extension to {@link org.apache.tapestry5.PropertyConduit2} that adds a method to determine the name of the property.
  * 
  * @since 5.2.0
  *
  */
-public interface InternalPropertyConduit extends PropertyConduit
+public interface InternalPropertyConduit extends PropertyConduit2
 {
     /**
      * Returns the name of the property read or updated by the conduit or null. 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
index 45da70b..6c6138b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
@@ -494,7 +494,11 @@ public class TapestryInternalUtils
 
             public Type getPropertyGenericType()
             {
-                return conduit.getPropertyGenericType();
+                if (conduit instanceof PropertyConduit2)
+                {
+                	return ((PropertyConduit2) conduit).getPropertyGenericType();
+                }
+            	return conduit.getPropertyType();
             }
             
             public Object get(Object instance)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
index 12885e1..8e731b7 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.internal.bindings;
 
 import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.Binding2;
 import org.apache.tapestry5.ioc.BaseLocatable;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
@@ -26,7 +27,7 @@ import java.lang.reflect.Type;
  * Abstract base class for bindings. Assumes that the binding is read only and invariant. Subclasses must provide an
  * implementation of {@link Binding#get()}.
  */
-public abstract class AbstractBinding extends BaseLocatable implements Binding
+public abstract class AbstractBinding extends BaseLocatable implements Binding2
 {
     public AbstractBinding()
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
index 1d7fd60..8af0943 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
@@ -13,13 +13,13 @@
 // limitations under the License.
 package org.apache.tapestry5.internal.bindings;
 
-import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.Binding2;
 
 /**
  * Internal marker interface for {@linkplain org.apache.tapestry5.internal.bindings.PropBinding}
  *
  */
-public interface InternalPropBinding extends Binding
+public interface InternalPropBinding extends Binding2
 {
     /**
      * Returns the name of the property, if exists.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
index 55ea9d8..afe63eb 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
@@ -14,15 +14,16 @@
 
 package org.apache.tapestry5.internal.bindings;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.internal.TapestryInternalUtils;
 import org.apache.tapestry5.internal.services.Invariant;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-
 /**
  * Base class for bindings created by the {@link org.apache.tapestry5.internal.bindings.PropBindingFactory}. A subclass
  * of this is created at runtime.
@@ -103,13 +104,17 @@ public class PropBinding extends AbstractBinding implements InternalPropBinding
     }
     
     /**
-     * Get the generic type from the underlying field or getter.
-     * @see PropertyConduit#getPropertyGenericType()
+     * Get the generic type from the underlying property
+     * 
+     * @see PropertyConduit2#getPropertyGenericType()
      */
     @Override
     public Type getBindingGenericType()
     {
-    	return conduit.getPropertyGenericType();
+    	if (conduit instanceof PropertyConduit2) {
+    		return ((PropertyConduit2) conduit).getPropertyGenericType();
+    	}
+    	return conduit.getPropertyType();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
index 158d4a4..4dbfb2d 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
@@ -14,13 +14,14 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.PropertyConduit;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
-public class CoercingPropertyConduitWrapper implements PropertyConduit
+import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+
+public class CoercingPropertyConduitWrapper implements PropertyConduit2
 {
     private final PropertyConduit conduit;
 
@@ -49,7 +50,10 @@ public class CoercingPropertyConduitWrapper implements PropertyConduit
     
     public Type getPropertyGenericType()
     {
-    	return conduit.getPropertyGenericType();
+    	if (conduit instanceof PropertyConduit2) {
+    		return ((PropertyConduit2) conduit).getPropertyGenericType();
+    	}
+    	return conduit.getPropertyType();
     }
 
     @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
index 6dab120..701420f 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
@@ -18,6 +18,7 @@ import org.antlr.runtime.ANTLRInputStream;
 import org.antlr.runtime.CommonTokenStream;
 import org.antlr.runtime.tree.Tree;
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.internal.InternalPropertyConduit;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionLexer;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionParser;
@@ -63,7 +64,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
         private static final MethodDescription GET_PROPERTY_TYPE = getMethodDescription(PropertyConduit.class,
                 "getPropertyType");
 
-        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit.class,
+        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit2.class,
                 "getPropertyGenericType");
         
         private static final MethodDescription GET_PROPERTY_NAME = getMethodDescription(InternalPropertyConduit.class,

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
index 5e0e440..c51c086 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
@@ -349,8 +349,13 @@ public class InternalComponentResourcesImpl extends LockSupport implements Inter
     public Type getBoundGenericType(String parameterName)
     {
         Binding binding = getBinding(parameterName);
-
-        return binding == null ? null : binding.getBindingGenericType();
+        Type genericType;
+        if (binding instanceof Binding2) {
+        	genericType = ((Binding2) binding).getBindingGenericType();
+        } else {
+        	genericType = binding.getBindingType();
+        }
+        return genericType;
     }
     
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index afdc002..d7ecc25 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -1726,14 +1726,14 @@ public class CoreBehaviorsTests extends App1TestCase
     {
     	openLinks("Generic bound type demo");
     	
-		assertTextPresent("clientId=one,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
-		assertTextPresent("clientId=two,type=java.lang.String,genericType=class java.lang.String");
-		assertTextPresent("clientId=three,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
-		assertTextPresent("clientId=four,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
-		assertTextPresent("clientId=five,type=java.util.List,genericType=interface java.util.List");
-		assertTextPresent("clientId=six,type=java.util.Date,genericType=class java.util.Date");
-		assertTextPresent("clientId=seven,type=java.util.List,genericType=interface java.util.List");
-		assertTextPresent("clientId=eight,type=java.util.Map,genericType=interface java.util.Map");
-		assertTextPresent("clientId=nine,type=java.lang.String,genericType=class java.lang.String");
+    	assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
+    	assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
+    	assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
+    	assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
+    	assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
+    	assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
+    	assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
+    	assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
+    	assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
index ab95807..f6d2aa7 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
@@ -22,23 +22,23 @@ import org.apache.tapestry5.annotations.Parameter;
 import org.apache.tapestry5.ioc.annotations.Inject;
 
 /**
- * Outputs the type and genericType of the 'value' parameter in a div
+ * Outputs the type and genericType of the 'value' binding in a div
  */
 public class GenericTypeDisplay {
 	@Inject
 	private ComponentResources resources;
 	
 	@Parameter(required=true, defaultPrefix=BindingConstants.LITERAL)
-	private String clientId;
+	private String description;
 	
 	@Parameter(required=true)
 	private Object value;
 	
 	void afterRender(MarkupWriter writer) {
-		writer.element("div", "id", clientId);
+		writer.element("div");
 		Class<?> type = resources.getBoundType("value");
 		Type genericType = resources.getBoundGenericType("value");
-		String text = String.format("clientId=%s,type=%s,genericType=%s", clientId, type.getName(), genericType.toString());
+		String text = String.format("description=%s,type=%s,genericType=%s", description, type.getName(), genericType.toString());
 		writer.write(text);
 		writer.end();
 	}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
index 80bf40a..8e9fdd3 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
@@ -1,14 +1,11 @@
 package org.apache.tapestry5.integration.app1.pages;
 
-import java.util.Arrays;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SetupRender;
 
 public class GenericTypeDemo {
 	private Set<Long> setOfLongs;
@@ -17,17 +14,10 @@ public class GenericTypeDemo {
 	private Map<String, String> mapOfStrings;
 	
 	public List<List<Date>> getListOfListOfDates() {
-		List<Date> dates = Arrays.asList(new Date(Long.MIN_VALUE), new Date(0), new Date(Long.MAX_VALUE));
-		return Arrays.asList(dates);
+		throw new UnsupportedOperationException();
 	}
 	
 	public void setSetOfLongs(Set<Long> setOfLongs) {
-		this.setOfLongs = setOfLongs;
-	}
-	
-	@SetupRender
-	void setupRender() {
-		mapOfStrings = new HashMap<String,String>();
-		mapOfStrings.put("foo", "bar");
+		throw new UnsupportedOperationException();
 	}
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
index 5c9f88a..0e61220 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
@@ -14,8 +14,14 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry5.Block;
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.beaneditor.NonVisual;
 import org.apache.tapestry5.beaneditor.Validate;
 import org.apache.tapestry5.integration.app1.data.IntegerHolder;
@@ -29,11 +35,6 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
 /**
  * Most of the testing occurs inside {@link PropBindingFactoryTest} (due to
  * historical reasons).
@@ -178,10 +179,10 @@ public class PropertyConduitSourceImplTest extends InternalBaseTestCase
     @Test
     public void generic_types_are_determined()
     {
-        PropertyConduit datesConduit = source.create(GenericBean.class, "dates");
-        PropertyConduit longsConduit = source.create(GenericBean.class, "longs");
-        PropertyConduit nestedDatesConduit = source.create(GenericBean.class, "genericBeans.get(0).dates");
-        PropertyConduit mapConduit = source.create(GenericBean.class, "map");
+        PropertyConduit2 datesConduit = (PropertyConduit2) source.create(GenericBean.class, "dates");
+        PropertyConduit2 longsConduit = (PropertyConduit2) source.create(GenericBean.class, "longs");
+        PropertyConduit2 nestedDatesConduit = (PropertyConduit2) source.create(GenericBean.class, "genericBeans.get(0).dates");
+        PropertyConduit2 mapConduit = (PropertyConduit2) source.create(GenericBean.class, "map");
         assertEquals(datesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
         assertEquals(longsConduit.getPropertyGenericType().toString(), "java.util.List<java.lang.Long>");
         assertEquals(nestedDatesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
index c9f4b78..12e347a 100644
--- a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
@@ -1,12 +1,12 @@
 <html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
 	<h1>Generic Type Tests</h1>
-	<t:genericTypeDisplay clientId="one" value="mapOfStrings" />
-	<t:genericTypeDisplay clientId="two" value="mapOfStrings.get('foo')" />
-	<t:genericTypeDisplay clientId="three" value="setOfLongs" />
-	<t:genericTypeDisplay clientId="four" value="listOfListOfDates" />
-	<t:genericTypeDisplay clientId="five" value="listOfListOfDates.get(0)" />
-	<t:genericTypeDisplay clientId="six" value="listOfListOfDates.get(0).get(0)" />
-	<t:genericTypeDisplay clientId="seven" value="[1,2,3]" />
-	<t:genericTypeDisplay clientId="eight" value="{'foo':'bar'}" />
-	<t:genericTypeDisplay clientId="nine" value="literal:aaa" />
+	<t:genericTypeDisplay description="mapOfStrings" value="mapOfStrings" />
+	<t:genericTypeDisplay description="mapOfStrings.get('foo')" value="mapOfStrings.get('foo')" />
+	<t:genericTypeDisplay description="setOfLongs" value="setOfLongs" />
+	<t:genericTypeDisplay description="listOfListOfDates" value="listOfListOfDates" />
+	<t:genericTypeDisplay description="listOfListOfDates.get(0)" value="listOfListOfDates.get(0)" />
+	<t:genericTypeDisplay description="listOfListOfDates.get(0).get(0)" value="listOfListOfDates.get(0).get(0)" />
+	<t:genericTypeDisplay description="[1,2,3]" value="[1,2,3]" />
+	<t:genericTypeDisplay description="{'foo':'bar'}" value="{'foo':'bar'}" />
+	<t:genericTypeDisplay description="baz" value="literal:baz" />
 </html>


[2/2] git commit: TAP5-1213 - Refactor public API changes to be backwards compatible

Posted by uk...@apache.org.
TAP5-1213 - Refactor public API changes to be backwards compatible


Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo
Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/737ebd64
Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/737ebd64
Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/737ebd64

Branch: refs/heads/master
Commit: 737ebd64cf8f1607b5c755c7967260e1e755633d
Parents: daa2790
Author: uklance <uk...@gmail.com>
Authored: Mon May 19 21:33:03 2014 +0100
Committer: uklance <uk...@gmail.com>
Committed: Mon May 19 21:34:52 2014 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/tapestry5/Binding.java |  9 -----
 .../java/org/apache/tapestry5/Binding2.java     | 38 +++++++++++++++++++
 .../org/apache/tapestry5/PropertyConduit.java   | 13 -------
 .../org/apache/tapestry5/PropertyConduit2.java  | 40 ++++++++++++++++++++
 .../internal/InternalPropertyConduit.java       |  6 +--
 .../internal/TapestryInternalUtils.java         |  6 ++-
 .../internal/bindings/AbstractBinding.java      |  3 +-
 .../internal/bindings/InternalPropBinding.java  |  4 +-
 .../internal/bindings/PropBinding.java          | 17 ++++++---
 .../CoercingPropertyConduitWrapper.java         | 14 ++++---
 .../services/PropertyConduitSourceImpl.java     |  3 +-
 .../InternalComponentResourcesImpl.java         |  9 ++++-
 .../integration/app1/CoreBehaviorsTests.java    | 18 ++++-----
 .../app1/components/GenericTypeDisplay.java     |  8 ++--
 .../integration/app1/pages/GenericTypeDemo.java | 14 +------
 .../services/PropertyConduitSourceImplTest.java | 19 +++++-----
 .../integration/app1/pages/GenericTypeDemo.tml  | 18 ++++-----
 17 files changed, 153 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
index 711c748..8a99914 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/Binding.java
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5;
 
-import java.lang.reflect.Type;
-
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -55,11 +53,4 @@ public interface Binding extends AnnotationProvider
      * bound.
      */
     Class getBindingType();
-    
-    /**
-     * Returns the generic type of the binding, either the generic type of resource exposed by the binding, or the 
-     * generic type of the property bound.
-     * @since 5.4
-     */
-    Type getBindingGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java b/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
new file mode 100644
index 0000000..7569a8c
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/Binding2.java
@@ -0,0 +1,38 @@
+// Copyright 2006-2013 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.tapestry5;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.apache.tapestry5.services.BindingFactory;
+
+/**
+ * Extension to {@link Binding} that adds a method to access the generic property type.
+ * {@link BindingFactory} instances should ideally return Binding2 objects, not Binding.
+ * This is only primarily of interest to {@link ComponentResources}.
+ * 
+ * @since 5.4
+ */
+public interface Binding2 extends Binding
+{
+    /**
+     * Returns the generic type of the binding
+     * 
+     * @see Method#getGenericReturnType()
+     * @see java.lang.reflect.Field#getGenericType()
+     */
+    Type getBindingGenericType();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
index b28293a..3dbb0c0 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit.java
@@ -14,8 +14,6 @@
 
 package org.apache.tapestry5;
 
-import java.lang.reflect.Type;
-
 import org.apache.tapestry5.ioc.AnnotationProvider;
 
 /**
@@ -44,15 +42,4 @@ public interface PropertyConduit extends AnnotationProvider
      * Returns the type of the property read or updated by the conduit.
      */
     Class getPropertyType();
-    
-    /**
-     * Returns a Type object that represents the declared type for the property.
-     * If the Type is a parameterized type, the Type object returned must accurately 
-     * reflect the actual type parameters used in the source code. If the type of the
-     * underlying property is a type variable or a parameterized type, it is created.
-     * Otherwise, it is resolved.
-     * 
-     * @since 5.4
-     */
-    Type getPropertyGenericType();
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
new file mode 100644
index 0000000..839d70f
--- /dev/null
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/PropertyConduit2.java
@@ -0,0 +1,40 @@
+// Copyright 2007 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.tapestry5;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.apache.tapestry5.services.PropertyConduitSource;
+
+
+/**
+ * Extension to {@link PropertyConduit} that adds a method to access the generic property type.
+ * {@link PropertyConduitSource} instances should ideally return PropertyConduit2 objects, not PropertyConduit.
+ * This is only primarily of interest to {@link Binding2}.
+ * 
+ * @since 5.4
+ */
+public interface PropertyConduit2 extends PropertyConduit
+{
+    /**
+     * Returns the generic type of the property
+     * 
+     * @see Method#getGenericReturnType()
+     * @see java.lang.reflect.Field#getGenericType()
+     * 
+     */
+	Type getPropertyGenericType();
+}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
index 5e19e5b..315b372 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalPropertyConduit.java
@@ -14,16 +14,16 @@
 
 package org.apache.tapestry5.internal;
 
-import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 
 
 /**
- * Extension to {@link org.apache.tapestry5.PropertyConduit} that adds a method to determine the name of the property.
+ * Extension to {@link org.apache.tapestry5.PropertyConduit2} that adds a method to determine the name of the property.
  * 
  * @since 5.2.0
  *
  */
-public interface InternalPropertyConduit extends PropertyConduit
+public interface InternalPropertyConduit extends PropertyConduit2
 {
     /**
      * Returns the name of the property read or updated by the conduit or null. 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
index 45da70b..6c6138b 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/TapestryInternalUtils.java
@@ -494,7 +494,11 @@ public class TapestryInternalUtils
 
             public Type getPropertyGenericType()
             {
-                return conduit.getPropertyGenericType();
+                if (conduit instanceof PropertyConduit2)
+                {
+                	return ((PropertyConduit2) conduit).getPropertyGenericType();
+                }
+            	return conduit.getPropertyType();
             }
             
             public Object get(Object instance)

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
index 12885e1..8e731b7 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AbstractBinding.java
@@ -15,6 +15,7 @@
 package org.apache.tapestry5.internal.bindings;
 
 import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.Binding2;
 import org.apache.tapestry5.ioc.BaseLocatable;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
@@ -26,7 +27,7 @@ import java.lang.reflect.Type;
  * Abstract base class for bindings. Assumes that the binding is read only and invariant. Subclasses must provide an
  * implementation of {@link Binding#get()}.
  */
-public abstract class AbstractBinding extends BaseLocatable implements Binding
+public abstract class AbstractBinding extends BaseLocatable implements Binding2
 {
     public AbstractBinding()
     {

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
index 1d7fd60..8af0943 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/InternalPropBinding.java
@@ -13,13 +13,13 @@
 // limitations under the License.
 package org.apache.tapestry5.internal.bindings;
 
-import org.apache.tapestry5.Binding;
+import org.apache.tapestry5.Binding2;
 
 /**
  * Internal marker interface for {@linkplain org.apache.tapestry5.internal.bindings.PropBinding}
  *
  */
-public interface InternalPropBinding extends Binding
+public interface InternalPropBinding extends Binding2
 {
     /**
      * Returns the name of the property, if exists.

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
index 55ea9d8..afe63eb 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/PropBinding.java
@@ -14,15 +14,16 @@
 
 package org.apache.tapestry5.internal.bindings;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.internal.TapestryInternalUtils;
 import org.apache.tapestry5.internal.services.Invariant;
 import org.apache.tapestry5.ioc.Location;
 import org.apache.tapestry5.ioc.internal.util.TapestryException;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-
 /**
  * Base class for bindings created by the {@link org.apache.tapestry5.internal.bindings.PropBindingFactory}. A subclass
  * of this is created at runtime.
@@ -103,13 +104,17 @@ public class PropBinding extends AbstractBinding implements InternalPropBinding
     }
     
     /**
-     * Get the generic type from the underlying field or getter.
-     * @see PropertyConduit#getPropertyGenericType()
+     * Get the generic type from the underlying property
+     * 
+     * @see PropertyConduit2#getPropertyGenericType()
      */
     @Override
     public Type getBindingGenericType()
     {
-    	return conduit.getPropertyGenericType();
+    	if (conduit instanceof PropertyConduit2) {
+    		return ((PropertyConduit2) conduit).getPropertyGenericType();
+    	}
+    	return conduit.getPropertyType();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
index 158d4a4..4dbfb2d 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/CoercingPropertyConduitWrapper.java
@@ -14,13 +14,14 @@
 
 package org.apache.tapestry5.internal.services;
 
-import org.apache.tapestry5.PropertyConduit;
-import org.apache.tapestry5.ioc.services.TypeCoercer;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
-public class CoercingPropertyConduitWrapper implements PropertyConduit
+import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+
+public class CoercingPropertyConduitWrapper implements PropertyConduit2
 {
     private final PropertyConduit conduit;
 
@@ -49,7 +50,10 @@ public class CoercingPropertyConduitWrapper implements PropertyConduit
     
     public Type getPropertyGenericType()
     {
-    	return conduit.getPropertyGenericType();
+    	if (conduit instanceof PropertyConduit2) {
+    		return ((PropertyConduit2) conduit).getPropertyGenericType();
+    	}
+    	return conduit.getPropertyType();
     }
 
     @SuppressWarnings("unchecked")

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
index 6dab120..701420f 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImpl.java
@@ -18,6 +18,7 @@ import org.antlr.runtime.ANTLRInputStream;
 import org.antlr.runtime.CommonTokenStream;
 import org.antlr.runtime.tree.Tree;
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.internal.InternalPropertyConduit;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionLexer;
 import org.apache.tapestry5.internal.antlr.PropertyExpressionParser;
@@ -63,7 +64,7 @@ public class PropertyConduitSourceImpl implements PropertyConduitSource
         private static final MethodDescription GET_PROPERTY_TYPE = getMethodDescription(PropertyConduit.class,
                 "getPropertyType");
 
-        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit.class,
+        private static final MethodDescription GET_PROPERTY_GENERIC_TYPE = getMethodDescription(PropertyConduit2.class,
                 "getPropertyGenericType");
         
         private static final MethodDescription GET_PROPERTY_NAME = getMethodDescription(InternalPropertyConduit.class,

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
index 5e0e440..c51c086 100644
--- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
+++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/InternalComponentResourcesImpl.java
@@ -349,8 +349,13 @@ public class InternalComponentResourcesImpl extends LockSupport implements Inter
     public Type getBoundGenericType(String parameterName)
     {
         Binding binding = getBinding(parameterName);
-
-        return binding == null ? null : binding.getBindingGenericType();
+        Type genericType;
+        if (binding instanceof Binding2) {
+        	genericType = ((Binding2) binding).getBindingGenericType();
+        } else {
+        	genericType = binding.getBindingType();
+        }
+        return genericType;
     }
     
 

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
index afdc002..d7ecc25 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/CoreBehaviorsTests.java
@@ -1726,14 +1726,14 @@ public class CoreBehaviorsTests extends App1TestCase
     {
     	openLinks("Generic bound type demo");
     	
-		assertTextPresent("clientId=one,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
-		assertTextPresent("clientId=two,type=java.lang.String,genericType=class java.lang.String");
-		assertTextPresent("clientId=three,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
-		assertTextPresent("clientId=four,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
-		assertTextPresent("clientId=five,type=java.util.List,genericType=interface java.util.List");
-		assertTextPresent("clientId=six,type=java.util.Date,genericType=class java.util.Date");
-		assertTextPresent("clientId=seven,type=java.util.List,genericType=interface java.util.List");
-		assertTextPresent("clientId=eight,type=java.util.Map,genericType=interface java.util.Map");
-		assertTextPresent("clientId=nine,type=java.lang.String,genericType=class java.lang.String");
+    	assertTextPresent("description=mapOfStrings,type=java.util.Map,genericType=java.util.Map<java.lang.String, java.lang.String>");
+    	assertTextPresent("description=mapOfStrings.get('foo'),type=java.lang.String,genericType=class java.lang.String");
+    	assertTextPresent("description=setOfLongs,type=java.util.Set,genericType=java.util.Set<java.lang.Long>");
+    	assertTextPresent("description=listOfListOfDates,type=java.util.List,genericType=java.util.List<java.util.List<java.util.Date>>");
+    	assertTextPresent("description=listOfListOfDates.get(0),type=java.util.List,genericType=interface java.util.List");
+    	assertTextPresent("description=listOfListOfDates.get(0).get(0),type=java.util.Date,genericType=class java.util.Date");
+    	assertTextPresent("description=[1,2,3],type=java.util.List,genericType=interface java.util.List");
+    	assertTextPresent("description={'foo':'bar'},type=java.util.Map,genericType=interface java.util.Map");
+    	assertTextPresent("description=baz,type=java.lang.String,genericType=class java.lang.String");
     }
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
index ab95807..f6d2aa7 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/GenericTypeDisplay.java
@@ -22,23 +22,23 @@ import org.apache.tapestry5.annotations.Parameter;
 import org.apache.tapestry5.ioc.annotations.Inject;
 
 /**
- * Outputs the type and genericType of the 'value' parameter in a div
+ * Outputs the type and genericType of the 'value' binding in a div
  */
 public class GenericTypeDisplay {
 	@Inject
 	private ComponentResources resources;
 	
 	@Parameter(required=true, defaultPrefix=BindingConstants.LITERAL)
-	private String clientId;
+	private String description;
 	
 	@Parameter(required=true)
 	private Object value;
 	
 	void afterRender(MarkupWriter writer) {
-		writer.element("div", "id", clientId);
+		writer.element("div");
 		Class<?> type = resources.getBoundType("value");
 		Type genericType = resources.getBoundGenericType("value");
-		String text = String.format("clientId=%s,type=%s,genericType=%s", clientId, type.getName(), genericType.toString());
+		String text = String.format("description=%s,type=%s,genericType=%s", description, type.getName(), genericType.toString());
 		writer.write(text);
 		writer.end();
 	}

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
index 80bf40a..8e9fdd3 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.java
@@ -1,14 +1,11 @@
 package org.apache.tapestry5.integration.app1.pages;
 
-import java.util.Arrays;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SetupRender;
 
 public class GenericTypeDemo {
 	private Set<Long> setOfLongs;
@@ -17,17 +14,10 @@ public class GenericTypeDemo {
 	private Map<String, String> mapOfStrings;
 	
 	public List<List<Date>> getListOfListOfDates() {
-		List<Date> dates = Arrays.asList(new Date(Long.MIN_VALUE), new Date(0), new Date(Long.MAX_VALUE));
-		return Arrays.asList(dates);
+		throw new UnsupportedOperationException();
 	}
 	
 	public void setSetOfLongs(Set<Long> setOfLongs) {
-		this.setOfLongs = setOfLongs;
-	}
-	
-	@SetupRender
-	void setupRender() {
-		mapOfStrings = new HashMap<String,String>();
-		mapOfStrings.put("foo", "bar");
+		throw new UnsupportedOperationException();
 	}
 }

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
index 5c9f88a..0e61220 100644
--- a/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
+++ b/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/PropertyConduitSourceImplTest.java
@@ -14,8 +14,14 @@
 
 package org.apache.tapestry5.internal.services;
 
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry5.Block;
 import org.apache.tapestry5.PropertyConduit;
+import org.apache.tapestry5.PropertyConduit2;
 import org.apache.tapestry5.beaneditor.NonVisual;
 import org.apache.tapestry5.beaneditor.Validate;
 import org.apache.tapestry5.integration.app1.data.IntegerHolder;
@@ -29,11 +35,6 @@ import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
 /**
  * Most of the testing occurs inside {@link PropBindingFactoryTest} (due to
  * historical reasons).
@@ -178,10 +179,10 @@ public class PropertyConduitSourceImplTest extends InternalBaseTestCase
     @Test
     public void generic_types_are_determined()
     {
-        PropertyConduit datesConduit = source.create(GenericBean.class, "dates");
-        PropertyConduit longsConduit = source.create(GenericBean.class, "longs");
-        PropertyConduit nestedDatesConduit = source.create(GenericBean.class, "genericBeans.get(0).dates");
-        PropertyConduit mapConduit = source.create(GenericBean.class, "map");
+        PropertyConduit2 datesConduit = (PropertyConduit2) source.create(GenericBean.class, "dates");
+        PropertyConduit2 longsConduit = (PropertyConduit2) source.create(GenericBean.class, "longs");
+        PropertyConduit2 nestedDatesConduit = (PropertyConduit2) source.create(GenericBean.class, "genericBeans.get(0).dates");
+        PropertyConduit2 mapConduit = (PropertyConduit2) source.create(GenericBean.class, "map");
         assertEquals(datesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");
         assertEquals(longsConduit.getPropertyGenericType().toString(), "java.util.List<java.lang.Long>");
         assertEquals(nestedDatesConduit.getPropertyGenericType().toString(), "java.util.List<java.util.Date>");

http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/737ebd64/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
----------------------------------------------------------------------
diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
index c9f4b78..12e347a 100644
--- a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
+++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/GenericTypeDemo.tml
@@ -1,12 +1,12 @@
 <html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
 	<h1>Generic Type Tests</h1>
-	<t:genericTypeDisplay clientId="one" value="mapOfStrings" />
-	<t:genericTypeDisplay clientId="two" value="mapOfStrings.get('foo')" />
-	<t:genericTypeDisplay clientId="three" value="setOfLongs" />
-	<t:genericTypeDisplay clientId="four" value="listOfListOfDates" />
-	<t:genericTypeDisplay clientId="five" value="listOfListOfDates.get(0)" />
-	<t:genericTypeDisplay clientId="six" value="listOfListOfDates.get(0).get(0)" />
-	<t:genericTypeDisplay clientId="seven" value="[1,2,3]" />
-	<t:genericTypeDisplay clientId="eight" value="{'foo':'bar'}" />
-	<t:genericTypeDisplay clientId="nine" value="literal:aaa" />
+	<t:genericTypeDisplay description="mapOfStrings" value="mapOfStrings" />
+	<t:genericTypeDisplay description="mapOfStrings.get('foo')" value="mapOfStrings.get('foo')" />
+	<t:genericTypeDisplay description="setOfLongs" value="setOfLongs" />
+	<t:genericTypeDisplay description="listOfListOfDates" value="listOfListOfDates" />
+	<t:genericTypeDisplay description="listOfListOfDates.get(0)" value="listOfListOfDates.get(0)" />
+	<t:genericTypeDisplay description="listOfListOfDates.get(0).get(0)" value="listOfListOfDates.get(0).get(0)" />
+	<t:genericTypeDisplay description="[1,2,3]" value="[1,2,3]" />
+	<t:genericTypeDisplay description="{'foo':'bar'}" value="{'foo':'bar'}" />
+	<t:genericTypeDisplay description="baz" value="literal:baz" />
 </html>