You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2013/01/19 12:06:16 UTC

svn commit: r1435522 - in /openwebbeans/trunk/webbeans-impl/src: main/java/org/apache/webbeans/component/creation/ main/java/org/apache/webbeans/config/ main/java/org/apache/webbeans/intercept/ main/java/org/apache/webbeans/proxy/ test/java/org/apache/...

Author: struberg
Date: Sat Jan 19 11:06:15 2013
New Revision: 1435522

URL: http://svn.apache.org/viewvc?rev=1435522&view=rev
Log:
OWB-344 add SubclassProxyFactory

Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java
      - copied, changed from r1435433, openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/DecoratorProxyFactory.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/SubclassProxyFactoryTest.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/MyAbstractTestDecorator.java
Removed:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/DecoratorProxyFactory.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/DecoratorBeanBuilder.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/DecoratorBeanBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/DecoratorBeanBuilder.java?rev=1435522&r1=1435521&r2=1435522&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/DecoratorBeanBuilder.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/creation/DecoratorBeanBuilder.java Sat Jan 19 11:06:15 2013
@@ -31,6 +31,7 @@ import javax.inject.Inject;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
@@ -309,7 +310,7 @@ public class DecoratorBeanBuilder<T> ext
 
         if (Modifier.isAbstract(annotatedType.getJavaClass().getModifiers()))
         {
-
+            injectionTarget = new AbstractDecoratorInjectionTarget(annotatedType, points, webBeansContext, postConstructMethods, preDestroyMethods);
         }
         return injectionTarget;
     }
@@ -361,8 +362,15 @@ public class DecoratorBeanBuilder<T> ext
         @Override
         protected AnnotatedConstructor<T> createConstructor()
         {
-            //X TODO create proxy subclass
-            
+            // create proxy subclass
+            ClassLoader classLoader = this.getClass().getClassLoader();
+            Class<T> classToProxy = annotatedType.getJavaClass();
+
+            List<Method> methods = ClassUtil.getNonPrivateMethods(classToProxy);
+
+            proxySubClass = webBeansContext.getSubclassProxyFactory().createDecoratorSubclass(null);
+
+
             //X TODO what about @Inject constructors?
             Constructor<T> ct = webBeansContext.getWebBeansUtil().getNoArgConstructor(proxySubClass);
             return new AnnotatedConstructorImpl<T>(webBeansContext, ct, annotatedType);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java?rev=1435522&r1=1435521&r2=1435522&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/WebBeansContext.java Sat Jan 19 11:06:15 2013
@@ -44,6 +44,7 @@ import org.apache.webbeans.intercept.ejb
 import org.apache.webbeans.plugins.PluginLoader;
 import org.apache.webbeans.portable.AnnotatedElementFactory;
 import org.apache.webbeans.portable.events.ExtensionLoader;
+import org.apache.webbeans.proxy.SubclassProxyFactory;
 import org.apache.webbeans.proxy.InterceptorDecoratorProxyFactory;
 import org.apache.webbeans.proxy.NormalScopeProxyFactory;
 import org.apache.webbeans.service.DefaultLoaderService;
@@ -81,6 +82,7 @@ public class WebBeansContext
     private final WebBeansInterceptorConfig webBeansInterceptorConfig = new WebBeansInterceptorConfig(this);
     private final InterceptorDecoratorProxyFactory interceptorDecoratorProxyFactory = new InterceptorDecoratorProxyFactory(this);
     private final NormalScopeProxyFactory normalScopeProxyFactory = new NormalScopeProxyFactory(this);
+    private final SubclassProxyFactory subclassProxyFactory = new SubclassProxyFactory(this);
     private final OpenWebBeansConfiguration openWebBeansConfiguration;
     private final PluginLoader pluginLoader = new PluginLoader();
     private final SerializableBeanVault serializableBeanVault = new SerializableBeanVault();
@@ -151,6 +153,7 @@ public class WebBeansContext
         managerMap.put(InterceptorsManager.class, interceptorsManager);
         managerMap.put(InterceptorDecoratorProxyFactory.class, interceptorDecoratorProxyFactory);
         managerMap.put(NormalScopeProxyFactory.class, normalScopeProxyFactory);
+        managerMap.put(SubclassProxyFactory.class, subclassProxyFactory);
         managerMap.put(OpenWebBeansConfiguration.class, openWebBeansConfiguration);
         managerMap.put(PluginLoader.class, pluginLoader);
         managerMap.put(SerializableBeanVault.class, serializableBeanVault);
@@ -334,6 +337,11 @@ public class WebBeansContext
         return normalScopeProxyFactory;
     }
 
+    public SubclassProxyFactory getSubclassProxyFactory()
+    {
+        return subclassProxyFactory;
+    }
+
     public ScannerService getScannerService()
     {
         if (scannerService == null)

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java?rev=1435522&r1=1435521&r2=1435522&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/WebBeansInterceptorConfig.java Sat Jan 19 11:06:15 2013
@@ -133,7 +133,6 @@ public final class WebBeansInterceptorCo
                 // we only need to create a proxy class for intercepted or decorated Beans
                 InterceptorDecoratorProxyFactory pf = webBeansContext.getInterceptorDecoratorProxyFactory();
 
-                // we take a fresh URLClassLoader to not blur the test classpath with synthetic classes.
                 ClassLoader classLoader = this.getClass().getClassLoader();
 
                 Method[] businessMethods = methodInterceptors.keySet().toArray(new Method[methodInterceptors.size()]);

Copied: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java (from r1435433, openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/DecoratorProxyFactory.java)
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java?p2=openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java&p1=openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/DecoratorProxyFactory.java&r1=1435433&r2=1435522&rev=1435522&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/DecoratorProxyFactory.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/SubclassProxyFactory.java Sat Jan 19 11:06:15 2013
@@ -19,22 +19,15 @@
 package org.apache.webbeans.proxy;
 
 import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.inject.Provider;
 import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.List;
 
 import org.apache.webbeans.component.OwbBean;
-import org.apache.webbeans.config.OpenWebBeansConfiguration;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.exception.WebBeansConfigurationException;
-import org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler;
 import org.apache.webbeans.util.ClassUtil;
-import org.apache.webbeans.util.ExceptionUtil;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
@@ -42,11 +35,12 @@ import org.objectweb.asm.Type;
 
 /**
  * This factory creates subclasses for abstract classes.
+ * TODO this is not used/nor finished yet.
  */
-public class DecoratorProxyFactory extends AbstractProxyFactory
+public class SubclassProxyFactory extends AbstractProxyFactory
 {
 
-    public DecoratorProxyFactory(WebBeansContext webBeansContext)
+    public SubclassProxyFactory(WebBeansContext webBeansContext)
     {
         super(webBeansContext);
     }
@@ -58,7 +52,7 @@ public class DecoratorProxyFactory exten
     }
 
 
-    public <T> T createDecoratorSubclass(Bean<T> bean)
+    public <T> Class<T> createDecoratorSubclass(Bean<T> bean)
     {
         ClassLoader classLoader = bean.getClass().getClassLoader();
 
@@ -79,50 +73,9 @@ public class DecoratorProxyFactory exten
             throw new WebBeansConfigurationException("Only abstract classes should get subclassed, not " + classToProxy);
         }
 
-        Class<? extends T> proxyClass = createSubClass(classLoader, classToProxy);
+        Class<T> proxyClass = createSubClass(classLoader, classToProxy);
 
-        return createProxyInstance(proxyClass, getInstanceProvider(classLoader, bean));
-    }
-
-    public Provider getInstanceProvider(ClassLoader classLoader, Bean<?> bean)
-    {
-        String scopeClassName = bean.getScope().getName();
-        Class<? extends Provider> instanceProviderClass = null;
-        String proxyMappingConfigKey = OpenWebBeansConfiguration.PROXY_MAPPING_PREFIX + scopeClassName;
-        String className = webBeansContext.getOpenWebBeansConfiguration().getProperty(proxyMappingConfigKey);
-        if (className == null || NormalScopedBeanInterceptorHandler.class.getName().equals(className))
-        {
-            return new NormalScopedBeanInterceptorHandler(webBeansContext.getBeanManagerImpl(), bean);
-        }
-
-        try
-        {
-            instanceProviderClass = (Class<? extends Provider>) Class.forName(className, true, classLoader);
-            Constructor<?> ct = instanceProviderClass.getConstructor(BeanManager.class, Bean.class);
-            return (Provider) ct.newInstance(webBeansContext.getBeanManagerImpl(), bean);
-        }
-        catch (NoSuchMethodException nsme)
-        {
-            throw new WebBeansConfigurationException("Configured InterceptorHandler " + className +" has wrong constructor" , nsme);
-        }
-        catch (ClassNotFoundException e)
-        {
-            throw new WebBeansConfigurationException("Configured InterceptorHandler " + className +" cannot be found", e);
-        }
-        catch (InvocationTargetException e)
-        {
-            throw new WebBeansConfigurationException("Configured InterceptorHandler " + className +" creation exception", e);
-        }
-        catch (InstantiationException e)
-        {
-            throw new WebBeansConfigurationException("Configured InterceptorHandler " + className +" creation exception", e);
-        }
-        catch (IllegalAccessException e)
-        {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-        }
-
-        return null;
+        return proxyClass;
     }
 
 
@@ -138,49 +91,14 @@ public class DecoratorProxyFactory exten
     {
         String proxyClassName = getUnusedProxyClassName(classLoader, classToProxy.getName() + "$OwbSubClass");
 
-        Method[] nonInterceptedMethods;
-        if (classToProxy.isInterface())
-        {
-            nonInterceptedMethods = classToProxy.getMethods();
-        }
-        else
-        {
-            List<Method> methods = ClassUtil.getNonPrivateMethods(classToProxy);
-            nonInterceptedMethods = methods.toArray(new Method[methods.size()]);
-        }
+        List<Method> methods = ClassUtil.getNonPrivateMethods(classToProxy);
+        Method[] businessMethods = methods.toArray(new Method[methods.size()]);
 
-        Class<T> clazz = createProxyClass(classLoader, proxyClassName, classToProxy, null, nonInterceptedMethods);
+        Class<T> clazz = createProxyClass(classLoader, proxyClassName, classToProxy, businessMethods, new Method[0]);
 
         return clazz;
     }
 
-    public <T> T createProxyInstance(Class<T> proxyClass, Provider provider)
-            throws ProxyGenerationException
-    {
-        try
-        {
-            T proxy = proxyClass.newInstance();
-
-            Field delegateField = proxy.getClass().getDeclaredField(FIELD_INSTANCE_PROVIDER);
-            delegateField.setAccessible(true);
-            delegateField.set(proxy, provider);
-
-            return proxy;
-        }
-        catch (InstantiationException e)
-        {
-            throw new ProxyGenerationException(e);
-        }
-        catch (IllegalAccessException e)
-        {
-            throw new ProxyGenerationException(e);
-        }
-        catch (NoSuchFieldException e)
-        {
-            throw new ProxyGenerationException(e);
-        }
-    }
-
 
     @Override
     protected void createConstructor(ClassWriter cw, String proxyClassFileName, Class<?> classToProxy, String classFileName) throws ProxyGenerationException
@@ -206,10 +124,6 @@ public class DecoratorProxyFactory exten
             mv.visitVarInsn(Opcodes.ALOAD, 0);
             mv.visitMethodInsn(Opcodes.INVOKESPECIAL, parentClassFileName, "<init>", descriptor);
 
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitInsn(Opcodes.ACONST_NULL);
-            mv.visitFieldInsn(Opcodes.PUTFIELD, proxyClassFileName, FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class));
-
             mv.visitInsn(Opcodes.RETURN);
             mv.visitMaxs(-1, -1);
             mv.visitEnd();
@@ -223,9 +137,6 @@ public class DecoratorProxyFactory exten
     @Override
     protected void createInstanceVariables(ClassWriter cw, Class<?> classToProxy, String classFileName)
     {
-        // variable #1, the Provider<?> for the Contextual Instance
-        cw.visitField(Opcodes.ACC_PRIVATE,
-                FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class), null, null).visitEnd();
     }
 
     @Override
@@ -261,16 +172,7 @@ public class DecoratorProxyFactory exten
             // fill method body
             mv.visitCode();
 
-            // load the contextual instance Provider
-            mv.visitVarInsn(Opcodes.ALOAD, 0);
-            mv.visitFieldInsn(Opcodes.GETFIELD, proxyClassFileName, FIELD_INSTANCE_PROVIDER, Type.getDescriptor(Provider.class));
-
-            // invoke the get() method on the Provider
-            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getInternalName(Provider.class), "get", "()Ljava/lang/Object;");
-
-            // and convert the Object to the target class type
-            mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(classToProxy));
-
+            boolean abstractMethod = Modifier.isAbstract(delegatedMethod.getModifiers());
 
             // now calculate the parameters
             int offset = 1;
@@ -283,9 +185,15 @@ public class DecoratorProxyFactory exten
 
             // and finally invoke the target method on the provided Contextual Instance
             final Type declaringClass = Type.getType(delegatedMethod.getDeclaringClass());
-            boolean interfaceMethod = Modifier.isAbstract(delegatedMethod.getModifiers());
-            mv.visitMethodInsn(interfaceMethod ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL,
-                               declaringClass.getInternalName(), delegatedMethod.getName(), methodDescriptor);
+            if (abstractMethod)
+            {
+                // generate an empty return block
+            }
+            else
+            {
+                // invoke the method on the super class;
+                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, declaringClass.getInternalName(), delegatedMethod.getName(), methodDescriptor);
+            }
 
             generateReturn(mv, delegatedMethod);
 

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/SubclassProxyFactoryTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/SubclassProxyFactoryTest.java?rev=1435522&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/SubclassProxyFactoryTest.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/SubclassProxyFactoryTest.java Sat Jan 19 11:06:15 2013
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.webbeans.newtests.interceptors.factory;
+
+import org.apache.webbeans.newtests.AbstractUnitTest;
+import org.apache.webbeans.newtests.decorators.common.Cow;
+import org.apache.webbeans.newtests.interceptors.factory.beans.MyAbstractTestDecorator;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class SubclassProxyFactoryTest extends AbstractUnitTest
+{
+    @Test
+    public void testSubclassProxy() throws Exception
+    {
+        startContainer();
+
+        Class<? extends MyAbstractTestDecorator> subClass
+                = getWebBeansContext().getSubclassProxyFactory().createSubClass(this.getClass().getClassLoader(), MyAbstractTestDecorator.class);
+        Assert.assertNotNull(subClass);
+
+        MyAbstractTestDecorator instance = subClass.newInstance();
+        Assert.assertNotNull(instance);
+
+        Cow cow = new Cow();
+        instance.setDelegate(cow);
+
+        Assert.assertEquals(49, instance.getAge());
+
+        shutDownContainer();
+    }
+}

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/MyAbstractTestDecorator.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/MyAbstractTestDecorator.java?rev=1435522&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/MyAbstractTestDecorator.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/newtests/interceptors/factory/beans/MyAbstractTestDecorator.java Sat Jan 19 11:06:15 2013
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.webbeans.newtests.interceptors.factory.beans;
+
+import javax.decorator.Decorator;
+import javax.decorator.Delegate;
+import javax.inject.Inject;
+
+import org.apache.webbeans.newtests.decorators.common.Breeded;
+
+/**
+ * Abstract Decorator for subclassing proxy test
+ */
+@Decorator
+public abstract class MyAbstractTestDecorator implements Breeded
+{
+    @Inject
+    @Delegate
+    private Breeded delegate;
+
+
+    @Override
+    public int getAge()
+    {
+        return delegate.getAge() + 42;
+    }
+
+    public void setDelegate(Breeded delegate)
+    {
+        this.delegate = delegate;
+    }
+}