Package org.jboss.weld.util

Source Code of org.jboss.weld.util.Decorators

/*
* 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.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.PassivationCapable;
import javax.inject.Inject;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedType;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.annotated.runtime.InvokableAnnotatedMethod;
import org.jboss.weld.bean.CustomDecoratorWrapper;
import org.jboss.weld.bean.DecoratorImpl;
import org.jboss.weld.bean.WeldDecorator;
import org.jboss.weld.bean.proxy.DecorationHelper;
import org.jboss.weld.bean.proxy.TargetBeanInstance;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.exceptions.IllegalStateException;
import org.jboss.weld.exceptions.WeldException;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.injection.attributes.WeldInjectionPointAttributes;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.resources.ClassTransformer;
import org.jboss.weld.serialization.spi.ContextualStore;
import org.jboss.weld.util.collections.ImmutableSet;
import org.jboss.weld.util.reflection.HierarchyDiscovery;
import org.jboss.weld.util.reflection.Reflections;

/**
* Helper class for {@link javax.enterprise.inject.spi.Decorator} inspections.
*
* @author Marius Bogoevici
*/
public class Decorators {

    private Decorators() {
    }

    /**
     * Determines the set of {@link InvokableAnnotatedMethod}s representing decorated methods of the specified decorator. A decorated method
     * is any method declared by a decorated type which is implemented by the decorator.
     *
     * @param beanManager the bean manager
     * @param decorator the specified decorator
     * @return the set of {@link InvokableAnnotatedMethod}s representing decorated methods of the specified decorator
     */
    public static Set<InvokableAnnotatedMethod<?>> getDecoratorMethods(BeanManagerImpl beanManager, WeldDecorator<?> decorator) {
        ImmutableSet.Builder<InvokableAnnotatedMethod<?>> builder = ImmutableSet.builder();
        for (Type type : decorator.getDecoratedTypes()) {
            EnhancedAnnotatedType<?> weldClass = getWeldClassOfDecoratedType(beanManager, type);
            for (EnhancedAnnotatedMethod<?, ?> method : weldClass.getDeclaredEnhancedMethods()) {
                if (decorator.getEnhancedAnnotated().getEnhancedMethod(method.getSignature()) != null) {
                    builder.add(InvokableAnnotatedMethod.of(method.slim()));
                }
            }
        }
        return builder.build();
    }

    private static EnhancedAnnotatedType<?> getWeldClassOfDecoratedType(BeanManagerImpl beanManager, Type type) {
        if (type instanceof Class<?>) {
            return beanManager.createEnhancedAnnotatedType((Class<?>) type);
        }
        if (type instanceof ParameterizedType && (((ParameterizedType) type).getRawType() instanceof Class)) {
            return beanManager.createEnhancedAnnotatedType((Class<?>) ((ParameterizedType) type).getRawType());
        }
        throw new IllegalStateException(BeanLogger.LOG.unableToProcess(type));
    }

    public static WeldInjectionPointAttributes<?, ?> findDelegateInjectionPoint(AnnotatedType<?> type, Iterable<InjectionPoint> injectionPoints) {
        WeldInjectionPointAttributes<?, ?> result = null;
        for (InjectionPoint injectionPoint : injectionPoints) {
            if (injectionPoint.isDelegate()) {
                if (result != null) {
                    throw BeanLogger.LOG.tooManyDelegatesForDecorator(type);
                }
                if (injectionPoint instanceof MethodInjectionPoint<?, ?> && !injectionPoint.getAnnotated().isAnnotationPresent(Inject.class)) {
                    throw BeanLogger.LOG.delegateOnNonInitializerMethod(injectionPoint);
                }
                result = InjectionPoints.getWeldInjectionPoint(injectionPoint);
            }
        }
        if (result == null) {
            throw BeanLogger.LOG.noDelegateForDecorator(type);
        }
        return result;
    }

    public static <T> T getOuterDelegate(Bean<T> bean, T instance, CreationalContext<T> creationalContext, Class<T> proxyClass, InjectionPoint originalInjectionPoint, BeanManagerImpl manager, List<Decorator<?>> decorators) {
        TargetBeanInstance beanInstance = new TargetBeanInstance(bean, instance);
        DecorationHelper<T> decorationHelper = new DecorationHelper<T>(beanInstance, bean, proxyClass, manager, manager.getServices().get(ContextualStore.class), decorators);
        DecorationHelper.push(decorationHelper);
        try {
            final T outerDelegate = decorationHelper.getNextDelegate(originalInjectionPoint, creationalContext);
            if (outerDelegate == null) {
                throw new WeldException(BeanLogger.LOG.proxyInstantiationFailed(bean));
            }
            return outerDelegate;
        } finally {
            DecorationHelper.pop();
        }
    }

    /**
     * Check whether the delegate type implements or extends all decorated types.
     *
     * @param decorator
     * @throws DefinitionException If the delegate type doesn't implement or extend all decorated types
     */
    public static void checkDelegateType(Decorator<?> decorator) {

        Set<Type> types = new HierarchyDiscovery(decorator.getDelegateType()).getTypeClosure();

        for (Type decoratedType : decorator.getDecoratedTypes()) {
            if(!types.contains(decoratedType)) {
                throw BeanLogger.LOG.delegateMustSupportEveryDecoratedType(decoratedType, decorator);
            }
        }
    }

    /**
     * Check all abstract methods are declared by the decorated types.
     *
     * @param type
     * @param beanManager
     * @param delegateType
     * @throws DefinitionException If any of the abstract methods is not declared by the decorated types
     */
    public static <T> void checkAbstractMethods(Set<Type> decoratedTypes, EnhancedAnnotatedType<T> type, BeanManagerImpl beanManager) {

        if(decoratedTypes == null) {
            decoratedTypes = new HashSet<Type>(type.getInterfaceClosure());
            decoratedTypes.remove(Serializable.class);
        }

        Set<MethodSignature> signatures = new HashSet<MethodSignature>();

        for (Type decoratedType : decoratedTypes) {
            for (EnhancedAnnotatedMethod<?, ?> method : ClassTransformer.instance(beanManager).getEnhancedAnnotatedType(Reflections.getRawType(decoratedType), beanManager.getId()).getEnhancedMethods()) {
                signatures.add(method.getSignature());
            }
        }

        for (EnhancedAnnotatedMethod<?, ?> method : type.getEnhancedMethods()) {
            if (Reflections.isAbstract(((AnnotatedMethod<?>) method).getJavaMember())) {
                MethodSignature methodSignature = method.getSignature();
                if (!signatures.contains(methodSignature)) {
                    throw BeanLogger.LOG.abstractMethodMustMatchDecoratedType(method.getSignature(), type);
                }
            }
        }
    }

    /**
     * Indicates whether a {@link Decorator} is passivation capable or not.
     * @return
     */
    public static boolean isPassivationCapable(Decorator<?> decorator) {
        if (decorator instanceof CustomDecoratorWrapper<?>) {
            // unwrap
            decorator = Reflections.<CustomDecoratorWrapper<?>>cast(decorator).delegate();
        }
        if (decorator instanceof DecoratorImpl<?>) {
            DecoratorImpl<?> weldDecorator = (DecoratorImpl<?>) decorator;
            return weldDecorator.getEnhancedAnnotated().isSerializable();
        }
        return decorator instanceof PassivationCapable;
    }
}
TOP

Related Classes of org.jboss.weld.util.Decorators

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.