Package com.softwaremill.common.cdi.autofactory.extension

Source Code of com.softwaremill.common.cdi.autofactory.extension.FactoryInvocationHandler

package com.softwaremill.common.cdi.autofactory.extension;

import org.jboss.weld.Container;
import org.jboss.weld.injection.ConstructorInjectionPoint;
import org.jboss.weld.injection.CurrentInjectionPoint;
import org.jboss.weld.introspector.WeldConstructor;
import com.softwaremill.common.cdi.autofactory.extension.parameter.ParameterValue;

import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* @author Adam Warski (adam at warski dot org)
*/
public class FactoryInvocationHandler<T> implements InvocationHandler {
    private final BeanManager beanManager;
    private final Bean<T> bean;
    private final CreatedTypeData<T> createdTypeData;
    private final CreationalContext<T> creationalContext;

    public FactoryInvocationHandler(BeanManager beanManager, Bean<T> bean, CreatedTypeData<T> createdTypeData,
                                    CreationalContext<T> creationalContext) {
        this.beanManager = beanManager;
        this.bean = bean;
        this.createdTypeData = createdTypeData;
        this.creationalContext = creationalContext;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] parameters) throws Throwable {
        T instance;

        if (createdTypeData.isConstructorInjection()) {
            CurrentInjectionPoint currentInjectionPoint = Container.instance().services().get(CurrentInjectionPoint.class);
            currentInjectionPoint.push(ConstructorInjectionPoint.of(bean, (WeldConstructor<T>) createdTypeData.getCreatedTypeConstructor()));
            instance = newInstance(parameters);
            currentInjectionPoint.pop();
        } else {
            instance = newInstance(parameters);
            createdTypeData.getCreatedTypeInjectionTarget().inject(instance, creationalContext);
            createdTypeData.getCreatedTypeInjectionTarget().postConstruct(instance);
        }

        return instance;
    }

    private T newInstance(Object[] parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        return createdTypeData.getCreatedTypeConstructor().getJavaMember().newInstance(createConstructorParameters(parameters));
    }

    private Object[] createConstructorParameters(Object[] factoryMethodParameters) {
        ParameterValue[] createdTypeConstructorParameterValues = createdTypeData.getCreatedTypeConstructorParameterValues();

        Object[] constructorParameters =  new Object[createdTypeConstructorParameterValues.length];

        for (int i = 0; i < createdTypeConstructorParameterValues.length; i++) {
            ParameterValue createdTypeConstructorParameterValue = createdTypeConstructorParameterValues[i];
            constructorParameters[i] = createdTypeConstructorParameterValue.getValue(beanManager, factoryMethodParameters);
        }

        return constructorParameters;
    }
}
TOP

Related Classes of com.softwaremill.common.cdi.autofactory.extension.FactoryInvocationHandler

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.