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 org.jboss.weld.bootstrap.BeanDeployerEnvironment;
import org.jboss.weld.bootstrap.api.ServiceRegistry;
import org.jboss.weld.exceptions.DefinitionException;
import org.jboss.weld.injection.MethodInjectionPoint;
import org.jboss.weld.introspector.WeldMethod;
import org.jboss.weld.introspector.WeldParameter;
import org.jboss.weld.manager.BeanManagerImpl;
import org.jboss.weld.util.Beans;
import org.jboss.weld.util.reflection.SecureReflections;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import static org.jboss.weld.logging.messages.BeanMessage.DISPOSE_NOT_FIRST_PARAM;
import static org.jboss.weld.logging.messages.BeanMessage.INCONSISTENT_ANNOTATIONS_ON_METHOD;
import static org.jboss.weld.logging.messages.BeanMessage.METHOD_NOT_BUSINESS_METHOD;
import static org.jboss.weld.logging.messages.BeanMessage.MULTIPLE_DISPOSE_PARAMS;
import static org.jboss.weld.util.reflection.Reflections.cast;

public class DisposalMethod extends AbstractReceiverBean {

    protected MethodInjectionPoint disposalMethodInjectionPoint;
    private WeldParameter disposesParameter;

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

    protected DisposalMethod(BeanManagerImpl beanManager, WeldMethod disposalMethod, AbstractClassBean declaringBean, ServiceRegistry services) {
        super(new StringBuilder().append(DisposalMethod.class.getSimpleName()).append(BEAN_ID_SEPARATOR).append(declaringBean.getWeldAnnotated().getName()).append(disposalMethod.getSignature().toString()).toString(), declaringBean, beanManager, services);
        this.disposalMethodInjectionPoint = MethodInjectionPoint.of(this, disposalMethod);
        initQualifiers();
        initType();
        initTypes();
        initStereotypes();
        addInjectionPoints(Beans.getParameterInjectionPoints(this, disposalMethodInjectionPoint));
    }

    private void initDisposesParameter() {
        this.disposesParameter = getWeldAnnotated().getWeldParameters(Disposes.class).get(0);
    }

    public WeldParameter getDisposesParameter() {
        return disposesParameter;
    }

    @Override
    public void initialize(BeanDeployerEnvironment environment) {
        super.initialize(environment);
        checkDisposalMethod();
        initDisposesParameter();
    }

    protected void initType() {
        this.type = cast(disposalMethodInjectionPoint.getAnnotatedParameters(Disposes.class).get(0).getJavaClass());
    }

    @Override
    public WeldMethod getWeldAnnotated() {
        return disposalMethodInjectionPoint;
    }

    @Override
    protected void initQualifiers() {
        // At least 1 parameter exists, already checked in constructor
        this.qualifiers = new HashSet();
        this.qualifiers.addAll(disposalMethodInjectionPoint.getWeldParameters().get(0).getQualifiers());
        initDefaultQualifiers();
    }

    /**
     * Initializes the API types
     */
    @Override
    protected void initTypes() {
        Set types = new HashSet();
        types.addAll(disposalMethodInjectionPoint.getAnnotatedParameters(Disposes.class).get(0).getTypeClosure());
        types.add(Object.class);
        super.types = types;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public Class getScope() {
        return null;
    }

    @Override
    public Set getTypes() {
        return types;
    }

    @Override
    public boolean isNullable() {
        // Not relevant
        return false;
    }

    @Override
    public boolean isPassivationCapableBean() {
        // Not relevant
        return false;
    }

    @Override
    public boolean isPassivationCapableDependency() {
        // Not relevant
        return false;
    }

    @Override
    public boolean isProxyable() {
        return true;
    }

    public T create(CreationalContext creationalContext) {
        // Not Relevant
        return null;
    }

    public void invokeDisposeMethod(Object instance) {
        CreationalContext creationalContext = beanManager.createCreationalContext(this);
        Object receiverInstance = getReceiver(creationalContext);
        if (receiverInstance == null) {
            disposalMethodInjectionPoint.invokeWithSpecialValue(null, Disposes.class, instance, beanManager, creationalContext, IllegalArgumentException.class);
        } else {
            disposalMethodInjectionPoint.invokeOnInstanceWithSpecialValue(receiverInstance, Disposes.class, instance, beanManager, creationalContext, IllegalArgumentException.class);
        }
        creationalContext.release();
    }

    private void checkDisposalMethod() {
        if (!disposalMethodInjectionPoint.getWeldParameters().get(0).isAnnotationPresent(Disposes.class)) {
            throw new DefinitionException(DISPOSE_NOT_FIRST_PARAM, disposalMethodInjectionPoint);
        }
        if (disposalMethodInjectionPoint.getAnnotatedParameters(Disposes.class).size() > 1) {
            throw new DefinitionException(MULTIPLE_DISPOSE_PARAMS, disposalMethodInjectionPoint);
        }
        if (disposalMethodInjectionPoint.getAnnotatedParameters(Observes.class).size() > 0) {
            throw new DefinitionException(INCONSISTENT_ANNOTATIONS_ON_METHOD, "@Observes", "@Disposes", disposalMethodInjectionPoint);
        }
        if (disposalMethodInjectionPoint.getAnnotation(Inject.class) != null) {
            throw new DefinitionException(INCONSISTENT_ANNOTATIONS_ON_METHOD, "@Intitializer", "@Disposes", disposalMethodInjectionPoint);
        }
        if (disposalMethodInjectionPoint.getAnnotation(Produces.class) != null) {
            throw new DefinitionException(INCONSISTENT_ANNOTATIONS_ON_METHOD, "@Produces", "@Disposes", disposalMethodInjectionPoint);
        }
        if (getDeclaringBean() instanceof SessionBean) {
            boolean methodDeclaredOnTypes = false;
            // TODO use annotated item?
            for (Type type : getDeclaringBean().getTypes()) {
                if (type instanceof Class) {
                    Class clazz = (Class) type;
                    if (SecureReflections.isMethodExists(clazz, disposalMethodInjectionPoint.getName(), disposalMethodInjectionPoint.getParameterTypesAsArray())) {
                        methodDeclaredOnTypes = true;
                        continue;
                    }
                }
            }
            if (!methodDeclaredOnTypes) {
                throw new DefinitionException(METHOD_NOT_BUSINESS_METHOD, this, getDeclaringBean());
            }
        }
    }

    @Override
    protected void checkType() {

    }

    @Override
    public Class getType() {
        return type;
    }

    @Override
    protected String getDefaultName() {
        return disposalMethodInjectionPoint.getPropertyName();
    }

    public void destroy(T instance, CreationalContext creationalContext) {
        // No-op. Producer method dependent objects are destroyed in producer method bean
    }

    @Override
    public AbstractBean getSpecializedBean() {
        // Doesn't support specialization
        return null;
    }

    @Override
    protected void initScope() {
        // Disposal methods aren't scoped
    }

    @Override
    public Set> getStereotypes() {
        return Collections.emptySet();
    }

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


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy