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 * Idea by Rachel Davies, Original code by various                           *
009 *****************************************************************************/
010package org.picocontainer.containers;
011
012import org.picocontainer.*;
013
014import java.lang.reflect.Type;
015import java.lang.annotation.Annotation;
016import java.io.Serializable;
017import java.util.List;
018import java.util.Collection;
019import java.util.Collections;
020
021/**
022 * CompositePicoContainer takes a var-args list of containers and will query them
023 * in turn for getComponent(*) and getComponentAdapter(*) requests.  Methods returning
024 * lists and getParent/accept will not function.
025 */
026public class CompositePicoContainer implements PicoContainer, Converting, Serializable {
027
028    private final PicoContainer[] containers;
029    private Converters compositeConverter = new CompositeConverters();
030
031    public class CompositeConverters implements Converters {
032        public boolean canConvert(Type type) {
033            for (PicoContainer container : containers) {
034                if (container instanceof Converting && ((Converting) container).getConverters().canConvert(type)) {
035                    return true;
036                }
037            }
038            return false;
039        }
040
041        public Object convert(String paramValue, Type type) {
042            for (PicoContainer container : containers) {
043                if (container instanceof Converting) {
044                    Converters converter = ((Converting) container).getConverters();
045                    if (converter.canConvert(type)) {
046                        return converter.convert(paramValue, type);
047                    }
048                }
049            }
050            return null;
051        }
052    }
053
054    public CompositePicoContainer(PicoContainer... containers) {
055        this.containers = containers;
056    }
057
058    public <T> T getComponent(Class<T> componentType) {
059        for (PicoContainer container : containers) {
060            T inst = container.getComponent(componentType);
061            if (inst != null) {
062                return inst;
063            }
064        }
065        return null;
066    }
067
068    public Object getComponent(Object componentKeyOrType, Type into) {
069        for (PicoContainer container : containers) {
070            Object inst = container.getComponent(componentKeyOrType, into);
071            if (inst != null) {
072                return inst;
073            }
074        }
075        return null;
076    }
077
078    public Object getComponent(Object componentKeyOrType) {
079        for (PicoContainer container : containers) {
080            Object inst = container.getComponent(componentKeyOrType);
081            if (inst != null) {
082                return inst;
083            }
084        }
085        return null;
086    }
087
088    public ComponentAdapter getComponentAdapter(Object componentKey) {
089        for (PicoContainer container : containers) {
090            ComponentAdapter inst = container.getComponentAdapter(componentKey);
091            if (inst != null) {
092                return inst;
093            }
094        }
095        return null;
096    }
097
098    public <T> ComponentAdapter<T> getComponentAdapter(Class<T> componentType, NameBinding nameBinding) {
099        for (PicoContainer container : containers) {
100            ComponentAdapter<T> inst = container.getComponentAdapter(componentType, nameBinding);
101            if (inst != null) {
102                return inst;
103            }
104        }
105        return null;
106    }
107
108    public <T> ComponentAdapter<T> getComponentAdapter(Class<T> componentType, Class<? extends Annotation> binding) {
109        for (PicoContainer container : containers) {
110            ComponentAdapter<T> inst = container.getComponentAdapter(componentType, binding);
111            if (inst != null) {
112                return inst;
113            }
114        }
115        return null;
116    }
117
118    public <T> T getComponent(Class<T> componentType, Class<? extends Annotation> binding) {
119        return null;
120    }
121
122    public List<Object> getComponents() {
123        return Collections.emptyList();
124    }
125
126    public PicoContainer getParent() {
127        return null;
128    }
129
130    public Collection<ComponentAdapter<?>> getComponentAdapters() {
131        return Collections.emptyList();
132    }
133
134    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType) {
135        return Collections.emptyList();
136    }
137
138    public <T> List<ComponentAdapter<T>> getComponentAdapters(Class<T> componentType, Class<? extends Annotation> binding) {
139        return Collections.emptyList();
140    }
141
142    public <T> List<T> getComponents(Class<T> componentType) {
143        return Collections.emptyList();
144    }
145
146    public void accept(PicoVisitor visitor) {
147    }
148
149    public Converters getConverters() {
150        return compositeConverter;
151    }
152}