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 }