All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.weld.util.Beans Maven / Gradle / Ivy

There is a newer version: 3.0.0.Alpha1
Show newest version
/*
 * 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.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.decorator.Decorator;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Alternative;
import javax.enterprise.inject.CreationException;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.inject.Inject;

import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Collections2;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;

import org.jboss.weld.Container;
import org.jboss.weld.bean.AbstractReceiverBean;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.bean.InterceptorImpl;
import org.jboss.weld.bean.RIBean;
import org.jboss.weld.bean.SessionBean;
import org.jboss.weld.ejb.EJBApiAbstraction;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.exceptions.IllegalArgumentException;
import org.jboss.weld.injection.ConstructorInjectionPoint;
import org.jboss.weld.injection.FieldInjectionPoint;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.injection.ParameterInjectionPoint;
import org.jboss.weld.injection.WeldInjectionPoint;
import org.jboss.weld.injection.spi.EjbInjectionServices;
import org.jboss.weld.injection.spi.JpaInjectionServices;
import org.jboss.weld.injection.spi.ResourceInjectionServices;
import org.jboss.weld.interceptor.InterceptorBindingType;
import org.jboss.weld.interceptor.spi.model.InterceptionType;
import org.jboss.weld.interceptor.util.InterceptionTypeRegistry;
import org.jboss.weld.introspector.MethodSignature;
import org.jboss.weld.introspector.WeldAnnotated;
import org.jboss.weld.introspector.WeldClass;
import org.jboss.weld.introspector.WeldConstructor;
import org.jboss.weld.introspector.WeldField;
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.introspector.WeldParameter;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.manager.Enabled;
import org.jboss.weld.metadata.cache.MergedStereotypes;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
import org.jboss.weld.persistence.PersistenceApiAbstraction;
import org.jboss.weld.resolution.QualifierInstance;
import org.jboss.weld.util.collections.ArraySet;
import org.jboss.weld.util.collections.HashSetSupplier;
import org.jboss.weld.util.reflection.Reflections;
import org.slf4j.cal10n.LocLogger;

import static java.util.Arrays.asList;
import static org.jboss.weld.logging.Category.BEAN;
import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_DEFAULT_CONSTRUCTOR;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_INJECTABLE_CONSTRUCTORS;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_ONE_INJECTABLE_CONSTRUCTOR;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_ONE_POST_CONSTRUCT_METHOD;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_ONE_PRE_DESTROY_METHOD;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_POST_CONSTRUCT_METHODS;
import static org.jboss.weld.logging.messages.BeanMessage.FOUND_PRE_DESTROY_METHODS;
import static org.jboss.weld.logging.messages.EventMessage.INVALID_INITIALIZER;
import static org.jboss.weld.logging.messages.UtilMessage.AMBIGUOUS_CONSTRUCTOR;
import static org.jboss.weld.logging.messages.UtilMessage.ANNOTATION_NOT_QUALIFIER;
import static org.jboss.weld.logging.messages.UtilMessage.INITIALIZER_CANNOT_BE_DISPOSAL_METHOD;
import static org.jboss.weld.logging.messages.UtilMessage.INITIALIZER_CANNOT_BE_PRODUCER;
import static org.jboss.weld.logging.messages.UtilMessage.INITIALIZER_METHOD_IS_GENERIC;
import static org.jboss.weld.logging.messages.UtilMessage.INVALID_QUANTITY_INJECTABLE_FIELDS_AND_INITIALIZER_METHODS;
import static org.jboss.weld.logging.messages.UtilMessage.QUALIFIER_ON_FINAL_FIELD;
import static org.jboss.weld.logging.messages.UtilMessage.REDUNDANT_QUALIFIER;
import static org.jboss.weld.logging.messages.UtilMessage.TOO_MANY_POST_CONSTRUCT_METHODS;
import static org.jboss.weld.logging.messages.UtilMessage.TOO_MANY_PRE_DESTROY_METHODS;
import static org.jboss.weld.logging.messages.UtilMessage.UNABLE_TO_FIND_CONSTRUCTOR;
import static org.jboss.weld.util.reflection.Reflections.EMPTY_ANNOTATIONS;

/**
 * Helper class for bean inspection
 *
 * @author Pete Muir
 * @author David Allen
 * @author Marius Bogoevici
 * @author Ales Justin
 * @author Marko Luksa
 */
public class Beans {
    // TODO Convert messages
    private static final LocLogger log = loggerFactory().getLogger(BEAN);

    /**
     * Oracle JDK 8 compiler (unlike prev versions) generates bridge methods which have method and parameter annotations copied from the original method.
     * However such methods should not become observers, producers, disposers, initializers and lifecycle callbacks.
     *
     * This predicate determines true if the given method is not a bridge method.
     *
     * @see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6695379
     */
    @SuppressWarnings("rawtypes")
    private static final Predicate BRIDGE_METHOD_FILTER_PREDICATE = new Predicate() {
        @Override
        public boolean apply(WeldMethod method) {
            return !method.getJavaMember().isBridge();
        }
    };

    /**
     * Indicates if a bean's scope type is passivating
     *
     * @param bean The bean to inspect
     * @return True if the scope is passivating, false otherwise
     */
    public static boolean isPassivatingScope(Bean bean, BeanManagerImpl manager) {
        if (bean == null) {
            return false;
        } else if (bean instanceof SessionBean) {
            return ((SessionBean) bean).getEjbDescriptor().isStateful();
        } else {
            return manager.getServices().get(MetaAnnotationStore.class).getScopeModel(bean.getScope()).isPassivating();
        }
    }

    /**
     * Tests if a bean is capable of having its state temporarily stored to
     * secondary storage
     *
     * @param bean The bean to inspect
     * @return True if the bean is passivation capable
     */
    public static boolean isPassivationCapableBean(Bean bean) {
        if (bean instanceof RIBean) {
            return ((RIBean) bean).isPassivationCapableBean();
        } else {
            return Reflections.isSerializable(bean.getBeanClass());
        }
    }

    /**
     * Tests if a bean is capable of having its state temporarily stored to
     * secondary storage
     *
     * @param bean The bean to inspect
     * @return True if the bean is passivation capable
     */
    public static boolean isPassivationCapableDependency(Bean bean) {
        if (bean instanceof RIBean) {
            return ((RIBean) bean).isPassivationCapableDependency();
        } else {
            if (isNormalScoped(bean)) {
                return true;
            } else if (bean.getScope().equals(Dependent.class) && isPassivationCapableBean(bean)) {
                return true;
            } else {
                return false;
            }
        }
    }

    public static boolean isNormalScoped(Bean bean) {
        return Container.instance().services().get(MetaAnnotationStore.class).getScopeModel(bean.getScope()).isNormal();
    }

    /**
     * Indicates if a bean is proxyable
     *
     * @param bean The bean to test
     * @return True if proxyable, false otherwise
     */
    public static boolean isBeanProxyable(Bean bean) {
        if (bean instanceof RIBean) {
            return ((RIBean) bean).isProxyable();
        } else {
            return Proxies.isTypesProxyable(bean.getTypes());
        }
    }

    public static List>> getFieldInjectionPoints(Bean declaringBean, WeldClass weldClass) {
        if (weldClass.isModified()) {
            return getFieldInjectionPointsFromWeldFields(declaringBean, weldClass);
        } else {
            return getFieldInjectionPointsFromDeclaredFields(declaringBean, weldClass);
        }
    }

    private static List>> getFieldInjectionPointsFromWeldFields(Bean declaringBean, WeldClass weldClass) {
        Collection> allFields = weldClass.getWeldFields(Inject.class);

        List>> injectableFields = new ArrayList>>();
        Class clazz = weldClass.getJavaClass();
        while (clazz != null) {
            ArraySet> set = new ArraySet>();
            for (WeldField field : allFields) {
                Class declaringClass = field.getJavaMember().getDeclaringClass();
                if (declaringClass.equals(clazz)) {
                    addFieldInjectionPoint(declaringBean, weldClass, field, set);
                }
            }
            set.trimToSize();
            injectableFields.add(0, set);

            clazz = clazz.getSuperclass();
        }
        return injectableFields;
    }

    private static List>> getFieldInjectionPointsFromDeclaredFields(Bean declaringBean, WeldClass weldClass) {
        List>> list = new ArrayList>>();
        WeldClass c = weldClass;
        while (c != null && !c.getJavaClass().equals(Object.class)) {
            ArraySet> injectionPoints = new ArraySet>();
            for (WeldField field : c.getDeclaredWeldFields(Inject.class)) {
                addFieldInjectionPoint(declaringBean, weldClass, field, injectionPoints);
            }
            injectionPoints.trimToSize();
            list.add(0, injectionPoints);

            c = c.getWeldSuperclass();
        }
        return list;
    }

    private static void addFieldInjectionPoint(Bean declaringBean, WeldClass weldClass, WeldField field, Set> injectionPoints) {
        if (isInjectableField(field)) {
            validateInjectableField(field);
            injectionPoints.add(FieldInjectionPoint.of(declaringBean, weldClass, field));
        }
    }

    private static boolean isInjectableField(WeldField field) {
        return !field.isStatic() && !field.isAnnotationPresent(Produces.class);
    }

    private static void validateInjectableField(WeldField field) {
        if (field.isFinal()) {
            throw new DefinitionException(QUALIFIER_ON_FINAL_FIELD, field);
        }
    }

    public static Set> mergeFieldInjectionPoints(List>> fieldInjectionPoints) {
        ArraySet> injectionPoints = new ArraySet>();
        for (Set> i : fieldInjectionPoints) {
            injectionPoints.addAll(i);
        }
        return injectionPoints.trimToSize();
    }

    public static  List> getPostConstructMethods(WeldClass type) {
        WeldClass t = type;
        List> methods = new ArrayList>();
        while (!t.getJavaClass().equals(Object.class)) {
            Collection> declaredMethods = filterOutOverriddenAndBridgeMethods(type, Reflections.>>cast(t.getDeclaredWeldMethods(PostConstruct.class)));
            log.trace(FOUND_POST_CONSTRUCT_METHODS, declaredMethods, type);
            if (declaredMethods.size() > 1) {
                throw new DefinitionException(TOO_MANY_POST_CONSTRUCT_METHODS, type);
            } else if (declaredMethods.size() == 1) {
                WeldMethod method = declaredMethods.iterator().next();
                log.trace(FOUND_ONE_POST_CONSTRUCT_METHOD, method, type);
                methods.add(0, method);
            }
            t = t.getWeldSuperclass();
        }
        return methods;
    }

    private static  Collection> filterOutOverriddenAndBridgeMethods(WeldClass type, Collection> methods) {
        Collection> filteredMethods = new ArrayList>();
        for (WeldMethod method : methods) {
            if (!type.isMethodOverridden(method) && BRIDGE_METHOD_FILTER_PREDICATE.apply(method)) {
                filteredMethods.add(method);
            }
        }
        return Collections.unmodifiableCollection(filteredMethods);
    }

    public static  List> getObserverMethods(WeldClass type) {
        List> observerMethods = new ArrayList>();
        // Keep track of all seen methods so we can ignore overridden methods
        Multimap seenMethods = Multimaps.newSetMultimap(new HashMap>(),
                new Supplier>() {

                    public Set get() {
                        return new HashSet();
                    }

                });
        WeldClass t = type;
        while (t != null && !t.getJavaClass().equals(Object.class)) {
            for (WeldMethod method : Collections2.filter(t.getDeclaredWeldMethods(), BRIDGE_METHOD_FILTER_PREDICATE)) {
                if (!isOverridden(method, seenMethods) && !method.getWeldParameters(Observes.class).isEmpty()) {
                    observerMethods.add(method);
                }
                seenMethods.put(method.getSignature(), method.getPackage());
            }
            t = t.getWeldSuperclass();
        }
        return observerMethods;
    }

    public static  List> getPreDestroyMethods(WeldClass type) {
        WeldClass t = type;
        List> methods = new ArrayList>();
        while (!t.getJavaClass().equals(Object.class)) {
            Collection> declaredMethods = filterOutOverriddenAndBridgeMethods(type, Reflections.>>cast(t.getDeclaredWeldMethods(PreDestroy.class)));
            log.trace(FOUND_PRE_DESTROY_METHODS, declaredMethods, type);
            if (declaredMethods.size() > 1) {
                throw new DefinitionException(TOO_MANY_PRE_DESTROY_METHODS, type);
            } else if (declaredMethods.size() == 1) {
                WeldMethod method = declaredMethods.iterator().next();
                log.trace(FOUND_ONE_PRE_DESTROY_METHOD, method, type);
                methods.add(0, method);
            }
            t = t.getWeldSuperclass();
        }
        return methods;
    }

    public static List> getInterceptableMethods(WeldClass type) {
        List> annotatedMethods = new ArrayList>();
        for (WeldMethod annotatedMethod : type.getWeldMethods()) {
            boolean businessMethod = !annotatedMethod.isStatic()
                    && !annotatedMethod.isAnnotationPresent(Inject.class)
                    && !annotatedMethod.getJavaMember().isBridge();

            if (businessMethod && !isInterceptorMethod(annotatedMethod)) {
                annotatedMethods.add(annotatedMethod);
            }
        }
        return annotatedMethods;
    }

    private static boolean isInterceptorMethod(WeldMethod annotatedMethod) {
        for (InterceptionType interceptionType : InterceptionTypeRegistry.getSupportedInterceptionTypes()) {
            if (annotatedMethod.isAnnotationPresent(InterceptionTypeRegistry.getAnnotationClass(interceptionType)))
                return true;
        }
        return false;
    }

    public static Set> getEjbInjectionPoints(Bean declaringBean, WeldClass type, BeanManagerImpl manager) {
        if (manager.getServices().contains(EjbInjectionServices.class)) {
            Class ejbAnnotationType = manager.getServices().get(EJBApiAbstraction.class).EJB_ANNOTATION_CLASS;
            return getInjectionPoints(declaringBean, type, ejbAnnotationType);
        } else {
            return Collections.emptySet();
        }
    }

    public static Set> getPersistenceContextInjectionPoints(Bean declaringBean, WeldClass type, BeanManagerImpl manager) {
        if (manager.getServices().contains(JpaInjectionServices.class)) {
            Class persistenceContextAnnotationType = manager.getServices().get(PersistenceApiAbstraction.class).PERSISTENCE_CONTEXT_ANNOTATION_CLASS;
            return getInjectionPoints(declaringBean, type, persistenceContextAnnotationType);
        } else {
            return Collections.emptySet();
        }
    }

    public static Set> getPersistenceUnitInjectionPoints(Bean declaringBean, WeldClass type, BeanManagerImpl manager) {
        if (manager.getServices().contains(JpaInjectionServices.class)) {
            Class persistenceUnitAnnotationType = manager.getServices().get(PersistenceApiAbstraction.class).PERSISTENCE_UNIT_ANNOTATION_CLASS;
            return getInjectionPoints(declaringBean, type, persistenceUnitAnnotationType);
        } else {
            return Collections.emptySet();
        }
    }

    public static Set> getResourceInjectionPoints(Bean declaringBean, WeldClass type, BeanManagerImpl manager) {
        if (manager.getServices().contains(ResourceInjectionServices.class)) {
            Class resourceAnnotationType = manager.getServices().get(EJBApiAbstraction.class).RESOURCE_ANNOTATION_CLASS;
            return getInjectionPoints(declaringBean, type, resourceAnnotationType);
        } else {
            return Collections.emptySet();
        }
    }

    private static Set> getInjectionPoints(Bean declaringBean, WeldClass type, Class annotationType) {
        ArraySet> set = new ArraySet>();
        for (WeldField field : type.getWeldFields(annotationType)) {
            set.add(FieldInjectionPoint.of(declaringBean, type, field));
        }
        return set.trimToSize();
    }

    public static List>> getInitializerMethods(Bean declaringBean, WeldClass weldClass) {
        if (weldClass.isModified()) {
            return getInitializerMethodsFromWeldMethods(declaringBean, weldClass);
        } else {
            return getInitializerMethodsFromDeclaredMethods(declaringBean, weldClass);
        }
    }

    private static  List>> getInitializerMethodsFromWeldMethods(Bean declaringBean, WeldClass weldClass) {
        List>> initializerMethods = new ArrayList>>();

        // Keep track of all seen methods so we can ignore overridden methods
        Multimap seenMethods = Multimaps.newSetMultimap(new HashMap>(), HashSetSupplier.instance());

        Class clazz = weldClass.getJavaClass();
        while (clazz != null) {
            ArraySet> set = new ArraySet>();
            for (WeldMethod weldMethod : Collections2.filter(weldClass.getWeldMethods(), BRIDGE_METHOD_FILTER_PREDICATE)) {
                if (weldMethod.getJavaMember().getDeclaringClass().equals(clazz)) {
                    processPossibleInitializerMethod(declaringBean, weldClass, weldMethod, seenMethods, set);
                }
            }
            set.trimToSize();
            initializerMethods.add(0, set);

            clazz = clazz.getSuperclass();
        }

        return initializerMethods;
    }

    public static List>> getInitializerMethodsFromDeclaredMethods(Bean declaringBean, WeldClass weldClass) {
        List>> list = new ArrayList>>();
        // Keep track of all seen methods so we can ignore overridden methods
        Multimap seenMethods = Multimaps.newSetMultimap(new HashMap>(), HashSetSupplier.instance());
        WeldClass clazz = weldClass;
        while (clazz != null && !clazz.getJavaClass().equals(Object.class)) {
            ArraySet> set = new ArraySet>();
            Collection declaredWeldMethods = Collections2.filter(clazz.getDeclaredWeldMethods(), BRIDGE_METHOD_FILTER_PREDICATE);
            for (WeldMethod method : (Collection>) declaredWeldMethods) {
                processPossibleInitializerMethod(declaringBean, weldClass, method, seenMethods, set);
            }
            set.trimToSize();
            list.add(0, set);
            clazz = clazz.getWeldSuperclass();
        }
        return list;
    }

    private static void processPossibleInitializerMethod(Bean declaringBean, WeldClass injectionTargetClass, WeldMethod method, Multimap seenMethods, ArraySet> set) {
        if (isInitializerMethod(method)) {
            validateInitializerMethod(method, injectionTargetClass);
            if (!isOverridden(method, seenMethods)) {
                set.add(MethodInjectionPoint.of(declaringBean, method));
            }
        }
        seenMethods.put(method.getSignature(), method.getPackage());
    }

    private static boolean isInitializerMethod(WeldMethod method) {
        return method.isAnnotationPresent(Inject.class) && !method.isStatic();
    }

    private static void validateInitializerMethod(WeldMethod method, WeldClass type) {
        if (method.getAnnotation(Produces.class) != null) {
            throw new DefinitionException(INITIALIZER_CANNOT_BE_PRODUCER, method, type);
        } else if (method.getWeldParameters(Disposes.class).size() > 0) {
            throw new DefinitionException(INITIALIZER_CANNOT_BE_DISPOSAL_METHOD, method, type);
        } else if (method.getWeldParameters(Observes.class).size() > 0) {
            throw new DefinitionException(INVALID_INITIALIZER, method);
        } else if (method.isGeneric()) {
            throw new DefinitionException(INITIALIZER_METHOD_IS_GENERIC, method, type);
        }
    }

    private static boolean isOverridden(WeldMethod method, Multimap seenMethods) {
        if (method.isPrivate()) {
            return false;
        } else if (method.isPackagePrivate() && seenMethods.containsKey(method.getSignature())) {
            return seenMethods.get(method.getSignature()).contains(method.getPackage());
        } else {
            return seenMethods.containsKey(method.getSignature());
        }
    }

    public static Set> getParameterInjectionPoints(Bean declaringBean, WeldConstructor constructor) {
        ArraySet> injectionPoints = new ArraySet>();
        for (WeldParameter parameter : constructor.getWeldParameters()) {
            injectionPoints.add(ParameterInjectionPoint.of(declaringBean, parameter));
        }
        return injectionPoints.trimToSize();
    }

    public static Set> getParameterInjectionPoints(Bean declaringBean, MethodInjectionPoint method) {
        ArraySet> injectionPoints = new ArraySet>();
        for (WeldParameter parameter : method.getWeldParameters()) {
            if (parameter.isAnnotationPresent(Disposes.class)) {
                continue; // disposes parameter is not an injection point
            }
            injectionPoints.add(ParameterInjectionPoint.of(declaringBean, parameter));
        }
        return injectionPoints.trimToSize();
    }

    public static Set> getParameterInjectionPoints(Bean declaringBean, List>> methodInjectionPoints) {
        ArraySet> injectionPoints = new ArraySet>();
        for (Set> i : methodInjectionPoints) {
            for (MethodInjectionPoint method : i) {
                for (WeldParameter parameter : method.getWeldParameters()) {
                    injectionPoints.add(ParameterInjectionPoint.of(declaringBean, parameter));
                }
            }
        }
        return injectionPoints.trimToSize();
    }

    /**
     * Checks that all the qualifiers in the set requiredQualifiers are in the set
     * of qualifiers. Qualifier equality rules for annotation members are followed.
     *
     * @param requiredQualifiers The required qualifiers
     * @param qualifiers         The set of qualifiers to check
     * @return True if all matches, false otherwise
     */
    public static boolean containsAllQualifiers(Set requiredQualifiers, Set qualifiers, BeanManagerImpl beanManager) {
        return qualifiers.containsAll(requiredQualifiers);
    }

    public static boolean containsAllInterceptionBindings(Set expectedBindings, Set existingBindings, BeanManagerImpl manager) {
        final Set expected = manager.extractInterceptorBindingsForQualifierInstance(QualifierInstance.qualifiers(manager, expectedBindings));
        return manager.extractInterceptorBindingsForQualifierInstance(existingBindings).containsAll(expected);
    }

    public static boolean findInterceptorBindingConflicts(Set flattenedBindings) {
        Map, InterceptorBindingType> foundAnnotations = new HashMap, InterceptorBindingType>();
        for (InterceptorBindingType binding : flattenedBindings) {
            if (foundAnnotations.containsKey(binding.annotationType())) {
                if (!binding.equals(foundAnnotations.get(binding.annotationType()))) {
                    return true;
                }
            } else {
                foundAnnotations.put(binding.annotationType(), binding);
            }
        }
        return false;
    }

    /**
     * Retains only beans which have deployment type X.
     * 

* The deployment type X is * * @param beans The beans to filter * @param beanManager the bean manager * @return The filtered beans */ public static > Set removeDisabledAndSpecializedBeans(Set beans, BeanManagerImpl beanManager) { if (beans.size() == 0) { return beans; } else { Set result = new HashSet(); for (T bean : beans) { if (isBeanEnabled(bean, beanManager.getEnabled()) && !isSpecialized(bean, beans, beanManager) && !isSuppressedBySpecialization(bean, beanManager)) { result.add(bean); } } return result; } } public static boolean isBeanEnabled(Bean bean, Enabled enabled) { if (bean.isAlternative()) { if (enabled.getAlternativeClass(bean.getBeanClass()) != null) { return true; } else { for (Class stereotype : bean.getStereotypes()) { if (enabled.getAlternativeStereotype(stereotype) != null) { return true; } } return false; } } else if (bean instanceof AbstractReceiverBean) { AbstractReceiverBean receiverBean = (AbstractReceiverBean) bean; return isBeanEnabled(receiverBean.getDeclaringBean(), enabled); } else if (bean instanceof DecoratorImpl) { return enabled.getDecorator(bean.getBeanClass()) != null; } else if (bean instanceof InterceptorImpl) { return enabled.getInterceptor(bean.getBeanClass()) != null; } else { return true; } } /** * Check if any of the beans is an alternative * * @param beans the beans to check * @return true if any bean is an alternative */ public static boolean isAlternativePresent(Set> beans) { for (Bean bean : beans) { if (bean.isAlternative()) { return true; } } return false; } /** * Is alternative. * * @param annotated the annotated * @param mergedStereotypes merged stereotypes * @return true if alternative, false otherwise */ public static boolean isAlternative(WeldAnnotated annotated, MergedStereotypes mergedStereotypes) { return annotated.isAnnotationPresent(Alternative.class) || mergedStereotypes.isAlternative(); } /** * Check if bean is specialized by any of beans * * @param bean the bean to check * @param beanManager bean manager * @return true if bean is specialized by some bean in all beans */ public static > boolean isSpecialized(T bean, BeanManagerImpl beanManager) { BeansClosure closure = beanManager.getClosure(); return closure.isSpecialized(bean); } /** * Check if bean is specialized by any of beans * * @param bean the bean to check * @param beans the possible specialized beans * @param beanManager bean manager * @return true if bean is specialized by some bean in beans */ public static > boolean isSpecialized(T bean, Set beans, BeanManagerImpl beanManager) { BeansClosure closure = beanManager.getClosure(); Bean specializingBean = closure.getSpecializingBean(bean); //noinspection SuspiciousMethodCalls return (specializingBean != null && beans.contains(specializingBean)); } /** * Check if the given producer/disposer method of producer field is defined on a specialized bean and is therefore disabled. */ public static boolean isSuppressedBySpecialization(Bean bean, BeanManagerImpl manager) { if (bean instanceof AbstractReceiverBean) { BeansClosure closure = manager.getClosure(); if (closure.isSpecialized(Reflections.>cast(bean).getDeclaringBean())) { // if a bean is specialized, its producer methods are not enabled (WELD-977) return true; } } return false; } public static ConstructorInjectionPoint getBeanConstructor(Bean declaringBean, WeldClass type) { ConstructorInjectionPoint constructor = null; Collection> initializerAnnotatedConstructors = type.getWeldConstructors(Inject.class); log.trace(FOUND_INJECTABLE_CONSTRUCTORS, initializerAnnotatedConstructors, type); if (initializerAnnotatedConstructors.size() > 1) { if (initializerAnnotatedConstructors.size() > 1) { throw new DefinitionException(AMBIGUOUS_CONSTRUCTOR, type, initializerAnnotatedConstructors); } } else if (initializerAnnotatedConstructors.size() == 1) { constructor = ConstructorInjectionPoint.of(declaringBean, initializerAnnotatedConstructors.iterator().next()); log.trace(FOUND_ONE_INJECTABLE_CONSTRUCTOR, constructor, type); } else if (type.getNoArgsWeldConstructor() != null) { constructor = ConstructorInjectionPoint.of(declaringBean, type.getNoArgsWeldConstructor()); log.trace(FOUND_DEFAULT_CONSTRUCTOR, constructor, type); } if (constructor == null) { throw new DefinitionException(UNABLE_TO_FIND_CONSTRUCTOR, type); } else { return constructor; } } /** * Injects EJBs and common fields */ public static void injectEEFields(T beanInstance, BeanManagerImpl manager, Iterable> ejbInjectionPoints, Iterable> persistenceContextInjectionPoints, Iterable> persistenceUnitInjectionPoints, Iterable> resourceInjectionPoints) { EjbInjectionServices ejbServices = manager.getServices().get(EjbInjectionServices.class); JpaInjectionServices jpaServices = manager.getServices().get(JpaInjectionServices.class); ResourceInjectionServices resourceServices = manager.getServices().get(ResourceInjectionServices.class); if (ejbServices != null) { for (WeldInjectionPoint injectionPoint : ejbInjectionPoints) { Object ejbInstance = ejbServices.resolveEjb(injectionPoint); injectionPoint.inject(beanInstance, ejbInstance); } } if (jpaServices != null) { for (WeldInjectionPoint injectionPoint : persistenceContextInjectionPoints) { Object pcInstance = jpaServices.resolvePersistenceContext(injectionPoint); injectionPoint.inject(beanInstance, pcInstance); } for (WeldInjectionPoint injectionPoint : persistenceUnitInjectionPoints) { Object puInstance = jpaServices.resolvePersistenceUnit(injectionPoint); injectionPoint.inject(beanInstance, puInstance); } } if (resourceServices != null) { for (WeldInjectionPoint injectionPoint : resourceInjectionPoints) { Object resourceInstance = resourceServices.resolveResource(injectionPoint); injectionPoint.inject(beanInstance, resourceInstance); } } } /** * Inspect an injection point, and try to retrieve a EE resource for it */ public static Object resolveEEResource(BeanManagerImpl manager, WeldInjectionPoint injectionPoint) { EjbInjectionServices ejbServices = manager.getServices().get(EjbInjectionServices.class); JpaInjectionServices jpaServices = manager.getServices().get(JpaInjectionServices.class); ResourceInjectionServices resourceServices = manager.getServices().get(ResourceInjectionServices.class); if (ejbServices != null) { Class ejbAnnotationType = manager.getServices().get(EJBApiAbstraction.class).EJB_ANNOTATION_CLASS; if (injectionPoint.isAnnotationPresent(ejbAnnotationType)) { return ejbServices.resolveEjb(injectionPoint); } } if (jpaServices != null) { final PersistenceApiAbstraction persistenceApiAbstraction = manager.getServices().get(PersistenceApiAbstraction.class); Class persistenceUnitAnnotationType = persistenceApiAbstraction.PERSISTENCE_UNIT_ANNOTATION_CLASS; if (injectionPoint.isAnnotationPresent(persistenceUnitAnnotationType)) { return jpaServices.resolvePersistenceUnit(injectionPoint); } Class persistenceContextAnnotationType = persistenceApiAbstraction.PERSISTENCE_CONTEXT_ANNOTATION_CLASS; if (injectionPoint.isAnnotationPresent(persistenceContextAnnotationType)) { return jpaServices.resolvePersistenceContext(injectionPoint); } } if (resourceServices != null) { Class resourceAnnotationType = manager.getServices().get(EJBApiAbstraction.class).RESOURCE_ANNOTATION_CLASS; if (injectionPoint.isAnnotationPresent(resourceAnnotationType)) { return resourceServices.resolveResource(injectionPoint); } } return null; } /** * Gets the declared bean type * * @return The bean type */ public static Type getDeclaredBeanType(Class clazz) { Type[] actualTypeArguments = Reflections.getActualTypeArguments(clazz); if (actualTypeArguments.length == 1) { return actualTypeArguments[0]; } else { return null; } } /** * Injects bound fields * * @param instance The instance to inject into */ public static void injectBoundFields(T instance, CreationalContext creationalContext, BeanManagerImpl manager, Iterable> injectableFields) { for (FieldInjectionPoint injectableField : injectableFields) { injectableField.inject(instance, manager, creationalContext); } } public static void injectFieldsAndInitializers(T instance, CreationalContext ctx, BeanManagerImpl beanManager, List>> injectableFields, List>> initializerMethods) { if (injectableFields.size() != initializerMethods.size()) { throw new IllegalArgumentException(INVALID_QUANTITY_INJECTABLE_FIELDS_AND_INITIALIZER_METHODS, injectableFields, initializerMethods); } for (int i = 0; i < injectableFields.size(); i++) { injectBoundFields(instance, ctx, beanManager, injectableFields.get(i)); callInitializers(instance, ctx, beanManager, initializerMethods.get(i)); } } /** * Calls all initializers of the bean * * @param instance The bean instance */ public static void callInitializers(T instance, CreationalContext creationalContext, BeanManagerImpl manager, Iterable> initializerMethods) { for (MethodInjectionPoint initializer : initializerMethods) { initializer.invoke(instance, manager, creationalContext, CreationException.class); } } public static boolean isInterceptor(WeldClass annotatedItem) { return annotatedItem.isAnnotationPresent(javax.interceptor.Interceptor.class); } public static boolean isDecorator(WeldClass annotatedItem) { return annotatedItem.isAnnotationPresent(Decorator.class); } public static Annotation[] mergeInQualifiers(Annotation[] qualifiers, Annotation[] newQualifiers) { if (qualifiers == null || newQualifiers == null) return EMPTY_ANNOTATIONS; return mergeInQualifiers(asList(qualifiers), newQualifiers).toArray(Reflections.EMPTY_ANNOTATIONS); } public static Set mergeInQualifiers(Collection qualifiers, Annotation[] newQualifiers) { Set result = new HashSet(); if (qualifiers != null && qualifiers.isEmpty() == false) result.addAll(qualifiers); if (newQualifiers != null && newQualifiers.length > 0) { final MetaAnnotationStore store = Container.instance().services().get(MetaAnnotationStore.class); Set checkedNewQualifiers = new HashSet(); for (Annotation qualifier : newQualifiers) { if (!store.getBindingTypeModel(qualifier.annotationType()).isValid()) { throw new IllegalArgumentException(ANNOTATION_NOT_QUALIFIER, qualifier); } if (checkedNewQualifiers.contains(qualifier)) { throw new IllegalArgumentException(REDUNDANT_QUALIFIER, qualifier, Arrays.asList(newQualifiers)); } checkedNewQualifiers.add(qualifier); } result.addAll(checkedNewQualifiers); } return result; } public static InjectionPoint getDelegateInjectionPoint(javax.enterprise.inject.spi.Decorator decorator) { if (decorator instanceof DecoratorImpl) { return ((DecoratorImpl) decorator).getDelegateInjectionPoint(); } else { for (InjectionPoint injectionPoint : decorator.getInjectionPoints()) { if (injectionPoint.isDelegate()) return injectionPoint; } } return null; } /** * * @param weldClass * @return a set of producer methods, bridge methods are filtered out */ public static Collection> getProducerMethods(WeldClass weldClass) { return Collections2.filter(weldClass.getDeclaredWeldMethods(Produces.class), BRIDGE_METHOD_FILTER_PREDICATE); } /** * * @param weldClass * @return a set of disposer methods, bridge methods are filtered out */ public static Collection> getDisposerMethods(WeldClass weldClass) { return Collections2.filter(weldClass.getDeclaredWeldMethodsWithAnnotatedParameters(Disposes.class), BRIDGE_METHOD_FILTER_PREDICATE); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy