001package org.picocontainer;
002
003import org.picocontainer.containers.ImmutablePicoContainer;
004import org.picocontainer.containers.TransientPicoContainer;
005import org.picocontainer.injectors.ConstructorInjection;
006
007import java.lang.reflect.Field;
008import java.lang.reflect.Type;
009
010public class Emjection {
011
012    private PicoContainer pico;
013
014    public void setPico(ImmutablePicoContainer container) {
015        if (pico != null) {
016            throw new PicoCompositionException("Emjection can only be setup once per component");
017        }
018        pico = container;
019    }
020
021    public static <T> T neu(Class<T> type, Emjection emjection, Object... args) {
022        if (emjection.pico == null) {
023            throw new PicoCompositionException("blah");
024        }
025        TransientPicoContainer tpc = new TransientPicoContainer(new ConstructorInjection(), emjection.pico);
026        for (Object arg : args) {
027            tpc.addComponent(arg);
028        }
029        T inst = tpc.getComponent(type);
030        if (inst == null) {
031            tpc.addComponent(type);
032            inst = tpc.getComponent(type);
033        }
034        setPico(inst, tpc);
035        return inst;
036    }
037
038    private static <T> void setPico(Object inst, PicoContainer container) {
039        try {
040            Field field = inst.getClass().getDeclaredField("emjection");
041            field.setAccessible(true);
042            Emjection e2 = (Emjection) field.get(inst);
043            e2.setPico(new ImmutablePicoContainer(container));
044        } catch (NoSuchFieldException e) {
045            throw new PicoCompositionException("Components created via emjection have to have a field 'private Emjection emjection'. " + inst.getClass() + " is missing that field");
046        } catch (IllegalAccessException e) {
047            throw new PicoCompositionException("unable to access field called emjection on " + inst.getClass());
048        }
049    }
050
051    public static void setupEmjection(Object inst, PicoContainer container) {
052            setPico(inst, container);
053    }
054
055
056}