Author: struberg
Date: Mon May 12 21:37:47 2014
New Revision: 1594099
URL: http://svn.apache.org/r1594099
Log:
OWB-955 first version of Alternatives with @Priority
still a lot of work to do...
Added:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/events/discovery/AfterTypeDiscoveryImpl.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithHighPriorityBean.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithPriorityBean.java
- copied, changed from r1593565,
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeBean.java
Removed:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/intercept/annotation/Priority.java
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/third/ThirdpartyBeanImpl.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/EJBWebBeansConfigurator.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AlternativesManager.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/tests/AlternativeBeanResolvingTest.java
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/xml/strict/AlternativesTest.java
openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansEjbPlugin.java
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/AbstractOwbBean.java
Mon May 12 21:37:47 2014
@@ -67,6 +67,11 @@ public abstract class AbstractOwbBean<T>
protected boolean enabled = true;
/**
+ * cached value for {@link #isAlternative()}
+ */
+ private Boolean isAlternative = null;
+
+ /**
* This string will be used for passivating the Bean.
* It will be created on the first use.
* @see #getId()
@@ -304,7 +309,12 @@ public abstract class AbstractOwbBean<T>
@Override
public boolean isAlternative()
{
- return
webBeansContext.getAlternativesManager().isBeanHasAlternative(this);
+ if (isAlternative == null)
+ {
+ isAlternative =
webBeansContext.getAlternativesManager().isAlternative(getBeanClass(),
getStereotypes());
+ }
+
+ return isAlternative;
}
/**
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/third/ThirdpartyBeanImpl.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/third/ThirdpartyBeanImpl.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/third/ThirdpartyBeanImpl.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/third/ThirdpartyBeanImpl.java
Mon May 12 21:37:47 2014
@@ -18,7 +18,6 @@
*/
package org.apache.webbeans.component.third;
-import java.lang.annotation.Annotation;
import java.util.Set;
import javax.enterprise.context.spi.CreationalContext;
@@ -122,22 +121,10 @@ public class ThirdpartyBeanImpl<T> exten
{
AlternativesManager manager =
getWebBeansContext().getAlternativesManager();
//Class alternative
- if(manager.isClassAlternative(getBeanClass()))
+ if (manager.isAlternative(getBeanClass(), bean.getStereotypes()))
{
return true;
}
-
- Set<Class<? extends Annotation>> stereoTypes =
bean.getStereotypes();
- if(stereoTypes != null)
- {
- for(Class<? extends Annotation> stereo : stereoTypes)
- {
- if(manager.isStereoAlternative(stereo))
- {
- return true;
- }
- }
- }
}
return false;
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/BeansDeployer.java
Mon May 12 21:37:47 2014
@@ -46,6 +46,9 @@ import org.apache.webbeans.event.Observe
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.exception.WebBeansDeploymentException;
import org.apache.webbeans.exception.WebBeansException;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.spi.DefinitionException;
import javax.enterprise.inject.spi.DeploymentException;
import
org.apache.webbeans.exception.inject.InconsistentSpecializationException;
@@ -59,6 +62,7 @@ import org.apache.webbeans.portable.even
import org.apache.webbeans.portable.events.ProcessInjectionTargetImpl;
import org.apache.webbeans.portable.events.discovery.AfterBeanDiscoveryImpl;
import
org.apache.webbeans.portable.events.discovery.AfterDeploymentValidationImpl;
+import org.apache.webbeans.portable.events.discovery.AfterTypeDiscoveryImpl;
import org.apache.webbeans.portable.events.discovery.BeforeBeanDiscoveryImpl;
import org.apache.webbeans.portable.events.generics.GProcessManagedBean;
import org.apache.webbeans.spi.BeanArchiveService;
@@ -87,7 +91,6 @@ import javax.enterprise.inject.spi.Decor
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.ObserverMethod;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.net.URL;
@@ -194,12 +197,19 @@ public class BeansDeployer
//Configure Default Beans
configureDefaultBeans();
-
- //Discover classpath classes
- deployFromClassPath(scanner);
-
+
+ List<AnnotatedType<?>> annotatedTypes =
annotatedTypesFromClassPath(scanner);
+
//Deploy additional Annotated Types
- deployAdditionalAnnotatedTypes();
+ addAdditionalAnnotatedTypes(annotatedTypes);
+
+
registerAlternativesDecoratorsAndInterceptorsWithPriority(annotatedTypes);
+
+ fireAfterTypeDiscoveryEvent();
+
+ // create beans from the discovered AnnotatedTypes
+ deployFromAnnotatedTypes(annotatedTypes);
+
//Check Specialization
processSpecializations(scanner);
@@ -248,6 +258,25 @@ public class BeansDeployer
}
}
+ private void
registerAlternativesDecoratorsAndInterceptorsWithPriority(List<AnnotatedType<?>>
annotatedTypes)
+ {
+ AlternativesManager alternativesManager =
webBeansContext.getAlternativesManager();
+
+ for (AnnotatedType<?> annotatedType : annotatedTypes)
+ {
+ if (annotatedType.getAnnotation(Alternative.class) != null)
+ {
+ Priority priority =
annotatedType.getAnnotation(Priority.class);
+ if (priority != null)
+ {
+
alternativesManager.addPriorityClazzAlternative(annotatedType.getJavaClass(),
priority);
+ }
+ }
+
+ //X TODO handle interceptors and decorators as well
+ }
+ }
+
/**
* Configure Default Beans.
*/
@@ -372,10 +401,27 @@ public class BeansDeployer
manager.fireLifecycleEvent(new
AfterBeanDiscoveryImpl(webBeansContext));
webBeansContext.getWebBeansUtil().inspectErrorStack(
- "There are errors that are added by AfterBeanDiscovery event
observers. Look at logs for further details");
+ "There are errors that are added by AfterBeanDiscovery event
observers. Look at logs for further details");
}
/**
+ * Fires event after bean discovery.
+ */
+ private void fireAfterTypeDiscoveryEvent()
+ {
+ AlternativesManager alternativesManager =
webBeansContext.getAlternativesManager();
+ List<Class<?>> sortedAlternatives =
alternativesManager.getSortedAlternatives();
+
+ BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
+ manager.fireLifecycleEvent(new AfterTypeDiscoveryImpl(webBeansContext,
sortedAlternatives));
+ // we do not need to set back the sortedAlternatives to the
AlternativesManager as the API
+ // and all layers in between use a mutable List. Not very elegant but
spec conform.
+
+ webBeansContext.getWebBeansUtil().inspectErrorStack(
+ "There are errors that are added by AfterTypeDiscovery event
observers. Look at logs for further details");
+ }
+
+ /**
* Fires event after deployment valdiation.
*/
private void fireAfterDeploymentValidationEvent()
@@ -566,121 +612,152 @@ public class BeansDeployer
}
}
}
-
-
-
+
/**
- * Discovers and deploys classes from class path.
- *
- * @param scanner discovery scanner
- * @throws ClassNotFoundException if class not found
+ * Create AnnotatedTypes from the ClassPath via the ScannerService
*/
- protected void deployFromClassPath(ScannerService scanner) throws
ClassNotFoundException
+ private List<AnnotatedType<?>> annotatedTypesFromClassPath(ScannerService
scanner)
{
- logger.fine("Deploying configurations from class files has started.");
+ logger.fine("Creating AnnotatedTypes from class files has started.");
// Start from the class
Set<Class<?>> classIndex = scanner.getBeanClasses();
-
+
+ List<AnnotatedType<?>> annotatedTypes = new
ArrayList<AnnotatedType<?>>();
+
//Iterating over each class
if (classIndex != null)
{
AnnotatedElementFactory annotatedElementFactory =
webBeansContext.getAnnotatedElementFactory();
- for(Class<?> implClass : classIndex)
+ for (Class<?> implClass : classIndex)
{
- //Define annotation type
- AnnotatedType<?> annotatedType =
annotatedElementFactory.newAnnotatedType(implClass);
-
- if (null != annotatedType)
+ try
{
- try
- {
- deploySingleAnnotatedType(implClass, annotatedType);
- }
- catch (NoClassDefFoundError ncdfe)
+ //Define annotation type
+ AnnotatedType<?> annotatedType =
annotatedElementFactory.newAnnotatedType(implClass);
+
+ if (annotatedType == null)
{
- logger.info("Skipping deployment of Class " +
implClass + "due to a NoClassDefFoundError: " + ncdfe.getMessage());
+ logger.info("Could not create AnnotatedType for class
" + implClass);
+ continue;
}
- // if the implClass already gets processed as part of the
- // standard BDA scanning, then we don't need to
'additionally'
- // deploy it anymore.
-
webBeansContext.getBeanManagerImpl().removeAdditionalAnnotatedType(annotatedType);
- }
- else
- {
- if (logger.isLoggable(Level.FINE))
+ // Fires ProcessAnnotatedType
+ ProcessAnnotatedTypeImpl<?> processAnnotatedEvent =
+
webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType);
+
+ // if veto() is called
+ if (!processAnnotatedEvent.isVeto())
{
- logger.fine("Error creating managed bean " +
implClass);
+
annotatedTypes.add(processAnnotatedEvent.getAnnotatedType());
}
-
}
-
+ catch (NoClassDefFoundError ncdfe)
+ {
+ logger.info("Skipping deployment of Class " + implClass +
"due to a NoClassDefFoundError: " + ncdfe.getMessage());
+ }
}
}
- logger.fine("Deploying configurations from class files has ended.");
-
+ return annotatedTypes;
}
-
+
/**
- * Deploys any AnnotatedTypes added to the BeanManager during
beforeBeanDiscovery.
+ * Process any AnnotatedTypes which got added by
BeforeBeanDiscovery#addAnnotatedType
+ * @param annotatedTypes
*/
- private void deployAdditionalAnnotatedTypes()
+ private void addAdditionalAnnotatedTypes(List<AnnotatedType<?>>
annotatedTypes)
{
BeanManagerImpl beanManager = webBeansContext.getBeanManagerImpl();
- Collection<AnnotatedType<?>> annotatedTypes =
beanManager.getAdditionalAnnotatedTypes();
-
- for(AnnotatedType<?> type : annotatedTypes)
+
+ Collection<AnnotatedType<?>> additionalAnnotatedTypes =
beanManager.getAdditionalAnnotatedTypes();
+
+ for (AnnotatedType<?> annotatedType : additionalAnnotatedTypes)
{
- Class implClass = type.getJavaClass();
+ // Fires ProcessAnnotatedType
+ ProcessAnnotatedTypeImpl<?> processAnnotatedEvent =
+
webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType);
+
+ if (!processAnnotatedEvent.isVeto())
+ {
+ AnnotatedType<?> changedAnnotatedType =
processAnnotatedEvent.getAnnotatedType();
+ if (annotatedTypes.contains(changedAnnotatedType))
+ {
+ annotatedTypes.remove(changedAnnotatedType);
+ }
+ annotatedTypes.add(changedAnnotatedType);
+ }
- deploySingleAnnotatedType(implClass, type);
}
}
+
/**
- * Common helper method used to deploy annotated types discovered through
- * scanning or during beforeBeanDiscovery.
+ * Discovers and deploys classes from class path.
*
- * @param implClass the class of the bean to be deployed
- * @param annotatedType the AnnotatedType representing the bean to be
deployed
+ * @param annotatedTypes the AnnotatedTypes which got discovered so far
and are not vetoed
+ * @throws ClassNotFoundException if class not found
*/
- private void deploySingleAnnotatedType(Class implClass, AnnotatedType
annotatedType)
+ protected void deployFromAnnotatedTypes(List<AnnotatedType<?>>
annotatedTypes) throws ClassNotFoundException
{
- // Fires ProcessAnnotatedType
- ProcessAnnotatedTypeImpl<?> processAnnotatedEvent =
-
webBeansContext.getWebBeansUtil().fireProcessAnnotatedTypeEvent(annotatedType);
+ logger.fine("Deploying configurations from class files has started.");
- // if veto() is called
- if (processAnnotatedEvent.isVeto())
+ // Start from the class
+ for(AnnotatedType<?> annotatedType : annotatedTypes)
{
- return;
+ try
+ {
+ deploySingleAnnotatedType(annotatedType);
+ }
+ catch (NoClassDefFoundError ncdfe)
+ {
+ logger.info("Skipping deployment of Class " +
annotatedType.getJavaClass() + "due to a NoClassDefFoundError: " +
ncdfe.getMessage());
+ }
+
+ // if the implClass already gets processed as part of the
+ // standard BDA scanning, then we don't need to 'additionally'
+ // deploy it anymore.
+
webBeansContext.getBeanManagerImpl().removeAdditionalAnnotatedType(annotatedType);
+
}
- Class beanClass =
processAnnotatedEvent.getAnnotatedType().getJavaClass();
+ logger.fine("Deploying configurations from class files has ended.");
+
+ }
+
+
+ /**
+ * Common helper method used to deploy annotated types discovered through
+ * scanning or during beforeBeanDiscovery.
+ *
+ * @param annotatedType the AnnotatedType representing the bean to be
deployed
+ */
+ private void deploySingleAnnotatedType(AnnotatedType annotatedType)
+ {
+
+ Class beanClass = annotatedType.getJavaClass();
// EJBs can be defined so test them really before going for a
ManagedBean
- if (discoverEjb && EJBWebBeansConfigurator.isSessionBean(implClass,
webBeansContext))
+ if (discoverEjb && EJBWebBeansConfigurator.isSessionBean(beanClass,
webBeansContext))
{
- logger.log(Level.FINE, "Found Enterprise Bean with class name :
[{0}]", implClass.getName());
- defineEnterpriseWebBean((Class<Object>) implClass,
(ProcessAnnotatedTypeImpl<Object>) processAnnotatedEvent);
+ logger.log(Level.FINE, "Found Enterprise Bean with class name :
[{0}]", beanClass.getName());
+ defineEnterpriseWebBean((Class<Object>) beanClass, annotatedType);
}
else
{
try
{
- if((ClassUtil.isConcrete(beanClass) ||
WebBeansUtil.isDecorator(processAnnotatedEvent.getAnnotatedType()))
- &&
isValidManagedBean(processAnnotatedEvent.getAnnotatedType()))
+ if((ClassUtil.isConcrete(beanClass) ||
WebBeansUtil.isDecorator(annotatedType))
+ && isValidManagedBean(annotatedType))
{
- defineManagedBean(processAnnotatedEvent);
+ defineManagedBean(annotatedType);
}
}
catch (NoClassDefFoundError ncdfe)
{
- logger.info("Skipping deployment of Class " + implClass + "due
to a NoClassDefFoundError: " + ncdfe.getMessage());
+ logger.info("Skipping deployment of Class " + beanClass + "due
to a NoClassDefFoundError: " + ncdfe.getMessage());
}
}
}
@@ -791,11 +868,11 @@ public class BeansDeployer
AlternativesManager manager =
WebBeansContext.getInstance().getAlternativesManager();
if (isStereotype)
{
- manager.addStereoTypeAlternative(clazz,
bdaLocation.toExternalForm(), scannerService);
+ manager.addXmlStereoTypeAlternative(clazz);
}
else
{
- manager.addClazzAlternative(clazz,
bdaLocation.toExternalForm(), scannerService);
+ manager.addXmlClazzAlternative(clazz);
}
}
}
@@ -1057,18 +1134,12 @@ public class BeansDeployer
* Defines and configures managed bean.
* @param <T> type info
*/
- protected <T> void defineManagedBean(ProcessAnnotatedTypeImpl<T>
processAnnotatedEvent)
+ protected <T> void defineManagedBean(AnnotatedType<T> annotatedType)
{
- //Bean manager
- BeanManagerImpl manager = webBeansContext.getBeanManagerImpl();
-
- //Create an annotated type
- AnnotatedType<T> annotatedType =
processAnnotatedEvent.getAnnotatedType();
-
//Fires ProcessInjectionTarget event for Java EE components instances
//That supports injections but not managed beans
ProcessInjectionTargetImpl<T> processInjectionTargetEvent;
- Class beanClass =
processAnnotatedEvent.getAnnotatedType().getJavaClass();
+ Class beanClass = annotatedType.getJavaClass();
if(webBeansContext.getWebBeansUtil().supportsJavaEeComponentInjections(beanClass))
{
//Fires ProcessInjectionTarget
@@ -1222,9 +1293,9 @@ public class BeansDeployer
* @param <T> bean class type
* @param clazz bean class
*/
- protected <T> void defineEnterpriseWebBean(Class<T> clazz,
ProcessAnnotatedType<T> processAnnotatedTypeEvent)
+ protected <T> void defineEnterpriseWebBean(Class<T> clazz,
AnnotatedType<T> annotatedType)
{
- InjectionTargetBean<T> bean = (InjectionTargetBean<T>)
EJBWebBeansConfigurator.defineEjbBean(clazz, processAnnotatedTypeEvent,
+ InjectionTargetBean<T> bean = (InjectionTargetBean<T>)
EJBWebBeansConfigurator.defineEjbBean(clazz, annotatedType,
webBeansContext);
webBeansContext.getWebBeansUtil().setInjectionTargetBeanEnableFlag(bean);
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/EJBWebBeansConfigurator.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/EJBWebBeansConfigurator.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/EJBWebBeansConfigurator.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/config/EJBWebBeansConfigurator.java
Mon May 12 21:37:47 2014
@@ -18,8 +18,8 @@
*/
package org.apache.webbeans.config;
+import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
import org.apache.webbeans.exception.WebBeansConfigurationException;
import org.apache.webbeans.plugins.PluginLoader;
@@ -60,7 +60,7 @@ public final class EJBWebBeansConfigurat
* @param clazz bean class
* @return ejb bean
*/
- public static <T> Bean<T> defineEjbBean(Class<T> clazz,
ProcessAnnotatedType<T> processAnnotatedTypeEvent,
+ public static <T> Bean<T> defineEjbBean(Class<T> clazz, AnnotatedType<T>
annotatedType,
WebBeansContext webBeansContext)
{
PluginLoader loader = webBeansContext.getPluginLoader();
@@ -71,7 +71,7 @@ public final class EJBWebBeansConfigurat
throw new IllegalStateException("There is no provided EJB plugin.
Unable to define session bean for class : " + clazz.getName());
}
- return ejbPlugin.defineSessionBean(clazz, processAnnotatedTypeEvent);
+ return ejbPlugin.defineSessionBean(clazz, annotatedType);
}
}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/container/InjectionResolver.java
Mon May 12 21:37:47 2014
@@ -69,7 +69,6 @@ import static org.apache.webbeans.util.I
* </p>
*
* @version $Rev$ $Date$
- * @see org.apache.webbeans.config.WebBeansFinder
*/
public class InjectionResolver
{
@@ -684,6 +683,16 @@ public class InjectionResolver
public <X> Bean<? extends X> resolve(Set<Bean<? extends X>> beans)
{
+ if (beans == null)
+ {
+ return null;
+ }
+
+ if (beans.size() == 1)
+ {
+ return beans.iterator().next();
+ }
+
Set set = resolveAll(beans);
if (set.isEmpty())
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AlternativesManager.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AlternativesManager.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AlternativesManager.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/inject/AlternativesManager.java
Mon May 12 21:37:47 2014
@@ -19,33 +19,76 @@
package org.apache.webbeans.inject;
import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.spi.Bean;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.exception.WebBeansConfigurationException;
-import org.apache.webbeans.spi.ScannerService;
import org.apache.webbeans.util.AnnotationUtil;
+/**
+ * This class has 2 responsibilities.
+ *
+ * 1.) to collect information about configured @Alternatives at boot time
+ *
+ * 2.) answer if a class is an enabled Alternative.
+ * This is needed for {@link
org.apache.webbeans.container.BeanManagerImpl#resolve(java.util.Set)}
+ *
+ * The boot order for 1.) is to first register all the alternatives and
stereotypes
+ * from the XML.
+ * After that the AnnotatedType scanning is performed and all
@Alternatives with
+ * @Priority get added as well. We will also add classes which have an
Alternative stereotype.
+ *
+ * After the AnnotatedTypes got scanned we have to fire the {@link
javax.enterprise.inject.spi.AfterTypeDiscovery}
+ * event with the collected <i>effective</i> alternative classes sorted by
their priority.
+ * Any extension can re-order the alternatives which then form the base of the
resolve() handling
+ * at runtime.
+ */
public class AlternativesManager
{
- private final Set<Class<?>> alternatives = new HashSet<Class<?>>();
-
- private final Set<Class<? extends Annotation>> stereoAlternatives = new
HashSet<Class<? extends Annotation>>();
private final WebBeansContext webBeansContext;
+ /**
+ * All the stereotypes which are configured via XML <class>
+ */
+ private final Set<Class<?>> configuredAlternatives = new
HashSet<Class<?>>();
+
+ /**
+ * All Stereotypes which are declared as @Alternative in a beans.xml.
+ * Please note that @Priority on a stereotype does <b>not</b>
automatically enable it!
+ */
+ private final Set<Class<? extends Annotation>>
configuredStereotypeAlternatives = new HashSet<Class<? extends Annotation>>();
+
+ /**
+ * All the stereotypes which are either configured via XML <class> or
+ * have a @Priority annotation.
+ * key: the class
+ * value: the priority. Alternatives from beans.xml have -1 as they are
lowest prio.
+ */
+ private final List<PriorityAlternative> priorityAlternatives = new
ArrayList<PriorityAlternative>();
+
+ private List<Class<?>> sortedAlternatives = null;
+
+
+
public AlternativesManager(WebBeansContext webBeansContext)
{
-
this.webBeansContext = webBeansContext;
}
- @SuppressWarnings("unchecked")
- public void addStereoTypeAlternative(Class<?> alternative, String
fileName, ScannerService scanner)
+ /**
+ * This methods gets called while scanning the various beans.xml files.
+ * It registers a <stereotype> alternative.
+ */
+ public void addXmlStereoTypeAlternative(Class<?> alternative)
{
if(Annotation.class.isAssignableFrom(alternative))
{
@@ -55,15 +98,9 @@ public class AlternativesManager
{
if(AnnotationUtil.hasClassAnnotation(stereo,
Alternative.class))
{
- boolean isBDAScanningEnabled=(scanner!=null &&
scanner.isBDABeansXmlScanningEnabled());
- if(isBDAScanningEnabled &&
!scanner.getBDABeansXmlScanner().addStereoType(stereo, fileName))
- {
- throw new WebBeansConfigurationException("Given
alternative class : " + alternative.getName() + " is already added as
@Alternative" );
- }
-
ok = true;
- stereoAlternatives.add(stereo);
+ configuredStereotypeAlternatives.add(stereo);
}
}
@@ -77,61 +114,126 @@ public class AlternativesManager
throw new WebBeansConfigurationException("Given stereotype class :
" + alternative.getName() + " is not an annotation" );
}
}
-
- public void addClazzAlternative(Class<?> alternative, String fileName,
ScannerService scanner)
+
+ /**
+ * This methods gets called while scanning the various beans.xml files.
+ * It registers a <class> alternative.
+ */
+ public void addXmlClazzAlternative(Class<?> alternative)
{
if(AnnotationUtil.hasClassAnnotation(alternative, Alternative.class))
{
- boolean isBDAScanningEnabled=(scanner!=null &&
scanner.isBDABeansXmlScanningEnabled());
- if((isBDAScanningEnabled &&
!scanner.getBDABeansXmlScanner().addAlternative(alternative, fileName)))
- {
- throw new WebBeansConfigurationException("Given class : " +
alternative.getName() + " is already added as @Alternative" );
- }
-
- alternatives.add(alternative);
+ configuredAlternatives.add(alternative);
}
else
{
throw new WebBeansConfigurationException("Given class : " +
alternative.getName() + " is not annotated with @Alternative" );
}
}
-
- public boolean isClassAlternative(Class<?> clazz)
+
+ /**
+ * This method is used to add Alternatives which have a @Priority
annotation.
+ * This is performed after the ProcessAnnotatedType events got fired.
+ */
+ public void addPriorityClazzAlternative(Class<?> clazz, Priority priority)
{
- return alternatives.contains(clazz);
+ priorityAlternatives.add(new PriorityAlternative(clazz,
priority.value()));
}
- public boolean isStereoAlternative(Class<? extends Annotation> stereo)
+ /**
+ * Alternatives get ordered by their priority and as lowest priority all
+ * the alternatives added via XML get added.
+ * @return the list of sorted alternatives
+ */
+ public List<Class<?>> getSortedAlternatives()
{
- return stereoAlternatives.contains(stereo);
+ if (sortedAlternatives == null)
+ {
+ Collections.sort(priorityAlternatives);
+
+ sortedAlternatives = new
ArrayList<Class<?>>(priorityAlternatives.size());
+
+ for (PriorityAlternative priorityAlternative :
priorityAlternatives)
+ {
+ // add in reverse order
+ sortedAlternatives.add(0, priorityAlternative.clazz);
+ }
+ }
+
+ return sortedAlternatives;
}
- public boolean isBeanHasAlternative(Bean<?> bean)
+
+ /**
+ * @deprecated this is not enough since CDI-1.1. We now need to handle a
weighted list of enabled alternatives
+ */
+ public boolean isClassAlternative(Class<?> clazz)
+ {
+ return configuredAlternatives.contains(clazz);
+ }
+
+
+ /**
+ * @return <code>true</code> if the given bean is a configured alternative
+ * @deprecated this is not enough since CDI-1.1. We now need to handle a
weighted list of enabled alternatives
+ */
+ public boolean isAlternative(Bean<?> bean)
{
return isAlternative(bean.getBeanClass(), bean.getStereotypes());
}
+ /**
+ * @return <code>true</code> if the given bean is a configured alternative
+ */
public boolean isAlternative(Class<?> beanType, Set<Class<? extends
Annotation>> stereotypes)
{
- if(alternatives.contains(beanType))
+ if(configuredAlternatives.contains(beanType) ||
+ sortedAlternatives.contains(beanType))
{
return true;
}
for(Class<? extends Annotation> ann : stereotypes)
{
- if(stereoAlternatives.contains(ann))
+ if(configuredStereotypeAlternatives.contains(ann))
{
return true;
}
}
-
+
+
return false;
}
public void clear()
{
- alternatives.clear();
- stereoAlternatives.clear();
+ configuredAlternatives.clear();
+ configuredStereotypeAlternatives.clear();
+ priorityAlternatives.clear();
+
+ sortedAlternatives = null;
+ }
+
+ private static class PriorityAlternative implements
Comparable<PriorityAlternative>
+ {
+ private final int priority;
+ private final Class<?> clazz;
+
+ public PriorityAlternative(Class<?> clazz, int priority)
+ {
+ this.clazz = clazz;
+ this.priority = priority;
+ }
+
+ @Override
+ public int compareTo(PriorityAlternative o)
+ {
+ if (priority != o.priority)
+ {
+ return Integer.compare(priority, o.priority);
+ }
+
+ return clazz.getName().compareTo(o.clazz.getName());
+ }
}
}
Added:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/events/discovery/AfterTypeDiscoveryImpl.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/events/discovery/AfterTypeDiscoveryImpl.java?rev=1594099&view=auto
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/events/discovery/AfterTypeDiscoveryImpl.java
(added)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/events/discovery/AfterTypeDiscoveryImpl.java
Mon May 12 21:37:47 2014
@@ -0,0 +1,65 @@
+/*
+ * 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.portable.events.discovery;
+
+import javax.enterprise.inject.spi.AfterTypeDiscovery;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.util.List;
+
+import org.apache.webbeans.config.WebBeansContext;
+
+/**
+ * OWB fires this event after all AnnotatedTypes from scanned classes
+ * got picked up.
+ */
+public class AfterTypeDiscoveryImpl implements AfterTypeDiscovery
+{
+ private final WebBeansContext webBeansContext;
+ private final List<Class<?>> sortedAlternatives;
+
+ public AfterTypeDiscoveryImpl(WebBeansContext webBeansContext,
List<Class<?>> sortedAlternatives)
+ {
+ this.webBeansContext = webBeansContext;
+ this.sortedAlternatives = sortedAlternatives;
+ }
+
+ @Override
+ public List<Class<?>> getAlternatives()
+ {
+ return sortedAlternatives;
+ }
+
+ @Override
+ public List<Class<?>> getInterceptors()
+ {
+ return null; //X TODO
+ }
+
+ @Override
+ public List<Class<?>> getDecorators()
+ {
+ return null; //X TODO
+ }
+
+ @Override
+ public void addAnnotatedType(AnnotatedType<?> type, String id)
+ {
+ webBeansContext.getBeanManagerImpl().addAdditionalAnnotatedType(type,
id);
+ }
+}
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
Mon May 12 21:37:47 2014
@@ -661,6 +661,8 @@ public final class WebBeansUtil
* @throws DefinitionException if name is defined
* @throws InconsistentSpecializationException related with priority
* @throws WebBeansConfigurationException any other exception
+ *
+ * TODO: this method needs to get changed to use AnnotatedTypes
*/
protected void configureSpecializations(Class<?> specializedClass,
List<Class<?>> beanClasses)
{
@@ -857,7 +859,7 @@ public final class WebBeansUtil
//disable superbean if the current bean is not an alternative
superBean.setEnabled(false);
}
- else if(altManager.isClassAlternative(bean.getBeanClass()))
+ else if(altManager.isAlternative(bean))
{
//disable superbean if the current bean is an enabled
alternative
superBean.setEnabled(false);
@@ -1422,7 +1424,7 @@ public final class WebBeansUtil
if (alternative)
{
return hasInjectionTargetBeanAnnotatedWithAlternative(parent) &&
-
webBeansContext.getAlternativesManager().isBeanHasAlternative(parent);
+
webBeansContext.getAlternativesManager().isAlternative(parent);
}
else
{
Added:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithHighPriorityBean.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithHighPriorityBean.java?rev=1594099&view=auto
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithHighPriorityBean.java
(added)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithHighPriorityBean.java
Mon May 12 21:37:47 2014
@@ -0,0 +1,34 @@
+/*
+ * 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.test.concepts.alternatives.common;
+
+import javax.annotation.Priority;
+import javax.enterprise.inject.Alternative;
+
+@Alternative
+@Priority(100)
+public class AlternativeWithHighPriorityBean implements SimpleInterface
+{
+
+ @Override
+ public Class<?> getImplementationType()
+ {
+ return AlternativeWithHighPriorityBean.class;
+ }
+}
Copied:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithPriorityBean.java
(from r1593565,
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeBean.java)
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithPriorityBean.java?p2=openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithPriorityBean.java&p1=openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeBean.java&r1=1593565&r2=1594099&rev=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeBean.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/common/AlternativeWithPriorityBean.java
Mon May 12 21:37:47 2014
@@ -18,15 +18,17 @@
*/
package org.apache.webbeans.test.concepts.alternatives.common;
+import javax.annotation.Priority;
import javax.enterprise.inject.Alternative;
@Alternative
-public class AlternativeBean implements SimpleInterface
+@Priority(5)
+public class AlternativeWithPriorityBean implements SimpleInterface
{
@Override
public Class<?> getImplementationType()
{
- return AlternativeBean.class;
+ return AlternativeWithPriorityBean.class;
}
}
Modified:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/tests/AlternativeBeanResolvingTest.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/tests/AlternativeBeanResolvingTest.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/tests/AlternativeBeanResolvingTest.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/concepts/alternatives/tests/AlternativeBeanResolvingTest.java
Mon May 12 21:37:47 2014
@@ -29,10 +29,13 @@ import org.apache.webbeans.test.Abstract
import org.apache.webbeans.test.concepts.alternatives.common.AlternativeBean;
import
org.apache.webbeans.test.concepts.alternatives.common.AlternativeOnClassAndProducerMethodBean;
import
org.apache.webbeans.test.concepts.alternatives.common.AlternativeOnClassOnlyBean;
+import
org.apache.webbeans.test.concepts.alternatives.common.AlternativeWithPriorityBean;
import
org.apache.webbeans.test.concepts.alternatives.common.DefaultBeanProducerWithoutDisposes;
import org.apache.webbeans.test.concepts.alternatives.common.Pen;
import org.apache.webbeans.test.concepts.alternatives.common.Pencil;
import
org.apache.webbeans.test.concepts.alternatives.common.PencilProducerBean;
+import org.apache.webbeans.test.concepts.alternatives.common.SimpleBean;
+import org.apache.webbeans.test.concepts.alternatives.common.SimpleInterface;
import org.apache.webbeans.test.concepts.alternatives.common.YetAnotherPencil;
import org.junit.Test;
import org.junit.Assert;
@@ -113,4 +116,18 @@ public class AlternativeBeanResolvingTes
}
+ /**
+ * Test alternatives which are NOT in any beans.xml but activated
+ * by having a Priority annotation.
+ */
+ @Test
+ public void testPriorityAlternative() throws Exception
+ {
+ startContainer(AlternativeWithPriorityBean.class, SimpleBean.class);
+
+ SimpleInterface simpleInterface = getInstance(SimpleInterface.class);
+ Assert.assertNotNull(simpleInterface);
+ Assert.assertEquals(AlternativeWithPriorityBean.class,
simpleInterface.getImplementationType());
+ }
+
}
Modified:
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/xml/strict/AlternativesTest.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/xml/strict/AlternativesTest.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/xml/strict/AlternativesTest.java
(original)
+++
openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/unittests/xml/strict/AlternativesTest.java
Mon May 12 21:37:47 2014
@@ -44,8 +44,8 @@ public class AlternativesTest extends Ab
AlternativesManager manager =
WebBeansContext.getInstance().getAlternativesManager();
- Assert.assertTrue(manager.isBeanHasAlternative(alternative1));
- Assert.assertTrue(manager.isBeanHasAlternative(alternative2));
+ Assert.assertTrue(manager.isAlternative(alternative1));
+ Assert.assertTrue(manager.isAlternative(alternative2));
manager.clear();
Modified:
openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansEjbPlugin.java
URL:
http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansEjbPlugin.java?rev=1594099&r1=1594098&r2=1594099&view=diff
==============================================================================
---
openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansEjbPlugin.java
(original)
+++
openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansEjbPlugin.java
Mon May 12 21:37:47 2014
@@ -19,8 +19,8 @@
package org.apache.webbeans.spi.plugins;
import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
import java.lang.reflect.Method;
/**
@@ -50,9 +50,9 @@ public interface OpenWebBeansEjbPlugin e
* Configures session bean and adds it into the container.
*
* @param clazz session bean class
- * @param processAnnotateTypeEvent process annotated type event
+ * @param annotatedType processed annotated type
*/
- public <T> Bean<T> defineSessionBean(Class<T> clazz,
ProcessAnnotatedType<T> processAnnotateTypeEvent);
+ public <T> Bean<T> defineSessionBean(Class<T> clazz, AnnotatedType<T>
annotatedType);
public <T> Bean<T> defineNewSessionBean(Class<T> clazz);
@@ -84,7 +84,7 @@ public interface OpenWebBeansEjbPlugin e
* Returns session bean proxy.
*
* @param bean session bean
- * @param proxy interface
+ * @param iface interface
* @return session bean proxy
*/
public Object getSessionBeanProxy(Bean<?> bean, Class<?> iface,
CreationalContext<?> creationalContext);