001/*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.            *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD      *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file.                                                     *
007 *                                                                           *
008 *****************************************************************************/
009package org.picocontainer.injectors;
010
011import org.picocontainer.ComponentMonitor;
012import org.picocontainer.Injector;
013import org.picocontainer.Parameter;
014import org.picocontainer.PicoCompositionException;
015import org.picocontainer.PicoContainer;
016import org.picocontainer.PicoVisitor;
017
018import java.lang.reflect.Type;
019
020@SuppressWarnings("serial")
021public class CompositeInjector<T> extends AbstractInjector<T> {
022
023    private final Injector<T>[] injectors;
024
025    public CompositeInjector(Object componentKey, Class<?> componentImplementation, Parameter[] parameters, ComponentMonitor monitor,
026                             boolean useNames, Injector... injectors) {
027        super(componentKey, componentImplementation, parameters, monitor, useNames);
028        this.injectors = injectors;
029    }
030
031
032    @Override
033    public T getComponentInstance(PicoContainer container) throws PicoCompositionException {
034        return getComponentInstance(container, NOTHING.class);
035    }
036
037    @Override
038    public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException {
039        T instance = null;
040        for (Injector<T> injector : injectors) {
041            if (instance == null) {
042                instance = injector.getComponentInstance(container, NOTHING.class);
043            } else {
044                injector.decorateComponentInstance(container, into, instance);
045            }
046        }
047        return (T) instance;
048    }
049
050
051    /**
052     * @return the object returned is the result of the last of the injectors delegated to
053     */
054    @Override
055    public Object decorateComponentInstance(PicoContainer container, Type into, T instance) {
056        Object result = null;
057        for (Injector<T> injector : injectors) {
058            result = injector.decorateComponentInstance(container, into, instance);
059        }        
060        return result;
061    }
062
063    @Override
064    public void verify(PicoContainer container) throws PicoCompositionException {
065        for (Injector<T> injector : injectors) {
066            injector.verify(container);
067        }
068    }
069
070    @Override
071    public final void accept(PicoVisitor visitor) {
072        super.accept(visitor);
073        for (Injector<T> injector : injectors) {
074            injector.accept(visitor);
075        }
076    }
077
078    @Override
079    public String getDescriptor() {
080        StringBuilder sb = new StringBuilder("CompositeInjector(");
081        for (Injector<T> injector : injectors) {
082            sb.append(injector.getDescriptor());
083        }
084        sb.deleteCharAt(sb.length()-1); // remove last dash
085        return sb.toString().replace("-", "+") + ")-";
086    }
087}