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;
+ }
+}