org.jboss.weld.bootstrap.events.AfterBeanDiscoveryImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weld-servlet-shaded Show documentation
Show all versions of weld-servlet-shaded Show documentation
This jar bundles all the bits of Weld and CDI required for running in a Servlet container.
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat, Inc., 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.weld.bootstrap.events;
import static org.jboss.weld.util.Observers.validateObserverMethod;
import static org.jboss.weld.util.reflection.Reflections.cast;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.Context;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.DefinitionException;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.ObserverMethod;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.enterprise.inject.spi.Prioritized;
import javax.enterprise.inject.spi.configurator.BeanConfigurator;
import javax.enterprise.inject.spi.configurator.ObserverMethodConfigurator;
import org.jboss.weld.annotated.slim.SlimAnnotatedTypeStore;
import org.jboss.weld.bean.CustomDecoratorWrapper;
import org.jboss.weld.bean.WeldBean;
import org.jboss.weld.bean.attributes.ExternalBeanAttributesFactory;
import org.jboss.weld.bootstrap.BeanDeploymentArchiveMapping;
import org.jboss.weld.bootstrap.BeanDeploymentFinder;
import org.jboss.weld.bootstrap.ContextHolder;
import org.jboss.weld.bootstrap.enablement.GlobalEnablementBuilder;
import org.jboss.weld.bootstrap.event.InterceptorConfigurator;
import org.jboss.weld.bootstrap.event.WeldAfterBeanDiscovery;
import org.jboss.weld.bootstrap.event.WeldBeanConfigurator;
import org.jboss.weld.bootstrap.events.configurator.BeanConfiguratorImpl;
import org.jboss.weld.bootstrap.events.configurator.ObserverMethodConfiguratorImpl;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.logging.BootstrapLogger;
import org.jboss.weld.logging.ContextLogger;
import org.jboss.weld.logging.InterceptorLogger;
import org.jboss.weld.logging.MetadataLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.Bindings;
import org.jboss.weld.util.Observers;
import org.jboss.weld.util.Preconditions;
public class AfterBeanDiscoveryImpl extends AbstractBeanDiscoveryEvent implements WeldAfterBeanDiscovery {
private static final String TYPE_ARGUMENT_NAME = "type";
public static void fire(BeanManagerImpl beanManager, Deployment deployment, BeanDeploymentArchiveMapping bdaMapping,
Collection> contexts) {
final AfterBeanDiscoveryImpl event = new AfterBeanDiscoveryImpl(beanManager, deployment, bdaMapping, contexts);
event.fire();
event.finish();
}
private AfterBeanDiscoveryImpl(BeanManagerImpl beanManager, Deployment deployment, BeanDeploymentArchiveMapping bdaMapping,
Collection> contexts) {
super(beanManager, WeldAfterBeanDiscovery.class, bdaMapping, deployment, contexts);
this.slimAnnotatedTypeStore = beanManager.getServices().get(SlimAnnotatedTypeStore.class);
this.containerLifecycleEvents = beanManager.getServices().get(ContainerLifecycleEvents.class);
this.additionalBeans = new LinkedList<>();
this.additionalObservers = new LinkedList<>();
}
private final SlimAnnotatedTypeStore slimAnnotatedTypeStore;
private final ContainerLifecycleEvents containerLifecycleEvents;
private final List additionalBeans;
private final List additionalObservers;
@Override
public void addBean(Bean> bean) {
checkWithinObserverNotification();
Preconditions.checkArgumentNotNull(bean, "bean");
ExternalBeanAttributesFactory.validateBeanAttributes(bean, getBeanManager());
validateBean(bean);
additionalBeans.add(BeanRegistration.of(bean, getReceiver()));
BootstrapLogger.LOG.addBeanCalled(getReceiver(), bean);
}
@Override
public WeldBeanConfigurator addBean() {
checkWithinObserverNotification();
BeanConfiguratorImpl configurator = new BeanConfiguratorImpl<>(getReceiver().getClass(), getBeanDeploymentFinder());
additionalBeans.add(BeanRegistration.of(configurator, getReceiver()));
return configurator;
}
@Override
public void addContext(Context context) {
checkWithinObserverNotification();
Preconditions.checkArgumentNotNull(context, "context");
Class extends Annotation> scope = context.getScope();
if (scope == null) {
throw ContextLogger.LOG.contextHasNullScope(context);
}
if (!getBeanManager().isScope(scope)) {
MetadataLogger.LOG.contextGetScopeIsNotAScope(scope, context);
}
if (scope == ApplicationScoped.class || scope == Dependent.class) {
throw ContextLogger.LOG.cannotRegisterContext(scope, context);
}
getBeanManager().addContext(context);
BootstrapLogger.LOG.addContext(getReceiver(), context);
}
@Override
public void addObserverMethod(ObserverMethod> observerMethod) {
checkWithinObserverNotification();
Preconditions.checkArgumentNotNull(observerMethod, "observerMethod");
validateObserverMethod(observerMethod, getBeanManager(), null);
additionalObservers.add(ObserverRegistration.of(observerMethod, getReceiver()));
BootstrapLogger.LOG.addObserverMethodCalled(getReceiver(), observerMethod);
}
@Override
public ObserverMethodConfigurator addObserverMethod() {
checkWithinObserverNotification();
ObserverMethodConfiguratorImpl configurator = new ObserverMethodConfiguratorImpl<>(getReceiver());
additionalObservers.add(ObserverRegistration.of(configurator, getReceiver()));
return configurator;
}
@Override
public AnnotatedType getAnnotatedType(Class type, String id) {
checkWithinObserverNotification();
Preconditions.checkArgumentNotNull(type, TYPE_ARGUMENT_NAME);
return slimAnnotatedTypeStore.get(type, id);
}
@Override
public Iterable> getAnnotatedTypes(Class type) {
checkWithinObserverNotification();
Preconditions.checkArgumentNotNull(type, TYPE_ARGUMENT_NAME);
return cast(slimAnnotatedTypeStore.get(type));
}
@Override
public InterceptorConfigurator addInterceptor() {
InterceptorConfiguratorImpl configurator = new InterceptorConfiguratorImpl(getBeanManager());
additionalBeans.add(BeanRegistration.of(configurator));
return configurator;
}
/**
* Bean and observer registration is delayed until after all {@link AfterBeanDiscovery} observers are notified.
*/
private void finish() {
try {
GlobalEnablementBuilder globalEnablementBuilder = getBeanManager().getServices().get(GlobalEnablementBuilder.class);
for (BeanRegistration registration : additionalBeans) {
processBeanRegistration(registration, globalEnablementBuilder);
}
for (ObserverRegistration registration : additionalObservers) {
processObserverRegistration(registration);
}
} catch (Exception e) {
throw new DefinitionException(e);
}
}
private void processBeanRegistration(BeanRegistration registration, GlobalEnablementBuilder globalEnablementBuilder) {
Bean> bean = registration.initBean();
BeanManagerImpl beanManager = registration.initBeanManager();
if (beanManager == null) {
// Get the bean manager for beans added via ABD#addBean()
beanManager = getOrCreateBeanDeployment(bean.getBeanClass()).getBeanManager();
} else {
// Also validate the bean produced by a builder
ExternalBeanAttributesFactory.validateBeanAttributes(bean, getBeanManager());
validateBean(bean);
}
// Custom beans (alternatives, interceptors, decorators) may also implement javax.enterprise.inject.spi.Prioritized
Integer priority = (bean instanceof Prioritized) ? ((Prioritized) bean).getPriority() : null;
// if added via WeldBeanConfigurator, there might be a priority specified as well
if (priority == null && bean instanceof WeldBean) {
priority = ((WeldBean) bean).getPriority();
}
if (bean instanceof Interceptor>) {
beanManager.addInterceptor((Interceptor>) bean);
if (priority != null) {
globalEnablementBuilder.addInterceptor(bean.getBeanClass(), priority);
}
} else if (bean instanceof Decorator>) {
beanManager.addDecorator(CustomDecoratorWrapper.of((Decorator>) bean, beanManager));
if (priority != null) {
globalEnablementBuilder.addDecorator(bean.getBeanClass(), priority);
}
} else {
beanManager.addBean(bean);
if (priority != null && bean.isAlternative()) {
globalEnablementBuilder.addAlternative(bean.getBeanClass(), priority);
}
}
containerLifecycleEvents.fireProcessBean(beanManager, bean, registration.extension);
}
private void validateBean(Bean> bean) {
if (bean.getBeanClass() == null) {
throw BeanLogger.LOG.beanMethodReturnsNull("getBeanClass", bean);
}
if (bean.getInjectionPoints() == null) {
throw BeanLogger.LOG.beanMethodReturnsNull("getInjectionPoints", bean);
}
if (bean instanceof PassivationCapable) {
PassivationCapable passivationCapable = (PassivationCapable) bean;
if (passivationCapable.getId() == null) {
throw BeanLogger.LOG.passivationCapableBeanHasNullId(bean);
}
}
if (bean instanceof Interceptor>) {
validateInterceptor((Interceptor>) bean);
} else if (bean instanceof Decorator>) {
validateDecorator((Decorator>) bean);
}
}
private void validateInterceptor(Interceptor> interceptor) {
Set bindings = interceptor.getInterceptorBindings();
if (bindings == null) {
throw InterceptorLogger.LOG.nullInterceptorBindings(interceptor);
}
for (Annotation annotation : bindings) {
if (!getBeanManager().isInterceptorBinding(annotation.annotationType())) {
throw MetadataLogger.LOG.notAnInterceptorBinding(annotation, interceptor);
}
}
}
private void validateDecorator(Decorator> decorator) {
Set qualifiers = decorator.getDelegateQualifiers();
if (decorator.getDelegateType() == null) {
throw BeanLogger.LOG.decoratorMethodReturnsNull("getDelegateType", decorator);
}
Bindings.validateQualifiers(qualifiers, getBeanManager(), decorator, "Decorator.getDelegateQualifiers");
if (decorator.getDecoratedTypes() == null) {
throw BeanLogger.LOG.decoratorMethodReturnsNull("getDecoratedTypes", decorator);
}
}
private void processObserverRegistration(ObserverRegistration registration) {
ObserverMethod> observerMethod = registration.initObserverMethod();
validateObserverMethod(observerMethod, getBeanManager(), null);
BeanManagerImpl manager = getOrCreateBeanDeployment(observerMethod.getBeanClass()).getBeanManager();
if (Observers.isObserverMethodEnabled(observerMethod, manager)) {
ObserverMethod> processedObserver = containerLifecycleEvents.fireProcessObserverMethod(manager, observerMethod, registration.extension);
if (processedObserver != null) {
manager.addObserver(processedObserver);
}
}
}
private BeanDeploymentFinder getBeanDeploymentFinder() {
return new BeanDeploymentFinder(getBeanDeployments(), getDeployment(), getContexts(), getBeanManager());
}
private static class BeanRegistration {
private final Bean> bean;
private final BeanConfiguratorImpl> beanConfigurator;
private final InterceptorConfiguratorImpl interceptorBuilder;
private final Extension extension;
static BeanRegistration of(Bean> bean, Extension extension) {
return new BeanRegistration(bean, null, null, extension);
}
static BeanRegistration of(BeanConfiguratorImpl> configurator, Extension extension) {
return new BeanRegistration(null, configurator, null, extension);
}
static BeanRegistration of(InterceptorConfiguratorImpl interceptorBuilder) {
return new BeanRegistration(null, null, interceptorBuilder, null);
}
BeanRegistration(Bean> bean, BeanConfiguratorImpl> beanConfigurator, InterceptorConfiguratorImpl interceptorBuilder, Extension extension) {
this.bean = bean;
this.beanConfigurator = beanConfigurator;
this.interceptorBuilder = interceptorBuilder;
this.extension = extension;
}
public Bean> initBean() {
if (bean != null) {
return bean;
} else if (beanConfigurator != null) {
Bean> bean;
try {
bean = beanConfigurator.complete();
} catch (Exception e) {
throw BootstrapLogger.LOG.unableToProcessConfigurator(BeanConfigurator.class.getSimpleName(), extension, e);
}
BootstrapLogger.LOG.addBeanCalled(extension, bean);
return bean;
}
return interceptorBuilder.build();
}
protected BeanManagerImpl initBeanManager() {
if (bean != null) {
return null;
} else if (beanConfigurator != null) {
return beanConfigurator.getBeanManager();
}
return interceptorBuilder.getBeanManager();
}
}
private static class ObserverRegistration {
private final ObserverMethod> observerMethod;
private final Extension extension;
private final ObserverMethodConfiguratorImpl> observerMethodConfigurator;
static ObserverRegistration of(ObserverMethod> observerMethod, Extension extension) {
return new ObserverRegistration(observerMethod, null, extension);
}
static ObserverRegistration of(ObserverMethodConfiguratorImpl configurator, Extension extension) {
return new ObserverRegistration(null, configurator, extension);
}
private ObserverRegistration(ObserverMethod> observerMethod, ObserverMethodConfiguratorImpl> observerMethodBuilder, Extension extension) {
this.observerMethod = observerMethod;
this.observerMethodConfigurator = observerMethodBuilder;
this.extension = extension;
}
ObserverMethod> initObserverMethod() {
if (observerMethod != null) {
return observerMethod;
}
try {
return observerMethodConfigurator.complete();
} catch (Exception e) {
throw BootstrapLogger.LOG.unableToProcessConfigurator(ObserverMethodConfigurator.class.getSimpleName(), extension, e);
}
}
}
}