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 static org.jboss.weld.util.reflection.Reflections.cast;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.decorator.Decorator;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.context.spi.Contextual;
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.Typed;
import javax.enterprise.inject.Vetoed;
import javax.enterprise.inject.spi.AnnotatedConstructor;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanAttributes;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.inject.Inject;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotated;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedConstructor;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.slim.SlimAnnotatedTypeStore;
import org.jboss.weld.bean.AbstractProducerBean;
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.bootstrap.api.ServiceRegistry;
import org.jboss.weld.bootstrap.enablement.ModuleEnablement;
import org.jboss.weld.ejb.InternalEjbDescriptor;
import org.jboss.weld.ejb.spi.BusinessInterfaceDescriptor;
import org.jboss.weld.ejb.spi.EjbDescriptor;
import org.jboss.weld.injection.FieldInjectionPoint;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.injection.ResourceInjection;
import org.jboss.weld.interceptor.spi.model.InterceptionType;
import org.jboss.weld.interceptor.util.InterceptionTypeRegistry;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.logging.MetadataLogger;
import org.jboss.weld.logging.UtilLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.metadata.cache.InterceptorBindingModel;
import org.jboss.weld.metadata.cache.MergedStereotypes;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
import org.jboss.weld.resolution.QualifierInstance;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.resources.spi.ClassFileInfo;
import org.jboss.weld.serialization.spi.BeanIdentifier;
import org.jboss.weld.serialization.spi.ContextualStore;
import org.jboss.weld.util.bytecode.BytecodeUtils;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.HierarchyDiscovery;
import org.jboss.weld.util.reflection.Reflections;
import org.jboss.weld.util.reflection.SessionBeanHierarchyDiscovery;


/**
 * Helper class for bean inspection
 *
 * @author Pete Muir
 * @author David Allen
 * @author Marius Bogoevici
 * @author Ales Justin
 * @author Jozef Hartinger
 */
public class Beans {

    private Beans() {
    }

    /**
     * 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 {
            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 bean instanceof PassivationCapable;
        }
    }

    /**
     * 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();
        }
        return bean instanceof PassivationCapable;
    }

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

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

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

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

    /**
     * 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) {
        return qualifiers.containsAll(requiredQualifiers);
    }

    public static boolean containsAllInterceptionBindings(Set expectedBindings,
            Set existingBindings, BeanManagerImpl manager) {
        final Set expected = manager.extractInterceptorBindingsForQualifierInstance(QualifierInstance.of(expectedBindings, manager.getServices().get(MetaAnnotationStore.class)));
        return manager.extractInterceptorBindingsForQualifierInstance(existingBindings).containsAll(expected);
    }

    public static boolean findInterceptorBindingConflicts(BeanManagerImpl manager, Set bindings) {
        Map, Annotation> foundAnnotations = new HashMap, Annotation>();
        for (Annotation binding : bindings) {
            if (foundAnnotations.containsKey(binding.annotationType())) {
                InterceptorBindingModel bindingType = manager.getServices().get(MetaAnnotationStore.class)
                        .getInterceptorBindingModel(binding.annotationType());
                if (!bindingType.isEqual(binding, foundAnnotations.get(binding.annotationType()), false)) {
                    return true;
                }
            } else {
                foundAnnotations.put(binding.annotationType(), binding);
            }
        }
        return false;
    }

    /**
     * Retains only beans which are enabled.
     *
     * @param beans The mutable set of beans to filter
     * @param beanManager The bean manager
     * @return An immutable set of enabled beans
     */
    public static > Set removeDisabledBeans(Set beans, final BeanManagerImpl beanManager) {
        if (beans.isEmpty()) {
            return beans;
        } else {
            for (Iterator iterator = beans.iterator(); iterator.hasNext();) {
                if (!isBeanEnabled(iterator.next(), beanManager.getEnabled())) {
                    iterator.remove();
                }
            }
            return beans;
        }
    }

    public static boolean isBeanEnabled(Bean bean, ModuleEnablement enabled) {
        if (bean.isAlternative()) {
            if (enabled.isEnabledAlternativeClass(bean.getBeanClass())) {
                return true;
            } else {
                for (Class stereotype : bean.getStereotypes()) {
                    if (enabled.isEnabledAlternativeStereotype(stereotype)) {
                        return true;
                    }
                }
                return false;
            }
        } else if (bean instanceof AbstractProducerBean) {
            AbstractProducerBean receiverBean = (AbstractProducerBean) bean;
            return isBeanEnabled(receiverBean.getDeclaringBean(), enabled);
        } else if (bean instanceof DecoratorImpl) {
            return enabled.isDecoratorEnabled(bean.getBeanClass());
        } else if (bean instanceof InterceptorImpl) {
            return enabled.isInterceptorEnabled(bean.getBeanClass());
        } else {
            return true;
        }
    }

    /**
     * Is alternative.
     *
     * @param annotated the annotated
     * @param mergedStereotypes merged stereotypes
     * @return true if alternative, false otherwise
     */
    public static boolean isAlternative(EnhancedAnnotated annotated, MergedStereotypes mergedStereotypes) {
        return annotated.isAnnotationPresent(Alternative.class) || mergedStereotypes.isAlternative();
    }

    public static  EnhancedAnnotatedConstructor getBeanConstructorStrict(EnhancedAnnotatedType type) {
        EnhancedAnnotatedConstructor constructor = getBeanConstructor(type);
        if (constructor == null) {
            throw UtilLogger.LOG.unableToFindConstructor(type);
        }
        return constructor;
    }

    public static  EnhancedAnnotatedConstructor getBeanConstructor(EnhancedAnnotatedType type) {
        Collection> initializerAnnotatedConstructors = type
                .getEnhancedConstructors(Inject.class);
        BeanLogger.LOG.foundInjectableConstructors(initializerAnnotatedConstructors, type);
        EnhancedAnnotatedConstructor constructor = null;
        if (initializerAnnotatedConstructors.size() > 1) {
            throw UtilLogger.LOG.ambiguousConstructor(type, initializerAnnotatedConstructors);
        } else if (initializerAnnotatedConstructors.size() == 1) {
            constructor = initializerAnnotatedConstructors.iterator().next();
            BeanLogger.LOG.foundOneInjectableConstructor(constructor, type);
        } else if (type.getNoArgsEnhancedConstructor() != null) {
            constructor = type.getNoArgsEnhancedConstructor();
            BeanLogger.LOG.foundDefaultConstructor(constructor, type);
        }
        if (constructor != null) {
            if (!constructor.getEnhancedParameters(Disposes.class).isEmpty()) {
                throw BeanLogger.LOG.parameterAnnotationNotAllowedOnConstructor("@Disposes", constructor,
                        Formats.formatAsStackTraceElement(constructor.getJavaMember()));
            }
            if (!constructor.getEnhancedParameters(Observes.class).isEmpty()) {
                throw BeanLogger.LOG.parameterAnnotationNotAllowedOnConstructor("@Observes", constructor,
                        Formats.formatAsStackTraceElement(constructor.getJavaMember()));
            }
        }
        return constructor;
    }

    /**
     * Injects EJBs and other EE resources.
     *
     * @param resourceInjectionsHierarchy
     * @param beanInstance
     * @param ctx
     */
    public static  void injectEEFields(Iterable>> resourceInjectionsHierarchy,
            T beanInstance, CreationalContext ctx) {
        for (Set> resourceInjections : resourceInjectionsHierarchy) {
            for (ResourceInjection resourceInjection : resourceInjections) {
                resourceInjection.injectResourceReference(beanInstance, ctx);
            }
        }
    }

    /**
     * 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 UtilLogger.LOG.invalidQuantityInjectableFieldsAndInitializerMethods(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, null, manager, creationalContext, CreationException.class);
        }
    }

    public static  boolean isInterceptor(AnnotatedType annotatedItem) {
        return annotatedItem.isAnnotationPresent(javax.interceptor.Interceptor.class);
    }

    public static  boolean isDecorator(EnhancedAnnotatedType annotatedItem) {
        return annotatedItem.isAnnotationPresent(Decorator.class);
    }

    public static Set mergeInQualifiers(BeanManagerImpl manager, Collection qualifiers, Annotation[] newQualifiers) {
        Set result = new HashSet();

        if (qualifiers != null && !(qualifiers.isEmpty())) {
            result.addAll(qualifiers);
        }
        if (newQualifiers != null && newQualifiers.length > 0) {
            final MetaAnnotationStore store = manager.getServices().get(MetaAnnotationStore.class);
            Set checkedNewQualifiers = new HashSet();
            for (Annotation qualifier : newQualifiers) {
                if (!store.getBindingTypeModel(qualifier.annotationType()).isValid()) {
                    throw UtilLogger.LOG.annotationNotQualifier(qualifier);
                }
                final Class annotationType = qualifier.annotationType();
                for (Annotation annotation : checkedNewQualifiers) {
                    if(annotationType.equals(annotation.annotationType())) {
                        throw UtilLogger.LOG.redundantQualifier(qualifier, Arrays.toString(newQualifiers));
                    }
                }
                checkedNewQualifiers.add(qualifier);
            }
            result.addAll(checkedNewQualifiers);
        }
        return result;
    }

    /**
     * Illegal bean types are ignored except fo array and primitive types and unless {@link Typed} is used.
     *
     * @return the set of bean types from an annotated element
     */
    public static Set getTypes(EnhancedAnnotated annotated) {
        // array and primitive types require special treatment
        if (annotated.getJavaClass().isArray() || annotated.getJavaClass().isPrimitive()) {
            return ImmutableSet.builder().addAll(annotated.getBaseType(), Object.class).build();
        } else {
            if (annotated.isAnnotationPresent(Typed.class)) {
                return ImmutableSet.builder().addAll(getTypedTypes(Reflections.buildTypeMap(annotated.getTypeClosure()),
                        annotated.getJavaClass(), annotated.getAnnotation(Typed.class))).build();
            } else {
                if (annotated.getJavaClass().isInterface()) {
                    return getLegalBeanTypes(annotated.getTypeClosure(), annotated, Object.class);
                }
                return getLegalBeanTypes(annotated.getTypeClosure(), annotated);
            }
        }
    }

    /**
     * Bean types of a session bean.
     */
    public static  Set getTypes(EnhancedAnnotated annotated, EjbDescriptor ejbDescriptor) {
        ImmutableSet.Builder types = ImmutableSet.builder();
        // session beans
        Map, Type> typeMap = new LinkedHashMap, Type>();
        HierarchyDiscovery beanClassDiscovery = HierarchyDiscovery.forNormalizedType(ejbDescriptor.getBeanClass());
        for (BusinessInterfaceDescriptor businessInterfaceDescriptor : ejbDescriptor.getLocalBusinessInterfaces()) {
            // first we need to resolve the local interface
            Type resolvedLocalInterface = beanClassDiscovery.resolveType(Types.getCanonicalType(businessInterfaceDescriptor.getInterface()));
            SessionBeanHierarchyDiscovery interfaceDiscovery = new SessionBeanHierarchyDiscovery(resolvedLocalInterface);
            if (beanClassDiscovery.getTypeMap().containsKey(businessInterfaceDescriptor.getInterface())) {
                // WELD-1675 Only add types also included in Annotated.getTypeClosure()
                for (Entry, Type> entry : interfaceDiscovery.getTypeMap().entrySet()) {
                    if (annotated.getTypeClosure().contains(entry.getValue())) {
                        typeMap.put(entry.getKey(), entry.getValue());
                    }
                }
            } else {
                // Session bean class does not implement the business interface and @javax.ejb.Local applied to the session bean class
                typeMap.putAll(interfaceDiscovery.getTypeMap());
            }
        }
        if (annotated.isAnnotationPresent(Typed.class)) {
            types.addAll(getTypedTypes(typeMap, annotated.getJavaClass(), annotated.getAnnotation(Typed.class)));
        } else {
            typeMap.put(Object.class, Object.class);
            types.addAll(typeMap.values());
        }
        return getLegalBeanTypes(types.build(), annotated);
    }

    /**
     * Bean types of a bean that uses the {@link Typed} annotation.
     */
    public static Set getTypedTypes(Map, Type> typeClosure, Class rawType, Typed typed) {
        Set types = new HashSet();
        for (Class specifiedClass : typed.value()) {
            Type tmp = typeClosure.get(specifiedClass);
            if (tmp != null) {
                types.add(tmp);
            } else {
                throw BeanLogger.LOG.typedClassNotInHierarchy(specifiedClass.getName(), rawType, Formats.formatTypes(typeClosure.values()));
            }
        }
        types.add(Object.class);
        return types;
    }

    /**
     * Indicates if the type is a simple Web Bean
     *
     * @param clazz The type to inspect
     * @return True if simple Web Bean, false otherwise
     */
    public static boolean isTypeManagedBeanOrDecoratorOrInterceptor(AnnotatedType annotatedType) {
        Class javaClass = annotatedType.getJavaClass();
        return !javaClass.isEnum() && !Extension.class.isAssignableFrom(javaClass)
                && Reflections.isTopLevelOrStaticNestedClass(javaClass) && !Reflections.isParameterizedTypeWithWildcard(javaClass)
                && hasSimpleCdiConstructor(annotatedType);
    }

    /**
     *
     * @param classFileInfo
     * @param checkTypeModifiers - this flag reflects whether Jandex version including fix for JANDEX-37 could be used
     * @return
     */
    public static boolean isTypeManagedBeanOrDecoratorOrInterceptor(ClassFileInfo classFileInfo, boolean checkTypeModifiers) {

        boolean isTypeManagedBean = ((classFileInfo.getModifiers() & BytecodeUtils.ENUM) == 0) && !classFileInfo.isAssignableTo(Extension.class)
                && classFileInfo.hasCdiConstructor()
                && (!Modifier.isAbstract(classFileInfo.getModifiers()) || classFileInfo.isAnnotationDeclared(Decorator.class));
        if (checkTypeModifiers) {
            return isTypeManagedBean && (classFileInfo.isTopLevelClass() || Modifier.isStatic(classFileInfo.getModifiers()));
        } else {
            return isTypeManagedBean;
        }
    }

    public static boolean isDecoratorDeclaringInAppropriateConstructor(ClassFileInfo classFileInfo) {
        return !classFileInfo.hasCdiConstructor() && classFileInfo.isAnnotationDeclared(Decorator.class);
    }

    public static boolean isDecoratorDeclaringInAppropriateConstructor(AnnotatedType annotatedType) {
        return !hasSimpleCdiConstructor(annotatedType) && annotatedType.isAnnotationPresent(Decorator.class);
    }

    public static boolean hasSimpleCdiConstructor(AnnotatedType type) {
        for (AnnotatedConstructor constructor : type.getConstructors()) {
            if (constructor.getParameters().isEmpty()) {
                return true;
            }
            if (constructor.isAnnotationPresent(Inject.class)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Determines if this Java class should be vetoed as a result of presence of {@link Veto} annotations.
     */
    public static boolean isVetoed(Class javaClass) {
        if (javaClass.isAnnotationPresent(Vetoed.class)) {
            return true;
        }
        return isPackageVetoed(javaClass.getPackage());
    }

    public static boolean isVetoed(AnnotatedType type) {
        if (type.isAnnotationPresent(Vetoed.class)) {
            return true;
        }
        return isPackageVetoed(type.getJavaClass().getPackage());
    }

    private static boolean isPackageVetoed(Package pkg) {
        return pkg != null && pkg.isAnnotationPresent(Vetoed.class);
    }

    /**
     * Generates a unique signature for {@link BeanAttributes}.
     */
    public static String createBeanAttributesId(BeanAttributes attributes) {
        StringBuilder builder = new StringBuilder();
        builder.append(attributes.getName());
        builder.append(",");
        builder.append(attributes.getScope().getName());
        builder.append(",");
        builder.append(attributes.isAlternative());
        builder.append(AnnotatedTypes.createAnnotationCollectionId(attributes.getQualifiers()));
        builder.append(createTypeCollectionId(attributes.getStereotypes()));
        builder.append(createTypeCollectionId(attributes.getTypes()));
        return builder.toString();
    }

    /**
     * Generates a unique signature of a collection of types.
     */
    public static String createTypeCollectionId(Collection types) {
        StringBuilder builder = new StringBuilder();
        List sortedTypes = new ArrayList(types);
        Collections.sort(sortedTypes, TypeComparator.INSTANCE);
        builder.append("[");
        for (Iterator iterator = sortedTypes.iterator(); iterator.hasNext();) {
            builder.append(createTypeId(iterator.next()));
            if (iterator.hasNext()) {
                builder.append(",");
            }
        }
        builder.append("]");
        return builder.toString();
    }

    /**
     * Creates a unique signature for a {@link Type}.
     */
    private static String createTypeId(Type type) {
        if (type instanceof Class) {
            return Reflections.> cast(type).getName();
        }
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            StringBuilder builder = new StringBuilder();
            builder.append(createTypeId(parameterizedType.getRawType()));
            builder.append("<");
            for (int i = 0; i < parameterizedType.getActualTypeArguments().length; i++) {
                builder.append(createTypeId(parameterizedType.getActualTypeArguments()[i]));
                if (i != parameterizedType.getActualTypeArguments().length - 1) {
                    builder.append(",");
                }
            }
            builder.append(">");
            return builder.toString();
        }
        if (type instanceof TypeVariable) {
            return Reflections.> cast(type).getName();
        }
        if (type instanceof GenericArrayType) {
            return createTypeId(Reflections. cast(type).getGenericComponentType());
        }
        throw new java.lang.IllegalArgumentException("Unknown type " + type);
    }

    private static class TypeComparator implements Comparator, Serializable {
        private static final long serialVersionUID = -2162735176891985078L;
        private static final TypeComparator INSTANCE = new TypeComparator();

        @Override
        public int compare(Type o1, Type o2) {
            return createTypeId(o1).compareTo(createTypeId(o2));
        }
    }

    public static > X checkEnhancedAnnotatedAvailable(X enhancedAnnotated) {
        if (enhancedAnnotated == null) {
            throw new IllegalStateException("Enhanced metadata should not be used at runtime.");
        }
        return enhancedAnnotated;
    }

    public static boolean hasBuiltinScope(Bean bean) {
        return RequestScoped.class.equals(bean.getScope()) || SessionScoped.class.equals(bean.getScope()) || ApplicationScoped.class.equals(bean.getScope())
                || ConversationScoped.class.equals(bean.getScope()) || Dependent.class.equals(bean.getScope());
    }

    public static Class getBeanDefiningAnnotationScope(AnnotatedType annotatedType) {
        for (Annotation annotation : annotatedType.getAnnotations()) {
            if (annotation.annotationType().isAnnotationPresent(NormalScope.class) || annotation.annotationType().equals(Dependent.class)) {
                return annotation.annotationType();
            }
        }
        return null;
    }

    /**
     * Returns {@link EnhancedAnnotatedType} for the EJB implementation class. Throws {@link IllegalStateException} if called after bootstrap.
     * @param bean
     * @throws IllegalStateException if called after bootstrap
     * @return {@link EnhancedAnnotatedType} representation of this EJB's implementation class
     */
    public static  EnhancedAnnotatedType getEjbImplementationClass(SessionBean bean) {
        return getEjbImplementationClass(bean.getEjbDescriptor(), bean.getBeanManager(), bean.getEnhancedAnnotated());
    }

    public static  EnhancedAnnotatedType getEjbImplementationClass(InternalEjbDescriptor ejbDescriptor, BeanManagerImpl manager, EnhancedAnnotatedType componentType) {
        if (ejbDescriptor.getBeanClass().equals(ejbDescriptor.getImplementationClass())) {
            // no special implementation class is used
            return componentType;
        }
        ClassTransformer transformer = manager.getServices().get(ClassTransformer.class);
        EnhancedAnnotatedType implementationClass = cast(transformer.getEnhancedAnnotatedType(ejbDescriptor.getImplementationClass(), manager.getId()));
        manager.getServices().get(SlimAnnotatedTypeStore.class).put(implementationClass.slim());
        return implementationClass;
    }

    /**
     *
     * @param types The initial set of types
     * @param annotated
     * @param additionalTypes Types to add to the initial set
     * @return the set of legal bean types
     */
    static Set getLegalBeanTypes(Set types, EnhancedAnnotated annotated, Type... additionalTypes) {
        if (additionalTypes != null && additionalTypes.length > 0) {
            // Micro-optimization is not possible
            return omitIllegalBeanTypes(types, annotated).addAll(additionalTypes).build();
        }
        for (Type type : types) {
            if (Types.isIllegalBeanType(type)) {
                return omitIllegalBeanTypes(types, annotated).build();
            }
        }
        return types;
    }

    static ImmutableSet.Builder omitIllegalBeanTypes(Set types, EnhancedAnnotated annotated) {
        ImmutableSet.Builder builder = ImmutableSet.builder();
        for (Type type : types) {
            if (Types.isIllegalBeanType(type)) {
                MetadataLogger.LOG.illegalBeanTypeIgnored(type, annotated);
            } else {
                builder.add(type);
            }
        }
        return builder;
    }

    /**
     * @param contextual
     * @param contextualStore
     * @return the identifier for the given contextual
     * @see #getIdentifier(Contextual, ContextualStore, ServiceRegistry)
     */
    public static BeanIdentifier getIdentifier(Contextual contextual, ContextualStore contextualStore) {
        return getIdentifier(contextual, contextualStore, null);
    }

    /**
     * @param contextual
     * @param serviceRegistry
     * @return the identifier for the given contextual
     * @see #getIdentifier(Contextual, ContextualStore, ServiceRegistry)
     */
    public static BeanIdentifier getIdentifier(Contextual contextual, ServiceRegistry serviceRegistry) {
        return getIdentifier(contextual, null, serviceRegistry);
    }

    /**
     * A slightly optimized way to get the bean identifier - there is not need to call ContextualStore.putIfAbsent() for passivation capable beans because it's
     * already called during bootstrap. See also {@link BeanManagerImpl#addBean(Bean)}.
     *
     * @param contextual
     * @param contextualStore
     * @param serviceRegistry
     * @return the identifier for the given contextual
     */
    private static BeanIdentifier getIdentifier(Contextual contextual, ContextualStore contextualStore, ServiceRegistry serviceRegistry) {
        if (contextual instanceof RIBean) {
            return ((RIBean) contextual).getIdentifier();
        }
        if (contextualStore == null) {
            contextualStore = serviceRegistry.get(ContextualStore.class);
        }
        return contextualStore.putIfAbsent(contextual);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy