Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.weld.bootstrap.Validator Maven / Gradle / Ivy
/*
* 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;
import static org.jboss.weld.util.Types.buildClassNameMap;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.NormalScope;
import javax.enterprise.event.Event;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.Decorated;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.Intercepted;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.TransientReference;
import javax.enterprise.inject.spi.Annotated;
import javax.enterprise.inject.spi.AnnotatedField;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.EventMetadata;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.Interceptor;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.enterprise.inject.spi.Producer;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Scope;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotated;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.bean.AbstractBean;
import org.jboss.weld.bean.AbstractClassBean;
import org.jboss.weld.bean.AbstractProducerBean;
import org.jboss.weld.bean.CommonBean;
import org.jboss.weld.bean.DecorableBean;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.bean.DisposalMethod;
import org.jboss.weld.bean.InterceptorImpl;
import org.jboss.weld.bean.NewBean;
import org.jboss.weld.bean.NewManagedBean;
import org.jboss.weld.bean.NewSessionBean;
import org.jboss.weld.bean.ProducerMethod;
import org.jboss.weld.bean.SessionBean;
import org.jboss.weld.bean.WeldDecorator;
import org.jboss.weld.bean.builtin.AbstractBuiltInBean;
import org.jboss.weld.bean.builtin.AbstractDecorableBuiltInBean;
import org.jboss.weld.bean.builtin.ee.EEResourceProducerField;
import org.jboss.weld.bean.interceptor.CdiInterceptorFactory;
import org.jboss.weld.bootstrap.api.Service;
import org.jboss.weld.bootstrap.spi.BeansXml;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.config.ConfigurationKey;
import org.jboss.weld.config.WeldConfiguration;
import org.jboss.weld.ejb.EJBApiAbstraction;
import org.jboss.weld.exceptions.AmbiguousResolutionException;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.exceptions.DeploymentException;
import org.jboss.weld.exceptions.UnproxyableResolutionException;
import org.jboss.weld.injection.producer.AbstractMemberProducer;
import org.jboss.weld.injection.producer.BasicInjectionTarget;
import org.jboss.weld.interceptor.reader.PlainInterceptorFactory;
import org.jboss.weld.interceptor.spi.metadata.InterceptorClassMetadata;
import org.jboss.weld.interceptor.spi.model.InterceptionModel;
import org.jboss.weld.literal.DecoratedLiteral;
import org.jboss.weld.literal.DefaultLiteral;
import org.jboss.weld.literal.InterceptedLiteral;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.logging.MessageCallback;
import org.jboss.weld.logging.ValidatorLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
import org.jboss.weld.metadata.cache.StereotypeModel;
import org.jboss.weld.security.GetDeclaredFieldsAction;
import org.jboss.weld.security.GetDeclaredMethodsAction;
import org.jboss.weld.util.AnnotatedTypes;
import org.jboss.weld.util.BeanMethods;
import org.jboss.weld.util.Beans;
import org.jboss.weld.util.Decorators;
import org.jboss.weld.util.InjectionPoints;
import org.jboss.weld.util.JtaApiAbstraction;
import org.jboss.weld.util.Proxies;
import org.jboss.weld.util.collections.Multimap;
import org.jboss.weld.util.collections.SetMultimap;
import org.jboss.weld.util.collections.WeldCollections;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;
/**
* Checks a list of beans for DeploymentExceptions and their subclasses
*
* @author Nicklas Karlsson
* @author David Allen
* @author Jozef Hartinger
* @author Stuart Douglas
* @author Ales Justin
*/
public class Validator implements Service {
protected void validateGeneralBean(Bean> bean, BeanManagerImpl beanManager) {
for (InjectionPoint ij : bean.getInjectionPoints()) {
validateInjectionPoint(ij, beanManager);
}
// Validate all pseudo-scoped beans, except for built-in beans and session beans which are proxied by the EJB container
if (!beanManager.isNormalScope(bean.getScope()) && !(bean instanceof AbstractBuiltInBean) && !(bean instanceof SessionBean)) {
validatePseudoScopedBean(bean, beanManager);
}
if (beanManager.isPassivatingScope(bean.getScope()) && !Beans.isPassivationCapableBean(bean)) {
throw ValidatorLogger.LOG.beanWithPassivatingScopeNotPassivationCapable(bean);
}
}
/**
* Validate an RIBean. This includes validating whether two beans specialize
* the same bean
*
* @param bean the bean to validate
* @param beanManager the current manager
* @param specializedBeans the existing specialized beans
*/
protected void validateRIBean(CommonBean> bean, BeanManagerImpl beanManager, Collection> specializedBeans) {
validateGeneralBean(bean, beanManager);
if (bean instanceof NewBean) {
return;
}
if (bean instanceof DecorableBean) {
validateDecorators(beanManager, (DecorableBean>) bean);
}
if ((bean instanceof AbstractClassBean>)) {
AbstractClassBean> classBean = (AbstractClassBean>) bean;
// validate CDI-defined interceptors
if (classBean.hasInterceptors()) {
validateInterceptors(beanManager, classBean);
}
}
// for each producer bean validate its disposer method
if (bean instanceof AbstractProducerBean, ?, ?>) {
AbstractProducerBean, ?, ?> producerBean = Reflections.> cast(bean);
if (producerBean.getProducer() instanceof AbstractMemberProducer, ?>) {
AbstractMemberProducer, ?> producer = Reflections.> cast(producerBean
.getProducer());
if (producer.getDisposalMethod() != null) {
for (InjectionPoint ip : producer.getDisposalMethod().getInjectionPoints()) {
// pass the producer bean instead of the disposal method bean
validateInjectionPointForDefinitionErrors(ip, null, beanManager);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_DISPOSER_METHOD);
validateEventMetadataInjectionPoint(ip);
validateInjectionPointForDeploymentProblems(ip, null, beanManager);
}
}
}
}
}
private void validateCustomBean(Bean> bean, BeanManagerImpl beanManager) {
validateGeneralBean(bean, beanManager);
if (!(bean instanceof PassivationCapable) && beanManager.isNormalScope(bean.getScope())) {
ValidatorLogger.LOG.beanNotPassivationCapable(bean);
}
}
private void validateInterceptors(BeanManagerImpl beanManager, AbstractClassBean> classBean) {
InterceptionModel interceptionModel = beanManager.getInterceptorModelRegistry().get(classBean.getAnnotated());
if (interceptionModel != null) {
Set extends InterceptorClassMetadata>> interceptors = interceptionModel.getAllInterceptors();
if (interceptors.size() > 0) {
boolean passivationCapabilityCheckRequired = beanManager.isPassivatingScope(classBean.getScope());
for (InterceptorClassMetadata> interceptorMetadata : interceptors) {
// in the case of CDI interceptors we only need to additionally validate passivation capability (if required)
if (interceptorMetadata.getInterceptorFactory() instanceof CdiInterceptorFactory> && passivationCapabilityCheckRequired) {
CdiInterceptorFactory> cdiInterceptorFactory = (CdiInterceptorFactory>) interceptorMetadata.getInterceptorFactory();
Interceptor> interceptor = cdiInterceptorFactory.getInterceptor();
boolean isSerializable = (interceptor instanceof InterceptorImpl) ? ((InterceptorImpl>) interceptor).isSerializable() : Beans.isPassivationCapableDependency(interceptor);
if (!isSerializable) {
throw ValidatorLogger.LOG.passivatingBeanWithNonserializableInterceptor(classBean, interceptor);
}
if (interceptor instanceof InterceptorImpl) {
beanManager = ((InterceptorImpl>) interceptor).getBeanManager();
}
for (InjectionPoint injectionPoint : interceptor.getInjectionPoints()) {
Bean> resolvedBean = beanManager.resolve(beanManager.getBeans(injectionPoint));
validateInterceptorDecoratorInjectionPointPassivationCapable(injectionPoint, resolvedBean, beanManager, classBean);
}
}
if (interceptorMetadata.getInterceptorFactory() instanceof PlainInterceptorFactory>) {
PlainInterceptorFactory> factory = (PlainInterceptorFactory>) interceptorMetadata.getInterceptorFactory();
Class> interceptorClass = interceptorMetadata.getJavaClass();
if (passivationCapabilityCheckRequired && !Reflections.isSerializable(interceptorClass)) {
throw ValidatorLogger.LOG.passivatingBeanWithNonserializableInterceptor(this, interceptorClass.getName());
}
// if we can't get to the interceptor's BeanManager, we will use the bean's BM instead
InjectionTarget> injectionTarget = factory.getInjectionTarget();
if (injectionTarget instanceof BasicInjectionTarget>) {
beanManager = ((BasicInjectionTarget>) injectionTarget).getBeanManager();
}
for (InjectionPoint injectionPoint : factory.getInjectionTarget().getInjectionPoints()) {
validateInjectionPoint(injectionPoint, beanManager);
if (passivationCapabilityCheckRequired) {
Bean> resolvedBean = beanManager.resolve(beanManager.getBeans(injectionPoint));
validateInterceptorDecoratorInjectionPointPassivationCapable(injectionPoint, resolvedBean, beanManager, classBean);
}
}
}
}
}
}
}
private void validateDecorators(BeanManagerImpl beanManager, DecorableBean> bean) {
if (!(beanManager.isPassivatingScope(bean.getScope()) || bean instanceof AbstractDecorableBuiltInBean>)) {
return;
}
List> decorators = bean.getDecorators();
if (decorators.isEmpty()) {
return;
}
for (Decorator> decorator : decorators) {
if (!Decorators.isPassivationCapable(decorator)) {
if (bean instanceof AbstractDecorableBuiltInBean>) {
throw ValidatorLogger.LOG.builtinBeanWithNonserializableDecorator(decorator, bean);
} else {
throw ValidatorLogger.LOG.passivatingBeanWithNonserializableDecorator(bean, decorator);
}
}
if (decorator instanceof DecoratorImpl) {
beanManager = ((DecoratorImpl>) decorator).getBeanManager();
}
for (InjectionPoint ij : decorator.getInjectionPoints()) {
if (!ij.isDelegate()) {
Bean> resolvedBean = beanManager.resolve(beanManager.getBeans(ij));
validateInterceptorDecoratorInjectionPointPassivationCapable(ij, resolvedBean, beanManager, bean);
}
}
}
}
/**
* Validate an injection point
*
* @param ij the injection point to validate
* @param beanManager the bean manager
*/
public void validateInjectionPoint(InjectionPoint ij, BeanManagerImpl beanManager) {
validateInjectionPointForDefinitionErrors(ij, ij.getBean(), beanManager);
validateMetadataInjectionPoint(ij, ij.getBean(), ValidatorLogger.INJECTION_INTO_NON_BEAN);
validateEventMetadataInjectionPoint(ij);
validateInjectionPointForDeploymentProblems(ij, ij.getBean(), beanManager);
}
/**
* Checks for definition errors associated with a given {@link InjectionPoint}
*/
public void validateInjectionPointForDefinitionErrors(InjectionPoint ij, Bean> bean, BeanManagerImpl beanManager) {
if (ij.getAnnotated().getAnnotation(New.class) != null && ij.getQualifiers().size() > 1) {
throw ValidatorLogger.LOG.newWithQualifiers(ij, Formats.formatAsStackTraceElement(ij));
}
if (ij.getType() instanceof TypeVariable>) {
throw ValidatorLogger.LOG.injectionPointWithTypeVariable(ij, Formats.formatAsStackTraceElement(ij));
}
if (!(ij.getMember() instanceof Field) && ij.getAnnotated().isAnnotationPresent(Named.class) && ij.getAnnotated().getAnnotation(Named.class).value().equals("")) {
throw ValidatorLogger.LOG.nonFieldInjectionPointCannotUseNamed(ij, Formats.formatAsStackTraceElement(ij));
}
if (ij.getAnnotated().isAnnotationPresent(Produces.class)) {
if (bean != null) {
throw BeanLogger.LOG.injectedFieldCannotBeProducer(ij.getAnnotated(), bean);
} else {
throw BeanLogger.LOG.injectedFieldCannotBeProducer(ij.getAnnotated(), Reflections.>cast(ij.getAnnotated()).getDeclaringType());
}
}
boolean newBean = (bean instanceof NewManagedBean>) || (bean instanceof NewSessionBean>);
if (!newBean) {
checkScopeAnnotations(ij, beanManager.getServices().get(MetaAnnotationStore.class));
}
checkFacadeInjectionPoint(ij, Instance.class);
checkFacadeInjectionPoint(ij, Event.class);
// check that UserTransaction is not injected into a SessionBean with container-managed transactions
if (bean instanceof SessionBean>) {
JtaApiAbstraction jtaApi = beanManager.getServices().get(JtaApiAbstraction.class);
if (jtaApi.USER_TRANSACTION_CLASS.equals(ij.getType()) &&
(ij.getQualifiers().isEmpty() || ij.getQualifiers().contains(DefaultLiteral.INSTANCE)) &&
beanManager.getServices().get(EJBApiAbstraction.class).isSessionBeanWithContainerManagedTransactions(bean)) {
throw ValidatorLogger.LOG.userTransactionInjectionIntoBeanWithContainerManagedTransactions(ij, Formats.formatAsStackTraceElement(ij));
}
}
}
public void validateMetadataInjectionPoint(InjectionPoint ij, Bean> bean, MessageCallback messageCallback) {
// metadata injection points
if (ij.getType().equals(InjectionPoint.class) && bean == null) {
throw messageCallback.construct(ij, Formats.formatAsStackTraceElement(ij));
}
if (ij.getType().equals(InjectionPoint.class) && !Dependent.class.equals(bean.getScope())) {
throw ValidatorLogger.LOG.injectionIntoNonDependentBean(ij, Formats.formatAsStackTraceElement(ij));
}
Class> rawType = Reflections.getRawType(ij.getType());
if (Bean.class.equals(rawType) || Interceptor.class.equals(rawType) || Decorator.class.equals(rawType)) {
if (bean == null) {
throw messageCallback.construct(ij, Formats.formatAsStackTraceElement(ij));
}
if (bean instanceof AbstractClassBean>) {
checkBeanMetadataInjectionPoint(bean, ij, AnnotatedTypes.getDeclaringAnnotatedType(ij.getAnnotated()).getBaseType());
}
if (bean instanceof ProducerMethod, ?>) {
ProducerMethod, ?> producerMethod = Reflections.cast(bean);
checkBeanMetadataInjectionPoint(bean, ij, producerMethod.getAnnotated().getBaseType());
}
}
}
public void validateEventMetadataInjectionPoint(InjectionPoint ip) {
if (EventMetadata.class.equals(ip.getType()) && ip.getQualifiers().contains(DefaultLiteral.INSTANCE)) {
throw ValidatorLogger.LOG.eventMetadataInjectedOutsideOfObserver(ip, Formats.formatAsStackTraceElement(ip));
}
}
/**
* Checks for deployment problems associated with a given {@link InjectionPoint}
*/
public void validateInjectionPointForDeploymentProblems(InjectionPoint ij, Bean> bean, BeanManagerImpl beanManager) {
if (ij.isDelegate()) {
return; // do not validate delegate injection points as these are special
}
Set> resolvedBeans = beanManager.getBeanResolver().resolve(beanManager.getBeans(ij));
if (!isInjectionPointSatisfied(ij, resolvedBeans, beanManager)) {
throw ValidatorLogger.LOG.injectionPointHasUnsatisfiedDependencies(
ij,
Formats.formatAnnotations(ij.getQualifiers()),
Formats.formatInjectionPointType(ij.getType()),
Formats.formatAsStackTraceElement(ij),
InjectionPoints.getUnsatisfiedDependenciesAdditionalInfo(ij, beanManager));
}
if (resolvedBeans.size() > 1) {
throw ValidatorLogger.LOG.injectionPointHasAmbiguousDependencies(
ij,
Formats.formatAnnotations(ij.getQualifiers()),
Formats.formatInjectionPointType(ij.getType()),
Formats.formatAsStackTraceElement(ij),
WeldCollections.toMultiRowString(resolvedBeans));
}
// Account for the case this is disabled decorator
if (!resolvedBeans.isEmpty()) {
Bean> resolvedBean = (Bean>) resolvedBeans.iterator().next();
if (beanManager.isNormalScope(resolvedBean.getScope())) {
UnproxyableResolutionException ue = Proxies.getUnproxyableTypeException(ij.getType(), resolvedBean, beanManager.getServices());
if (ue != null) {
throw ValidatorLogger.LOG.injectionPointHasNonProxyableDependencies(ij, Formats.formatAsStackTraceElement(ij), ue);
}
}
if (bean != null && Beans.isPassivatingScope(bean, beanManager)) {
validateInjectionPointPassivationCapable(ij, resolvedBean, beanManager);
}
}
}
public void validateProducers(Collection> producers, BeanManagerImpl beanManager) {
for (Producer> producer : producers) {
validateProducer(producer, beanManager);
}
}
public void validateProducer(Producer> producer, BeanManagerImpl beanManager) {
for (InjectionPoint injectionPoint : producer.getInjectionPoints()) {
validateInjectionPoint(injectionPoint, beanManager);
}
}
private void checkScopeAnnotations(InjectionPoint ij, MetaAnnotationStore metaAnnotationStore) {
Annotated annotated = ij.getAnnotated();
if (annotated instanceof EnhancedAnnotated, ?>) {
EnhancedAnnotated, ?> weldAnnotated = (EnhancedAnnotated, ?>) annotated;
Set scopes = weldAnnotated.getMetaAnnotations(Scope.class);
Set normalScopes = weldAnnotated.getMetaAnnotations(NormalScope.class);
for (Annotation annotation : scopes) {
logScopeOnInjectionPointWarning(ij, annotation);
}
for (Annotation annotation : normalScopes) {
logScopeOnInjectionPointWarning(ij, annotation);
}
} else {
for (Annotation annotation : annotated.getAnnotations()) {
if (hasScopeMetaAnnotation(annotation)) {
logScopeOnInjectionPointWarning(ij, annotation);
}
}
}
}
private void logScopeOnInjectionPointWarning(InjectionPoint ij, Annotation annotation) {
ValidatorLogger.LOG.scopeAnnotationOnInjectionPoint(annotation, ij, Formats.formatAsStackTraceElement(ij));
}
private boolean hasScopeMetaAnnotation(Annotation annotation) {
Class extends Annotation> annotationType = annotation.annotationType();
return annotationType.isAnnotationPresent(Scope.class) || annotationType.isAnnotationPresent(NormalScope.class);
}
private boolean isInjectionPointPassivationCapable(InjectionPoint ij, Bean> resolvedBean, BeanManagerImpl beanManager) {
if (!Beans.isPassivationCapableDependency(resolvedBean)) {
if (((ij.getMember() instanceof Field) && ij.isTransient())) {
return true;
}
if (ij.getAnnotated() instanceof AnnotatedParameter> && ij.getAnnotated().isAnnotationPresent(TransientReference.class)) {
return true;
}
return false;
}
return true;
}
public void validateInjectionPointPassivationCapable(InjectionPoint ij, Bean> resolvedBean, BeanManagerImpl beanManager) {
if (!isInjectionPointPassivationCapable(ij, resolvedBean, beanManager)) {
throw ValidatorLogger.LOG.injectionPointHasNonSerializableDependency(ij.getBean(), resolvedBean);
}
}
public void validateInterceptorDecoratorInjectionPointPassivationCapable(InjectionPoint ij, Bean> resolvedBean, BeanManagerImpl beanManager, Bean> bean) {
if (!isInjectionPointPassivationCapable(ij, resolvedBean, beanManager)) {
throw ValidatorLogger.LOG.interceptorDecoratorInjectionPointHasNonSerializableDependency(bean, ij.getBean(), resolvedBean);
}
}
public void validateDeployment(BeanManagerImpl manager, BeanDeployment deployment) {
validateDecorators(manager.getDecorators(), manager);
validateInterceptors(manager.getInterceptors(), manager);
validateBeans(manager.getBeans(), manager);
validateEnabledDecoratorClasses(manager, deployment);
validateEnabledInterceptorClasses(manager, deployment);
validateEnabledAlternativeStereotypes(manager, deployment);
validateEnabledAlternativeClasses(manager, deployment);
validateSpecialization(manager);
validateDisposalMethods(deployment.getBeanDeployer().getEnvironment());
validateObserverMethods(deployment.getBeanDeployer().getEnvironment().getObservers(), manager);
validateBeanNames(manager);
}
public void validateSpecialization(BeanManagerImpl manager) {
SpecializationAndEnablementRegistry registry = manager.getServices().get(SpecializationAndEnablementRegistry.class);
for (Entry, Long> entry : registry.getBeansSpecializedInAnyDeploymentAsMap().entrySet()) {
if (entry.getValue()> 1) {
throw ValidatorLogger.LOG.beanSpecializedTooManyTimes(entry.getKey());
}
}
}
public void validateBeans(Collection extends Bean>> beans, BeanManagerImpl manager) {
final List problems = new ArrayList();
final Set> specializedBeans = new HashSet>();
for (Bean> bean : beans) {
validateBean(bean, specializedBeans, manager, problems);
}
if (!problems.isEmpty()) {
if (problems.size() == 1) {
throw problems.get(0);
} else {
throw new DeploymentException(problems);
}
}
}
protected void validateBean(Bean> bean, Collection> specializedBeans, BeanManagerImpl manager, List problems) {
try {
if (bean instanceof CommonBean>) {
validateRIBean((CommonBean>) bean, manager, specializedBeans);
} else {
validateCustomBean(bean, manager);
}
} catch (RuntimeException e) {
problems.add(e);
}
}
public void validateInterceptors(Collection extends Interceptor>> interceptors, BeanManagerImpl manager) {
for (Interceptor> interceptor : interceptors) {
validateInterceptor(interceptor, manager);
}
}
protected void validateInterceptor(Interceptor> interceptor, BeanManagerImpl manager) {
if (interceptor instanceof InterceptorImpl>) {
EnhancedAnnotatedType> annotated = ((InterceptorImpl>) interceptor).getEnhancedAnnotated();
if (!BeanMethods.getObserverMethods(annotated).isEmpty()) {
throw ValidatorLogger.LOG.interceptorsCannotHaveObserverMethods(interceptor);
}
if (!interceptor.getScope().equals(Dependent.class)) {
throw ValidatorLogger.LOG.interceptorOrDecoratorMustBeDependent(interceptor);
}
while (annotated != null && annotated.getJavaClass() != Object.class) {
if (!annotated.getDeclaredEnhancedMethods(Produces.class).isEmpty()) {
throw ValidatorLogger.LOG.interceptorsCannotHaveProducerMethods(interceptor);
}
if (!annotated.getDeclaredEnhancedFields(Produces.class).isEmpty()) {
throw ValidatorLogger.LOG.interceptorsCannotHaveProducerFields(interceptor);
}
if (!annotated.getDeclaredEnhancedMethodsWithAnnotatedParameters(Disposes.class).isEmpty()) {
throw ValidatorLogger.LOG.interceptorsCannotHaveDisposerMethods(interceptor);
}
annotated = annotated.getEnhancedSuperclass();
}
}
for (InjectionPoint injectionPoint : interceptor.getInjectionPoints()) {
validateInjectionPoint(injectionPoint, manager);
}
}
public void validateDecorators(Collection extends Decorator>> decorators, BeanManagerImpl manager) {
Set> specializedBeans = new HashSet>();
for (Decorator> decorator : decorators) {
validateDecorator(decorator, specializedBeans, manager);
}
}
protected void validateDecorator(Decorator> decorator, Collection> specializedBeans, BeanManagerImpl manager) {
if (decorator.getDecoratedTypes().isEmpty()) {
throw ValidatorLogger.LOG.noDecoratedTypes(decorator);
}
if (!decorator.getScope().equals(Dependent.class)) {
throw ValidatorLogger.LOG.interceptorOrDecoratorMustBeDependent(decorator);
}
Decorators.checkDelegateType(decorator);
/*
* Validate decorators of facade built-in beans
*/
Type delegateType = decorator.getDelegateType();
if (delegateType instanceof ParameterizedType) {
ParameterizedType parameterizedDelegateType = (ParameterizedType) delegateType;
if (!Decorators.isPassivationCapable(decorator)) {
if (Instance.class.equals(parameterizedDelegateType.getRawType()) || Provider.class.equals(parameterizedDelegateType.getRawType())) {
throw ValidatorLogger.LOG.builtinBeanWithNonserializableDecorator(decorator, Instance.class.getName());
}
if (Event.class.equals(parameterizedDelegateType.getRawType())) {
throw ValidatorLogger.LOG.builtinBeanWithNonserializableDecorator(decorator, Event.class.getName());
}
}
}
if (decorator instanceof WeldDecorator>) {
EnhancedAnnotatedType> annotated = ((WeldDecorator>) decorator).getEnhancedAnnotated();
if (decorator instanceof DecoratorImpl>) {
// Discovered decorator bean - abstract methods and delegate injection point are validated during bean initialization
validateRIBean((CommonBean>) decorator, manager, specializedBeans);
// Following checks are not legal for custom decorator beans as we cannot rely on decorator bean class methods
if (!BeanMethods.getObserverMethods(annotated).isEmpty()) {
throw ValidatorLogger.LOG.decoratorsCannotHaveObserverMethods(decorator);
}
while (annotated != null && annotated.getJavaClass() != Object.class) {
if (!annotated.getDeclaredEnhancedMethods(Produces.class).isEmpty()) {
throw ValidatorLogger.LOG.decoratorsCannotHaveProducerMethods(decorator);
}
if (!annotated.getDeclaredEnhancedFields(Produces.class).isEmpty()) {
throw ValidatorLogger.LOG.decoratorsCannotHaveProducerFields(decorator);
}
if (!annotated.getDeclaredEnhancedMethodsWithAnnotatedParameters(Disposes.class).isEmpty()) {
throw ValidatorLogger.LOG.decoratorsCannotHaveDisposerMethods(decorator);
}
annotated = annotated.getEnhancedSuperclass();
}
} else {
// Custom decorator bean
validateGeneralBean(decorator, manager);
Decorators.findDelegateInjectionPoint(annotated, decorator.getInjectionPoints());
}
}
}
public void validateBeanNames(BeanManagerImpl beanManager) {
SetMultimap> namedAccessibleBeans = SetMultimap.newSetMultimap();
for (Bean> bean : beanManager.getAccessibleBeans()) {
if (bean.getName() != null) {
namedAccessibleBeans.put(bean.getName(), bean);
}
}
List accessibleNamespaces = beanManager.getAccessibleNamespaces();
for (String name : namedAccessibleBeans.keySet()) {
validateBeanName(name, namedAccessibleBeans, accessibleNamespaces, beanManager);
}
}
protected void validateBeanName(String name, SetMultimap> namedAccessibleBeans, List accessibleNamespaces,
BeanManagerImpl beanManager) {
Set> resolvedBeans = beanManager.getBeanResolver(). resolve(Beans.removeDisabledBeans(namedAccessibleBeans.get(name), beanManager));
if (resolvedBeans.size() > 1) {
throw ValidatorLogger.LOG.ambiguousElName(name, resolvedBeans);
}
if (accessibleNamespaces.contains(name)) {
throw ValidatorLogger.LOG.beanNameIsPrefix(name);
}
}
private void validateEnabledInterceptorClasses(BeanManagerImpl beanManager, BeanDeployment deployment) {
BeansXml beansXml = deployment.getBeanDeploymentArchive().getBeansXml();
if (beansXml != null && !beansXml.getEnabledInterceptors().isEmpty()) {
Set interceptorBeanClasses = new HashSet();
for (Interceptor> interceptor : beanManager.getDynamicAccessibleInterceptors()) {
interceptorBeanClasses.add(interceptor.getBeanClass().getName());
}
for (Metadata interceptorClassName : beansXml.getEnabledInterceptors()) {
if (!interceptorBeanClasses.contains(interceptorClassName.getValue())) {
throw ValidatorLogger.LOG.interceptorClassDoesNotMatchInterceptorBean(interceptorClassName.getValue(), interceptorClassName.getLocation());
}
}
}
}
private void validateEnabledDecoratorClasses(BeanManagerImpl beanManager, BeanDeployment deployment) {
BeansXml beansXml = deployment.getBeanDeploymentArchive().getBeansXml();
if (beansXml != null && !beansXml.getEnabledDecorators().isEmpty()) {
Set decoratorBeanClasses = new HashSet();
for (Decorator> bean : beanManager.getDynamicAccessibleDecorators()) {
decoratorBeanClasses.add(bean.getBeanClass().getName());
}
for (Metadata decoratorClassName : beansXml.getEnabledDecorators()) {
if (!decoratorBeanClasses.contains(decoratorClassName.getValue())) {
throw ValidatorLogger.LOG.decoratorClassNotBeanClassOfDecorator(decoratorClassName.getValue(), WeldCollections.toMultiRowString(decoratorBeanClasses));
}
}
}
}
private void validateEnabledAlternativeStereotypes(BeanManagerImpl beanManager, BeanDeployment deployment) {
BeansXml beansXml = deployment.getBeanDeploymentArchive().getBeansXml();
if (beansXml != null && !beansXml.getEnabledAlternativeStereotypes().isEmpty()) {
// prepare lookup structure
Map> loadedStereotypes = buildClassNameMap(beanManager.getEnabled().getAlternativeStereotypes());
for (Metadata definition : beansXml.getEnabledAlternativeStereotypes()) {
Class extends Annotation> stereotype = loadedStereotypes.get(definition.getValue());
if (!beanManager.isStereotype(stereotype)) {
throw ValidatorLogger.LOG.alternativeStereotypeNotStereotype(definition);
}
if (!isAlternativeStereotype(beanManager, stereotype)) {
throw ValidatorLogger.LOG.alternativeStereotypeNotAnnotated(definition);
}
}
}
}
private void validateEnabledAlternativeClasses(BeanManagerImpl beanManager, BeanDeployment deployment) {
BeansXml beansXml = deployment.getBeanDeploymentArchive().getBeansXml();
if (beansXml != null && !beansXml.getEnabledAlternativeClasses().isEmpty()) {
// prepare lookup structure
Map> loadedClasses = buildClassNameMap(beanManager.getEnabled().getAlternativeClasses());
// lookup structure for validation of alternatives
Multimap, Bean>> beansByClass = SetMultimap.newSetMultimap();
for (Bean> bean : beanManager.getDynamicAccessibleBeans()) {
if (!(bean instanceof NewBean)) {
beansByClass.put(bean.getBeanClass(), bean);
}
}
for (Metadata definition : beansXml.getEnabledAlternativeClasses()) {
Class> enabledClass = loadedClasses.get(definition.getValue());
if (enabledClass.isAnnotation() || enabledClass.isInterface()) {
throw ValidatorLogger.LOG.alternativeBeanClassNotClass(definition);
} else {
final WeldConfiguration configuration = beanManager.getServices().get(WeldConfiguration.class);
boolean allowVetoedAlternatives = configuration.getBooleanProperty(ConfigurationKey.ALLOW_VETOED_ALTERNATIVES);
// check that the class is a bean class of at least one alternative. If it is not and weld is configured to allow excluded alternatives check if the class is annotated with @Alternative or an alternative stereotype.
if (!isAlternativeBean(enabledClass, beansByClass)) {
if (!allowVetoedAlternatives) {
throw ValidatorLogger.LOG.alternativeBeanClassNotAnnotatedOrVetoed(definition.getValue(), definition.getLocation());
} else if (! isAlternativeCandidate(enabledClass, beanManager)) {
throw ValidatorLogger.LOG.alternativeBeanClassNotAnnotated(definition.getValue(), definition.getLocation());
}
}
}
}
}
}
private boolean isAlternativeCandidate(Class> enabledClass, BeanManagerImpl beanManager) {
// Note that the deployment would fail if any alternative cannot be loaded
// exists and is annotated with @Alternative or alternative stereotype
if (isAlternativeOrHasAlternativeStereotype(enabledClass, beanManager)) {
return true;
}
// declares producer with alternative
// Intentionally do not process the class hierarchy -
for (Method declaredMethod : AccessController.doPrivileged(new GetDeclaredMethodsAction(enabledClass))) {
if (declaredMethod.isAnnotationPresent(Produces.class) && isAlternativeOrHasAlternativeStereotype(declaredMethod, beanManager)) {
return true;
}
}
for (Field declaredField : AccessController.doPrivileged(new GetDeclaredFieldsAction(enabledClass))) {
if (declaredField.isAnnotationPresent(Produces.class) && isAlternativeOrHasAlternativeStereotype(declaredField, beanManager)) {
return true;
}
}
return false;
}
private boolean isAlternativeOrHasAlternativeStereotype(AnnotatedElement annotatedElement, BeanManagerImpl beanManager) {
if (annotatedElement.isAnnotationPresent(Alternative.class)) {
return true;
}
for (Annotation annotation : annotatedElement.getAnnotations()) {
if (isAlternativeStereotype(beanManager, annotation.annotationType())) {
return true;
}
}
return false;
}
private boolean isAlternativeBean(Class> enabledClass, Multimap, Bean>> beansByClass) {
// check that the class is a bean class of at least one alternative
for (Bean> bean : beansByClass.get(enabledClass)) {
if (bean.isAlternative()) {
return true;
}
}
return false;
}
private boolean isAlternativeStereotype(BeanManagerImpl beanManager, Class extends Annotation> stereotype) {
final StereotypeModel extends Annotation> model = beanManager.getServices().get(MetaAnnotationStore.class).getStereotype(stereotype);
if (model.isValid() && model.isAlternative()) {
return true;
}
return false;
}
private void validateDisposalMethods(BeanDeployerEnvironment environment) {
Set> beans = environment.getUnresolvedDisposalBeans();
if (!beans.isEmpty()) {
throw ValidatorLogger.LOG.disposalMethodsWithoutProducer(WeldCollections.toMultiRowString(beans));
}
}
protected void validateObserverMethods(Iterable> observers, BeanManagerImpl beanManager) {
for (ObserverInitializationContext, ?> omi : observers) {
for (InjectionPoint ip : omi.getObserver().getInjectionPoints()) {
validateInjectionPointForDefinitionErrors(ip, ip.getBean(), beanManager);
validateMetadataInjectionPoint(ip, null, ValidatorLogger.INJECTION_INTO_NON_BEAN);
validateInjectionPointForDeploymentProblems(ip, ip.getBean(), beanManager);
}
}
}
private static void checkFacadeInjectionPoint(InjectionPoint injectionPoint, Class> type) {
Type injectionPointType = injectionPoint.getType();
if (injectionPointType instanceof Class> && type.equals(injectionPointType)) {
throw ValidatorLogger.LOG.injectionPointMustHaveTypeParameter(injectionPoint, Formats.formatAsStackTraceElement(injectionPoint));
}
if (injectionPointType instanceof ParameterizedType && !injectionPoint.isDelegate()) {
ParameterizedType parameterizedType = (ParameterizedType) injectionPointType;
if (type.equals(parameterizedType.getRawType())) {
if (parameterizedType.getActualTypeArguments()[0] instanceof TypeVariable>) {
throw ValidatorLogger.LOG.injectionPointWithTypeVariable(injectionPoint, Formats.formatAsStackTraceElement(injectionPoint));
}
if (parameterizedType.getActualTypeArguments()[0] instanceof WildcardType) {
throw ValidatorLogger.LOG.injectionPointHasWildcard(injectionPoint, Formats.formatAsStackTraceElement(injectionPoint));
}
}
}
}
public static void checkBeanMetadataInjectionPoint(Object bean, InjectionPoint ip, Type expectedTypeArgument) {
if (!(ip.getType() instanceof ParameterizedType)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
ParameterizedType parameterizedType = (ParameterizedType) ip.getType();
if (parameterizedType.getActualTypeArguments().length != 1) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
Class> rawType = (Class>) parameterizedType.getRawType();
Type typeArgument = parameterizedType.getActualTypeArguments()[0];
if (bean == null) {
throw ValidatorLogger.LOG.injectionIntoNonBean(ip, Formats.formatAsStackTraceElement(ip));
}
/*
* If an Interceptor instance is injected into a bean instance other than an interceptor instance, the container
* automatically detects the problem and treats it as a definition error.
*/
if (rawType.equals(Interceptor.class) && !(bean instanceof Interceptor>)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
/*
* If a Decorator instance is injected into a bean instance other than a decorator instance, the container automatically
* detects the problem and treats it as a definition error.
*/
if (rawType.equals(Decorator.class) && !(bean instanceof Decorator>)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
Set qualifiers = ip.getQualifiers();
if (qualifiers.contains(InterceptedLiteral.INSTANCE)) {
/*
* If a Bean instance with qualifier @Intercepted is injected into a bean instance other than an interceptor
* instance, the container automatically detects the problem and treats it as a definition error.
*/
if (!(bean instanceof Interceptor>)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointQualifier(Intercepted.class, Interceptor.class, ip, Formats.formatAsStackTraceElement(ip));
}
/*
* If the injection point is a field, an initializer method parameter or a bean constructor of an interceptor, with
* qualifier @Intercepted, then the type parameter of the injected Bean must be an unbounded wildcard.
*/
if (!rawType.equals(Bean.class)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
if (!Reflections.isUnboundedWildcard(typeArgument)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointTypeArgument(typeArgument, ip, Formats.formatAsStackTraceElement(ip));
}
}
if (qualifiers.contains(DecoratedLiteral.INSTANCE)) {
/*
* If a Bean instance with qualifier @Decorated is injected into a bean instance other than a decorator instance,
* the container automatically detects the problem and treats it as a definition error.
*/
if (!(bean instanceof Decorator>)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointQualifier(Decorated.class, Decorator.class, ip, Formats.formatAsStackTraceElement(ip));
}
Decorator> decorator = Reflections.cast(bean);
/*
* If the injection point is a field, an initializer method parameter or a bean constructor of a decorator, with
* qualifier @Decorated, then the type parameter of the injected Bean must be the same as the delegate type.
*/
if (!rawType.equals(Bean.class)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointType(ip.getType(), ip, Formats.formatAsStackTraceElement(ip));
}
if (!typeArgument.equals(decorator.getDelegateType())) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointTypeArgument(typeArgument, ip, Formats.formatAsStackTraceElement(ip));
}
}
if (qualifiers.contains(DefaultLiteral.INSTANCE)) {
/*
* If the injection point is a field, an initializer method parameter or a bean constructor, with qualifier
* @Default, then the type parameter of the injected Bean, Interceptor or Decorator must be the same as the type
* declaring the injection point.
*
* If the injection point is a producer method parameter then the type parameter of the injected Bean must be the
* same as the producer method return type.
*
* If the injection point is a disposer method parameter then the type parameter of the injected Bean must be the
* same as the disposed parameter.
*/
if (!expectedTypeArgument.equals(typeArgument)) {
throw ValidatorLogger.LOG.invalidBeanMetadataInjectionPointTypeArgument(typeArgument, ip, Formats.formatAsStackTraceElement(ip));
}
}
}
private static boolean isInjectionPointSatisfied(InjectionPoint ij, Set> resolvedBeans, BeanManagerImpl beanManager) {
if (ij.getBean() instanceof Decorator>) {
if (beanManager.getEnabled().isDecoratorEnabled(ij.getBean().getBeanClass())) {
return resolvedBeans.size() > 0;
} else {
return true;
}
} else {
return resolvedBeans.size() > 0;
}
}
/**
* Checks to make sure that pseudo scoped beans (i.e. @Dependent scoped beans) have no circular dependencies.
*/
private static void validatePseudoScopedBean(Bean> bean, BeanManagerImpl beanManager) {
if (bean.getInjectionPoints().isEmpty()) {
// Skip validation if there are no injection points (e.g. for classes which are not intended to be used as beans)
return;
}
reallyValidatePseudoScopedBean(bean, beanManager, new LinkedHashSet(), new HashSet>());
}
/**
* checks if a bean has been seen before in the dependencyPath. If not, it
* resolves the InjectionPoints and adds the resolved beans to the set of
* beans to be validated
*/
private static void reallyValidatePseudoScopedBean(Bean> bean, BeanManagerImpl beanManager, Set dependencyPath, Set> validatedBeans) {
// see if we have already seen this bean in the dependency path
if (dependencyPath.contains(bean)) {
// create a list that shows the path to the bean
List realDependencyPath = new ArrayList(dependencyPath);
realDependencyPath.add(bean);
throw ValidatorLogger.LOG.pseudoScopedBeanHasCircularReferences(WeldCollections.toMultiRowString(realDependencyPath));
}
if (validatedBeans.contains(bean)) {
return;
}
dependencyPath.add(bean);
for (InjectionPoint injectionPoint : bean.getInjectionPoints()) {
if (!injectionPoint.isDelegate()) {
dependencyPath.add(injectionPoint);
validatePseudoScopedInjectionPoint(injectionPoint, beanManager, dependencyPath, validatedBeans);
dependencyPath.remove(injectionPoint);
}
}
if (bean instanceof DecorableBean>) {
final List> decorators = Reflections.>cast(bean).getDecorators();
if (!decorators.isEmpty()) {
for (final Decorator> decorator : decorators) {
reallyValidatePseudoScopedBean(decorator, beanManager, dependencyPath, validatedBeans);
}
}
}
if (bean instanceof AbstractProducerBean, ?, ?> && !(bean instanceof EEResourceProducerField, ?>)) {
AbstractProducerBean, ?, ?> producer = (AbstractProducerBean, ?, ?>) bean;
if (!beanManager.isNormalScope(producer.getDeclaringBean().getScope()) && !producer.getAnnotated().isStatic()) {
reallyValidatePseudoScopedBean(producer.getDeclaringBean(), beanManager, dependencyPath, validatedBeans);
}
}
validatedBeans.add(bean);
dependencyPath.remove(bean);
}
private static void validatePseudoScopedInjectionPoint(InjectionPoint ij, BeanManagerImpl beanManager, Set dependencyPath, Set> validatedBeans) {
Set> resolved = beanManager.getBeans(ij);
Bean> bean = null;
try {
bean = beanManager.resolve(resolved);
} catch (AmbiguousResolutionException ex) {
throw ValidatorLogger.LOG.injectionPointHasAmbiguousDependencies(ij, Formats.formatAnnotations(ij.getQualifiers()),
Formats.formatInjectionPointType(ij.getType()),
Formats.formatAsStackTraceElement(ij),
WeldCollections.toMultiRowString(resolved));
}
if (bean != null) {
if (!(bean instanceof AbstractBuiltInBean>)) {
if (!ij.isDelegate()) {
boolean normalScoped = beanManager.isNormalScope(bean.getScope());
if (!normalScoped && !(bean instanceof SessionBean)) {
reallyValidatePseudoScopedBean(bean, beanManager, dependencyPath, validatedBeans);
}
}
}
}
}
@Override
public void cleanup() {
}
}