You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2011/04/10 03:54:49 UTC

svn commit: r1090732 - in /tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc: internal/services/PlasticProxyFactoryImpl.java services/PlasticProxyFactory.java

Author: hlship
Date: Sun Apr 10 01:54:49 2011
New Revision: 1090732

URL: http://svn.apache.org/viewvc?rev=1090732&view=rev
Log:
TAP5-853: Introduce a method on PlasticProxyFactory that creates a proxy instance from an interface type and an ObjectCreator

Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java?rev=1090732&r1=1090731&r2=1090732&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PlasticProxyFactoryImpl.java Sun Apr 10 01:54:49 2011
@@ -1,10 +1,21 @@
 package org.apache.tapestry5.ioc.internal.services;
 
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
 import org.apache.tapestry5.plastic.ClassInstantiator;
+import org.apache.tapestry5.plastic.InstructionBuilder;
+import org.apache.tapestry5.plastic.InstructionBuilderCallback;
+import org.apache.tapestry5.plastic.MethodDescription;
+import org.apache.tapestry5.plastic.PlasticClass;
 import org.apache.tapestry5.plastic.PlasticClassTransformation;
 import org.apache.tapestry5.plastic.PlasticClassTransformer;
+import org.apache.tapestry5.plastic.PlasticField;
 import org.apache.tapestry5.plastic.PlasticManager;
+import org.apache.tapestry5.plastic.PlasticMethod;
 
 public class PlasticProxyFactoryImpl implements PlasticProxyFactory
 {
@@ -30,4 +41,43 @@ public class PlasticProxyFactoryImpl imp
         return manager.createProxyTransformation(interfaceType);
     }
 
+    public <T> T createProxy(final Class<T> interfaceType, final ObjectCreator<T> creator, final String description)
+    {
+        assert creator != null;
+        assert InternalUtils.isNonBlank(description);
+
+        ClassInstantiator instantiator = createProxy(interfaceType, new PlasticClassTransformer()
+        {
+            public void transform(PlasticClass plasticClass)
+            {
+                final PlasticField objectCreatorField = plasticClass.introduceField(ObjectCreator.class, "creator")
+                        .inject(creator);
+
+                PlasticMethod delegateMethod = plasticClass.introducePrivateMethod(interfaceType.getName(), "delegate",
+                        null, null);
+
+                delegateMethod.changeImplementation(new InstructionBuilderCallback()
+                {
+                    public void doBuild(InstructionBuilder builder)
+                    {
+                        builder.loadThis().getField(objectCreatorField);
+                        builder.invoke(ObjectCreator.class, Object.class, "createObject");
+                        builder.checkcast(interfaceType).returnResult();
+                    }
+                });
+
+                for (Method method : interfaceType.getMethods())
+                {
+                    plasticClass.introduceMethod(method).delegateTo(delegateMethod);
+                }
+
+                plasticClass.addToString(description);
+
+                // TODO: Copy annotations from delegate?
+            }
+        });
+
+        return interfaceType.cast(instantiator.newInstance());
+    }
+
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java?rev=1090732&r1=1090731&r2=1090732&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/PlasticProxyFactory.java Sun Apr 10 01:54:49 2011
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry5.ioc.services;
 
+import org.apache.tapestry5.ioc.ObjectCreator;
 import org.apache.tapestry5.plastic.ClassInstantiator;
 import org.apache.tapestry5.plastic.PlasticClassTransformation;
 import org.apache.tapestry5.plastic.PlasticClassTransformer;
@@ -53,4 +54,22 @@ public interface PlasticProxyFactory
      * @return transformation from which an instantiator may be created
      */
     PlasticClassTransformation createProxyTransformation(Class interfaceType);
+
+    /**
+     * Creates a proxy instance that delegates all methods through a corresponding
+     * ObjectCreator. Each method invocation on the proxy will route through {@link ObjectCreator#createObject()} (the
+     * creator implementation may decide to
+     * cache the return value as appropriate).
+     * 
+     * @param <T>
+     *            type of proxy
+     * @param interfaceType
+     *            interface class for proxy
+     * @param creator
+     *            object responsible for creating the real object
+     * @param description
+     *            the <code>toString()</code> of the proxy
+     * @return proxy instance
+     */
+    <T> T createProxy(Class<T> interfaceType, ObjectCreator<T> creator, String description);
 }