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

org.jboss.weld.bean.DisposalMethod 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.bean;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Set;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.Specializes;
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.AnnotatedParameter;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.Decorator;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.Interceptor;
import javax.inject.Inject;
import javax.inject.Qualifier;

import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedMethod;
import org.jboss.weld.annotated.enhanced.EnhancedAnnotatedParameter;
import org.jboss.weld.annotated.enhanced.MethodSignature;
import org.jboss.weld.bootstrap.Validator;
import org.jboss.weld.injection.InjectionPointFactory;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.injection.MethodInjectionPoint.MethodInjectionPointType;
import org.jboss.weld.injection.MethodInvocationStrategy;
import org.jboss.weld.injection.ParameterInjectionPoint;
import org.jboss.weld.literal.DefaultLiteral;
import org.jboss.weld.logging.BeanLogger;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.metadata.cache.MetaAnnotationStore;
import org.jboss.weld.resolution.QualifierInstance;
import org.jboss.weld.util.reflection.Formats;
import org.jboss.weld.util.reflection.Reflections;

public class DisposalMethod {

    private static final String DISPOSER_ANNOTATION = "@Disposes";
    private final BeanManagerImpl beanManager;
    private final AbstractClassBean declaringBean;

    private final MethodInjectionPoint disposalMethodInjectionPoint;
    private final AnnotatedParameter disposesParameter;

    private final Set requiredQualifiers;

    private final MethodInvocationStrategy invocationStrategy;

    public static  DisposalMethod of(BeanManagerImpl manager, EnhancedAnnotatedMethod method, AbstractClassBean declaringBean) {
        return new DisposalMethod(manager, method, declaringBean);
    }

    protected DisposalMethod(BeanManagerImpl beanManager, EnhancedAnnotatedMethod enhancedAnnotatedMethod, AbstractClassBean declaringBean) {
        this.disposalMethodInjectionPoint = InjectionPointFactory.instance().createMethodInjectionPoint(MethodInjectionPointType.DISPOSER, enhancedAnnotatedMethod, declaringBean, declaringBean.getBeanClass(), Disposes.class, beanManager);
        this.beanManager = beanManager;
        this.declaringBean = declaringBean;
        EnhancedAnnotatedParameter enhancedDisposesParameter = getEnhancedDisposesParameter(enhancedAnnotatedMethod);
        this.disposesParameter = enhancedDisposesParameter.slim();
        this.requiredQualifiers = getRequiredQualifiers(enhancedDisposesParameter);
        checkDisposalMethod(enhancedAnnotatedMethod, declaringBean);
        this.invocationStrategy = MethodInvocationStrategy.forDisposer(disposalMethodInjectionPoint, beanManager);
    }

    private EnhancedAnnotatedParameter getEnhancedDisposesParameter(EnhancedAnnotatedMethod enhancedAnnotatedMethod) {
        return enhancedAnnotatedMethod.getEnhancedParameters(Disposes.class).get(0);
    }

    public AnnotatedParameter getDisposesParameter() {
        return disposesParameter;
    }


    public AnnotatedMethod getAnnotated() {
        return disposalMethodInjectionPoint.getAnnotated();
    }

    public void invokeDisposeMethod(Object receiver, Object instance, CreationalContext creationalContext) {
        invocationStrategy.invoke(receiver, disposalMethodInjectionPoint, instance, beanManager, creationalContext);
    }

    private void checkDisposalMethod(EnhancedAnnotatedMethod enhancedAnnotatedMethod, AbstractClassBean declaringBean) {
        if (enhancedAnnotatedMethod.getEnhancedParameters(Disposes.class).size() > 1) {
            throw BeanLogger.LOG
                    .multipleDisposeParams(disposalMethodInjectionPoint, Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
        }
        if (enhancedAnnotatedMethod.getEnhancedParameters(Observes.class).size() > 0) {
            throw BeanLogger.LOG.inconsistentAnnotationsOnMethod("@Observes", DISPOSER_ANNOTATION, disposalMethodInjectionPoint,
                    Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
        }
        if (enhancedAnnotatedMethod.getAnnotation(Inject.class) != null) {
            throw BeanLogger.LOG.inconsistentAnnotationsOnMethod("@Inject", DISPOSER_ANNOTATION, disposalMethodInjectionPoint,
                    Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
        }
        if (enhancedAnnotatedMethod.getAnnotation(Produces.class) != null) {
            throw BeanLogger.LOG.inconsistentAnnotationsOnMethod("@Produces", DISPOSER_ANNOTATION, disposalMethodInjectionPoint,
                    Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
        }
        if (enhancedAnnotatedMethod.getAnnotation(Specializes.class) != null) {
            throw BeanLogger.LOG.inconsistentAnnotationsOnMethod("@Specialized", DISPOSER_ANNOTATION, disposalMethodInjectionPoint,
                    Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
        }
        if (declaringBean instanceof SessionBean) {
            SessionBean sessionBean = (SessionBean) declaringBean;
            Set businessMethodSignatures = sessionBean.getBusinessMethodSignatures();
            if (!businessMethodSignatures.contains(enhancedAnnotatedMethod.getSignature())) {
                throw BeanLogger.LOG.methodNotBusinessMethod("Disposer", enhancedAnnotatedMethod, declaringBean,
                        Formats.formatAsStackTraceElement(enhancedAnnotatedMethod.getJavaMember()));
            }
        }
        for (ParameterInjectionPoint ip : disposalMethodInjectionPoint.getParameterInjectionPoints()) {
            Class rawType = Reflections.getRawType(ip.getType());
            if (Bean.class.equals(rawType) || Interceptor.class.equals(rawType) || Decorator.class.equals(rawType)) {
                Validator.checkBeanMetadataInjectionPoint(this, ip, getDisposesParameter().getBaseType());
            }
        }
    }

    public Type getGenericType() {
        return getDisposesParameter().getBaseType();
    }

    public Set getRequiredQualifiers() {
        return requiredQualifiers;
    }

    public AbstractClassBean getDeclaringBean() {
        return declaringBean;
    }

    @Override
    public String toString() {
        return "Disposer method [" + getDisposesParameter().getDeclaringCallable() + "]";
    }

    public Set getInjectionPoints() {
        return disposalMethodInjectionPoint.getInjectionPoints();
    }

    /**
     * A disposer method is bound to a producer if the producer is assignable to the disposed parameter.
     *
     * @param enhancedDisposedParameter
     * @return the set of required qualifiers for the given disposed parameter
     */
    private Set getRequiredQualifiers(EnhancedAnnotatedParameter enhancedDisposedParameter) {
        Set disposedParameterQualifiers = enhancedDisposedParameter.getMetaAnnotations(Qualifier.class);
        if (disposedParameterQualifiers.isEmpty()) {
            disposedParameterQualifiers = Collections. singleton(DefaultLiteral.INSTANCE);
        }
        return beanManager.getServices().get(MetaAnnotationStore.class).getQualifierInstances(disposedParameterQualifiers);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy