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     *****************************************************************************/
010    package org.picocontainer.containers;
011    
012    import org.picocontainer.*;
013    
014    import java.lang.reflect.Type;
015    import java.lang.annotation.Annotation;
016    import java.io.Serializable;
017    import java.util.List;
018    import java.util.Collection;
019    import 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     */
026    public 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    }