From d53a65ac006c86943e8fc34cc1d24a2cdf9170b4 Mon Sep 17 00:00:00 2001 From: Pete Muir Date: Sat, 25 Jul 2009 21:19:28 +0000 Subject: [PATCH] Fix disposal methods for enterprise beans, use OO for DisposalMethodBean git-svn-id: http://anonsvn.jboss.org/repos/weld/ri/trunk@3231 1c488680-804c-0410-94cd-c6b725194a0e --- .../org/jboss/webbeans/bean/AbstractBean.java | 7 - .../webbeans/bean/AbstractClassBean.java | 7 +- .../webbeans/bean/AbstractProducerBean.java | 71 +------ .../webbeans/bean/AbstractReceiverBean.java | 92 +++++++++ .../webbeans/bean/DisposalMethodBean.java | 178 ++++++------------ .../webbeans/bean/ProducerMethodBean.java | 10 +- .../bootstrap/AbstractBeanDeployer.java | 2 +- .../bootstrap/BeanDeployerEnvironment.java | 8 +- 8 files changed, 161 insertions(+), 214 deletions(-) create mode 100644 impl/src/main/java/org/jboss/webbeans/bean/AbstractReceiverBean.java diff --git a/impl/src/main/java/org/jboss/webbeans/bean/AbstractBean.java b/impl/src/main/java/org/jboss/webbeans/bean/AbstractBean.java index 9db96cfbf64..bd8014e6a73 100644 --- a/impl/src/main/java/org/jboss/webbeans/bean/AbstractBean.java +++ b/impl/src/main/java/org/jboss/webbeans/bean/AbstractBean.java @@ -233,13 +233,6 @@ protected void initDeploymentTypeFromStereotype() } } - /** - * Gets the default deployment type - * - * @return The default deployment type - */ - protected abstract Class getDefaultDeploymentType(); - /** * Initializes the name */ diff --git a/impl/src/main/java/org/jboss/webbeans/bean/AbstractClassBean.java b/impl/src/main/java/org/jboss/webbeans/bean/AbstractClassBean.java index aab148fa411..093ae171353 100644 --- a/impl/src/main/java/org/jboss/webbeans/bean/AbstractClassBean.java +++ b/impl/src/main/java/org/jboss/webbeans/bean/AbstractClassBean.java @@ -426,12 +426,6 @@ public String toString() return "AbstractClassBean " + getName(); } - @Override - /* - * Gets the default deployment type - * - * @return The default deployment type - */ protected Class getDefaultDeploymentType() { return Production.class; @@ -442,5 +436,6 @@ public String getId() { return id; } + } diff --git a/impl/src/main/java/org/jboss/webbeans/bean/AbstractProducerBean.java b/impl/src/main/java/org/jboss/webbeans/bean/AbstractProducerBean.java index 85b83cf89b2..c6794eae2ee 100644 --- a/impl/src/main/java/org/jboss/webbeans/bean/AbstractProducerBean.java +++ b/impl/src/main/java/org/jboss/webbeans/bean/AbstractProducerBean.java @@ -40,7 +40,6 @@ import org.jboss.webbeans.BeanManagerImpl; import org.jboss.webbeans.DefinitionException; import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment; -import org.jboss.webbeans.context.CreationalContextImpl; import org.jboss.webbeans.introspector.WBMember; import org.jboss.webbeans.log.LogProvider; import org.jboss.webbeans.log.Logging; @@ -57,11 +56,8 @@ * @param * @param */ -public abstract class AbstractProducerBean extends AbstractBean +public abstract class AbstractProducerBean extends AbstractReceiverBean { - // The declaring bean - protected AbstractClassBean declaringBean; - private static final LogProvider log = Logging.getLogProvider(AbstractProducerBean.class); /** @@ -72,8 +68,7 @@ public abstract class AbstractProducerBean extends Abstract */ public AbstractProducerBean(AbstractClassBean declaringBean, BeanManagerImpl manager) { - super(manager); - this.declaringBean = declaringBean; + super(declaringBean, manager); } @Override @@ -86,28 +81,9 @@ public Class getBeanClass() return getDeclaringBean().getBeanClass(); } - @Override - public String getId() - { - // TODO Auto-generated method stub - return null; - } - - public void destroy(T instance, CreationalContext creationalContext) - { - // TODO Auto-generated method stub - - } - - /** - * Gets the deployment types - * - * @return The deployment types of the declaring bean - */ - @Override protected Class getDefaultDeploymentType() { - return deploymentType = declaringBean.getDeploymentType(); + return getDeclaringBean().getDeploymentType(); } /** @@ -171,16 +147,6 @@ protected Type getDeclaredBeanType() return null; } - /** - * Returns the declaring bean - * - * @return The bean representation - */ - public AbstractClassBean getDeclaringBean() - { - return declaringBean; - } - /** * Validates the producer method */ @@ -209,7 +175,7 @@ protected void checkProducerReturnType() @Override public void initialize(BeanDeployerEnvironment environment) { - declaringBean.initialize(environment); + getDeclaringBean().initialize(environment); super.initialize(environment); checkProducerReturnType(); } @@ -321,35 +287,6 @@ protected void initSerializable() _serializable = true; } - /** - * Gets the receiver of the product - * - * @return The receiver - */ - protected Object getReceiver(CreationalContext creationalContext) - { - // This is a bit dangerous, as it means that producer methods can end of - // executing on partially constructed instances. Also, it's not required - // by the spec... - if (getAnnotatedItem().isStatic()) - { - return null; - } - else - { - if (creationalContext instanceof CreationalContextImpl) - { - CreationalContextImpl creationalContextImpl = (CreationalContextImpl) creationalContext; - if (creationalContextImpl.containsIncompleteInstance(getDeclaringBean())) - { - log.warn("Executing producer field or method " + getAnnotatedItem() + " on incomplete declaring bean " + getDeclaringBean() + " due to circular injection"); - return creationalContextImpl.getIncompleteInstance(getDeclaringBean()); - } - } - return manager.getReference(getDeclaringBean(), Object.class, creationalContext); - } - } - /** * Creates an instance of the bean * diff --git a/impl/src/main/java/org/jboss/webbeans/bean/AbstractReceiverBean.java b/impl/src/main/java/org/jboss/webbeans/bean/AbstractReceiverBean.java new file mode 100644 index 00000000000..d2adb9e521b --- /dev/null +++ b/impl/src/main/java/org/jboss/webbeans/bean/AbstractReceiverBean.java @@ -0,0 +1,92 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * 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.jboss.webbeans.bean; + +import java.lang.reflect.Member; + +import javax.enterprise.context.spi.CreationalContext; + +import org.jboss.webbeans.BeanManagerImpl; +import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment; +import org.jboss.webbeans.context.CreationalContextImpl; +import org.jboss.webbeans.log.LogProvider; +import org.jboss.webbeans.log.Logging; + +/** + * @author pmuir + * + */ +public abstract class AbstractReceiverBean extends AbstractBean +{ + + private static final LogProvider log = Logging.getLogProvider(AbstractReceiverBean.class); + + private AbstractClassBean declaringBean; + + public AbstractReceiverBean(AbstractClassBean declaringBean, BeanManagerImpl manager) + { + super(manager); + this.declaringBean = declaringBean; + } + + @Override + public void initialize(BeanDeployerEnvironment environment) + { + super.initialize(environment); + } + + /** + * Gets the receiver of the product + * + * @return The receiver + */ + protected Object getReceiver(CreationalContext creationalContext) + { + // This is a bit dangerous, as it means that producer methods can end of + // executing on partially constructed instances. Also, it's not required + // by the spec... + if (getAnnotatedItem().isStatic()) + { + return null; + } + else + { + if (creationalContext instanceof CreationalContextImpl) + { + CreationalContextImpl creationalContextImpl = (CreationalContextImpl) creationalContext; + if (creationalContextImpl.containsIncompleteInstance(getDeclaringBean())) + { + log.warn("Executing producer field or method " + getAnnotatedItem() + " on incomplete declaring bean " + getDeclaringBean() + " due to circular injection"); + return creationalContextImpl.getIncompleteInstance(getDeclaringBean()); + } + } + return manager.getReference(getDeclaringBean(), Object.class, creationalContext); + } + } + + + /** + * Returns the declaring bean + * + * @return The bean representation + */ + public AbstractClassBean getDeclaringBean() + { + return declaringBean; + } + +} diff --git a/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java b/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java index a618f3c212e..4990871e192 100644 --- a/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java +++ b/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java @@ -20,50 +20,43 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.HashSet; -import java.util.List; import java.util.Set; -import javax.enterprise.context.Dependent; -import javax.enterprise.context.ScopeType; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.event.Observes; import javax.enterprise.inject.Disposes; import javax.enterprise.inject.Initializer; import javax.enterprise.inject.Produces; -import javax.enterprise.inject.deployment.DeploymentType; import org.jboss.webbeans.BeanManagerImpl; import org.jboss.webbeans.DefinitionException; import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment; import org.jboss.webbeans.injection.MethodInjectionPoint; -import org.jboss.webbeans.injection.ParameterInjectionPoint; import org.jboss.webbeans.injection.WBInjectionPoint; import org.jboss.webbeans.introspector.WBMethod; -import org.jboss.webbeans.introspector.WBParameter; -import org.jboss.webbeans.log.LogProvider; -import org.jboss.webbeans.log.Logging; -public class DisposalMethodBean extends AbstractBean +public class DisposalMethodBean extends AbstractReceiverBean { - private static final LogProvider log = Logging.getLogProvider(AbstractProducerBean.class); - protected AbstractClassBean declaringBean; - private DisposalMethodBean specializedBean; protected MethodInjectionPoint disposalMethodInjectionPoint; - protected Set> disposalInjectionPoints; private final String id; protected DisposalMethodBean(BeanManagerImpl manager, WBMethod disposalMethod, AbstractClassBean declaringBean) { - super(manager); + super(declaringBean, manager); this.disposalMethodInjectionPoint = MethodInjectionPoint.of(this, disposalMethod); - this.declaringBean = declaringBean; - checkDisposalMethod(); + this.id = createId("DisposalMethod-" + declaringBean.getName() + "-" + disposalMethod.getSignature().toString()); initBindings(); initType(); initTypes(); - this.id = createId("DisposalMethod-" + declaringBean.getName() + "-" + disposalMethod.getSignature().toString()); - + } + + @Override + public void initialize(BeanDeployerEnvironment environment) + { + // TODO Auto-generated method stub + super.initialize(environment); + checkDisposalMethod(); } @SuppressWarnings("unchecked") @@ -85,22 +78,7 @@ public static DisposalMethodBean of(BeanManagerImpl manager, WBMethod protected void initInjectionPoints() { - disposalInjectionPoints = new HashSet>(); - - List> disposalMethodParameters = disposalMethodInjectionPoint.getParameters(); - - // First one must be @Disposes, if more, register injectionpoints - if (disposalMethodParameters.size() > 1) - { - for (int i = 1; i < disposalMethodParameters.size(); i++) - { - WBParameter parameter = disposalMethodParameters.get(i); - disposalInjectionPoints.add(ParameterInjectionPoint.of(declaringBean, parameter)); - } - } - - injectionPoints.add(MethodInjectionPoint.of(declaringBean, disposalMethodInjectionPoint)); - + injectionPoints.add(disposalMethodInjectionPoint); } @Override @@ -112,12 +90,6 @@ protected void initBindings() initDefaultBindings(); } - @Override - public Class getDeploymentType() - { - return declaringBean.getDeploymentType(); - } - /** * Initializes the API types */ @@ -127,7 +99,6 @@ protected void initTypes() Set types = new HashSet(); types = new HashSet(); types.addAll(disposalMethodInjectionPoint.getAnnotatedParameters(Disposes.class).get(0).getTypeClosure()); - types.add(getType()); types.add(Object.class); super.types = types; } @@ -141,13 +112,13 @@ protected void initTypes() @Override public String getName() { - return disposalMethodInjectionPoint.getPropertyName(); + return null; } @Override public Class getScopeType() { - return declaringBean.getScopeType(); + return null; } @Override @@ -165,13 +136,15 @@ public String toString() @Override public boolean isNullable() { + // Not relevant return false; } @Override public boolean isSerializable() { - return declaringBean.isSerializable(); + // Not relevant + return false; } @Override @@ -182,14 +155,21 @@ public boolean isProxyable() public T create(CreationalContext creationalContext) { + // Not Relevant return null; } public void invokeDisposeMethod(Object instance, CreationalContext creationalContext) { - // TODO WTF - why isn't this using getReceiver!? Why is it assigning the beanInstance as the beanObject!?! - Object beanInstance = disposalMethodInjectionPoint.isStatic() ? declaringBean : getManager().getReference(declaringBean, declaringBean.getType(), creationalContext); - disposalMethodInjectionPoint.invokeWithSpecialValue(beanInstance, Disposes.class, instance, manager, creationalContext, IllegalArgumentException.class); + Object receiverInstance = getReceiver(creationalContext); + if (receiverInstance == null) + { + disposalMethodInjectionPoint.invokeWithSpecialValue(null, Disposes.class, instance, manager, creationalContext, IllegalArgumentException.class); + } + else + { + disposalMethodInjectionPoint.invokeOnInstanceWithSpecialValue(receiverInstance, Disposes.class, instance, manager, creationalContext, IllegalArgumentException.class); + } } private void checkDisposalMethod() @@ -214,13 +194,13 @@ private void checkDisposalMethod() { throw new DefinitionException("@Produces is not allowed on a disposal method, see " + disposalMethodInjectionPoint.toString()); } - if (declaringBean instanceof EnterpriseBean) + if (getDeclaringBean() instanceof EnterpriseBean) { boolean methodDeclaredOnTypes = false; // TODO use annotated item? - for (Type type : declaringBean.getTypes()) + for (Type type : getDeclaringBean().getTypes()) { - if (type instanceof Class) + if (type instanceof Class) { Class clazz = (Class) type; try @@ -236,118 +216,68 @@ private void checkDisposalMethod() } if (!methodDeclaredOnTypes) { - throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + declaringBean); + throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + getDeclaringBean()); } } } @Override - protected void preSpecialize(BeanDeployerEnvironment environment) + public Class getType() { - if (declaringBean.getAnnotatedItem().getSuperclass().getDeclaredMethod(getAnnotatedItem().getAnnotatedMethod()) == null) - { - throw new DefinitionException("Specialized disposal method does not override a method on the direct superclass"); - } + return type; } @Override - protected void specialize(BeanDeployerEnvironment environment) + protected String getDefaultName() { - WBMethod superClassMethod = declaringBean.getAnnotatedItem().getSuperclass().getMethod(getAnnotatedItem().getAnnotatedMethod()); - if (environment.getProducerMethod(superClassMethod) == null) - { - throw new IllegalStateException(toString() + " does not specialize a bean"); - } - this.specializedBean = environment.getDisposalMethod(superClassMethod); + return disposalMethodInjectionPoint.getPropertyName(); } - @Override - public Class getType() + public void destroy(T instance, CreationalContext creationalContext) { - return type; + // No-op. Producer method dependent objects are destroyed in producer method bean } @Override - protected Class getDefaultDeploymentType() + public String getId() { - return declaringBean.getDeploymentType(); + return id; } - @Override - protected String getDefaultName() + public boolean isPolicy() { - return disposalMethodInjectionPoint.getPropertyName(); + return false; } @Override - protected void initDeploymentType() + public AbstractBean getSpecializedBean() { - Set deploymentTypes = getAnnotatedItem().getMetaAnnotations(DeploymentType.class); - if (deploymentTypes.size() > 1) - { - throw new DefinitionException("At most one deployment type may be specified (" + deploymentTypes + " are specified) on " + getAnnotatedItem().toString()); - } - else if (deploymentTypes.size() == 1) - { - this.deploymentType = deploymentTypes.iterator().next().annotationType(); - log.trace("Deployment type " + deploymentType + " specified by annotation"); - return; - } - - initDeploymentTypeFromStereotype(); - - if (this.deploymentType == null) - { - this.deploymentType = getDefaultDeploymentType(); - log.trace("Using default " + this.deploymentType + " deployment type"); - return; - } + // Doesn't support specialization + return null; } - + @Override protected void initScopeType() { - Set scopeAnnotations = getAnnotatedItem().getMetaAnnotations(ScopeType.class); - if (scopeAnnotations.size() > 1) - { - throw new DefinitionException("At most one scope may be specified"); - } - if (scopeAnnotations.size() == 1) - { - this.scopeType = scopeAnnotations.iterator().next().annotationType(); - log.trace("Scope " + scopeType + " specified by annotation"); - return; - } - - initScopeTypeFromStereotype(); - - if (this.scopeType == null) - { - this.scopeType = Dependent.class; - log.trace("Using default @Dependent scope"); - } + // Disposal methods aren't scoped } @Override - public AbstractBean getSpecializedBean() - { - return specializedBean; - } - - public void destroy(T instance, CreationalContext creationalContext) + public Class getDeploymentType() { - // No-op. Producer method dependent objects are destroyed in producer method bean + return getDeclaringBean().getDeploymentType(); } @Override - public String getId() + protected void initDeploymentType() { - return id; + // Not used } - - public boolean isPolicy() + + @Override + protected void checkDeploymentType() { - return false; + // TODO sort out ordering of init, then we can use initDeploymentType and hence checkDeploymentType } } diff --git a/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java b/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java index f1fe03fab5a..e7ab7368a05 100644 --- a/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java +++ b/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java @@ -126,11 +126,11 @@ else if (getAnnotatedItem().getAnnotatedParameters(Disposes.class).size() > 0) { throw new DefinitionException("Producer method cannot have parameter annotated @Disposes"); } - else if (declaringBean instanceof EnterpriseBean) + else if (getDeclaringBean() instanceof EnterpriseBean) { boolean methodDeclaredOnTypes = false; // TODO use annotated item? - for (Type type : declaringBean.getTypes()) + for (Type type : getDeclaringBean().getTypes()) { if (type instanceof Class) { @@ -148,7 +148,7 @@ else if (declaringBean instanceof EnterpriseBean) } if (!methodDeclaredOnTypes) { - throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + declaringBean); + throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + getDeclaringBean()); } } } @@ -253,7 +253,7 @@ public String toString() @Override protected void preSpecialize(BeanDeployerEnvironment environment) { - if (declaringBean.getAnnotatedItem().getSuperclass().getDeclaredMethod(getAnnotatedItem().getAnnotatedMethod()) == null) + if (getDeclaringBean().getAnnotatedItem().getSuperclass().getDeclaredMethod(getAnnotatedItem().getAnnotatedMethod()) == null) { throw new DefinitionException("Specialized producer method does not override a method on the direct superclass"); } @@ -262,7 +262,7 @@ protected void preSpecialize(BeanDeployerEnvironment environment) @Override protected void specialize(BeanDeployerEnvironment environment) { - WBMethod superClassMethod = declaringBean.getAnnotatedItem().getSuperclass().getMethod(getAnnotatedItem().getAnnotatedMethod()); + WBMethod superClassMethod = getDeclaringBean().getAnnotatedItem().getSuperclass().getMethod(getAnnotatedItem().getAnnotatedMethod()); if (environment.getProducerMethod(superClassMethod) == null) { throw new IllegalStateException(toString() + " does not specialize a bean"); diff --git a/impl/src/main/java/org/jboss/webbeans/bootstrap/AbstractBeanDeployer.java b/impl/src/main/java/org/jboss/webbeans/bootstrap/AbstractBeanDeployer.java index d1f3bb88412..ca4c4c358fe 100644 --- a/impl/src/main/java/org/jboss/webbeans/bootstrap/AbstractBeanDeployer.java +++ b/impl/src/main/java/org/jboss/webbeans/bootstrap/AbstractBeanDeployer.java @@ -24,7 +24,6 @@ import javax.enterprise.inject.Disposes; import javax.enterprise.inject.Initializer; import javax.enterprise.inject.Produces; -import javax.enterprise.inject.spi.AnnotatedMethod; import javax.enterprise.inject.spi.ObserverMethod; import org.jboss.webbeans.BeanManagerImpl; @@ -131,6 +130,7 @@ protected void createDisposalMethods(AbstractClassBean declaringBean, WBClass for (WBMethod method : annotatedClass.getDeclaredMethodsWithAnnotatedParameters(Disposes.class)) { DisposalMethodBean disposalBean = DisposalMethodBean.of(manager, method, declaringBean); + disposalBean.initialize(environment); environment.addDisposalBean(disposalBean); } } diff --git a/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java b/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java index 39640e23251..593ec2dd7b5 100644 --- a/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java +++ b/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java @@ -54,7 +54,7 @@ public class BeanDeployerEnvironment private final Set> resolvedDisposalBeans; private final Set> decorators; private final EjbDescriptorCache ejbDescriptors; - private final TypeSafeResolver disposalMethodResolver; + private final TypeSafeResolver> disposalMethodResolver; private final BeanManagerImpl manager; public BeanDeployerEnvironment(EjbDescriptorCache ejbDescriptors, BeanManagerImpl manager) @@ -68,7 +68,7 @@ public BeanDeployerEnvironment(EjbDescriptorCache ejbDescriptors, BeanManagerImp this.decorators = new HashSet>(); this.observers = new HashSet>(); this.ejbDescriptors = ejbDescriptors; - this.disposalMethodResolver = new TypeSafeBeanResolver(manager, allDisposalBeans); + this.disposalMethodResolver = new TypeSafeBeanResolver>(manager, allDisposalBeans); this.manager = manager; } @@ -190,11 +190,11 @@ public EjbDescriptorCache getEjbDescriptors() public Set> resolveDisposalBeans(WBAnnotated annotatedItem) { // Correct? - Set> beans = disposalMethodResolver.resolve(ResolvableFactory.of(annotatedItem)); + Set> beans = disposalMethodResolver.resolve(ResolvableFactory.of(annotatedItem)); Set> disposalBeans = new HashSet>(); for (Bean bean : beans) { - if (bean instanceof DisposalMethodBean) + if (bean instanceof DisposalMethodBean) { disposalBeans.add((DisposalMethodBean) bean); }