001/**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.test;
017
018import org.apache.commons.logging.Log;
019import org.apache.commons.logging.LogFactory;
020import org.kuali.rice.core.framework.resourceloader.SpringResourceLoader;
021import org.springframework.beans.BeansException;
022import org.springframework.beans.factory.BeanFactory;
023import org.springframework.beans.factory.NoSuchBeanDefinitionException;
024import org.springframework.core.ResolvableType;
025
026import java.util.ArrayList;
027import java.util.Collection;
028
029/** 
030 * Wraps a collection of bean factories delegating to the inner bean factories.
031 * 
032 * The first bean factory that returns a non-null/true result is the value that is returned/
033 */
034public final class CompositeBeanFactory implements BeanFactory {
035
036        private static final Log LOG = LogFactory.getLog(CompositeBeanFactory.class);
037        
038        private final Collection<BeanFactory> factories;
039        
040        public static BeanFactory createBeanFactory(Collection<? extends SpringResourceLoader> rls) {
041                if (rls == null || rls.isEmpty()) {
042                        throw new IllegalArgumentException("rls is null or empty");
043                }
044                
045                final Collection<BeanFactory> bfs = new ArrayList<BeanFactory>();
046                for (SpringResourceLoader rl : rls) {
047                        bfs.add(rl.getContext());
048                }
049                return new CompositeBeanFactory(bfs);
050        }
051        
052        public CompositeBeanFactory(Collection<? extends BeanFactory> factories) {
053                if (factories == null || factories.isEmpty()) {
054                        throw new IllegalArgumentException("factories is null or empty");
055                }
056                
057                this.factories = new ArrayList<BeanFactory>(factories);
058        }
059
060        @Override
061        public Object getBean(String name) throws BeansException {
062                for (BeanFactory f : factories) {
063                        try {
064                                Object o = f.getBean(name);
065                                if (o != null) {
066                                        return o;
067                                }       
068                        } catch (BeansException e) {
069                                LOG.debug("bean exception", e);
070                        }
071                }
072                return null;
073        }
074
075        @Override
076        public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
077                for (BeanFactory f : factories) {
078                        try {
079                                T t = f.getBean(name, requiredType);
080                                if (t != null) {
081                                        return t;
082                                }       
083                        } catch (BeansException e) {
084                                LOG.info("bean exception", e);
085                        }
086                }
087                return null;
088        }
089
090        @Override
091        public <T> T getBean(Class<T> requiredType) throws BeansException {
092                for (BeanFactory f : factories) {
093                        try {
094                                T t = f.getBean(requiredType);
095                                if (t != null) {
096                                        return t;
097                                }       
098                        } catch (BeansException e) {
099                                LOG.info("bean exception", e);
100                        }
101                }
102                return null;
103        }
104
105        @Override
106        public Object getBean(String name, Object... args) throws BeansException {
107                for (BeanFactory f : factories) {
108                        try {
109                                Object o = f.getBean(name, args);
110                                if (o != null) {
111                                        return o;
112                                }       
113                        } catch (BeansException e) {
114                                LOG.info("bean exception", e);
115                        }
116                }
117                return null;
118        }
119
120    @Override
121    public <T> T getBean(Class<T> tClass, Object... objects) throws BeansException {
122        // Does not currently support creating a bean instance using explicit arguments
123        return getBean(tClass);
124    }
125
126    @Override
127        public boolean containsBean(String name) {
128                for (BeanFactory f : factories) {
129                        try {
130                                boolean b = f.containsBean(name);
131                                if (b) {
132                                        return b;
133                                }       
134                        } catch (BeansException e) {
135                                LOG.info("bean exception", e);
136                        }
137                }
138                return false;
139        }
140
141        @Override
142        public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
143                for (BeanFactory f : factories) {
144                        try {
145                                boolean b = f.isSingleton(name);
146                                if (b) {
147                                        return b;
148                                }       
149                        } catch (BeansException e) {
150                                LOG.info("bean exception", e);
151                        }
152                }
153                return false;
154        }
155
156        @Override
157        public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
158                for (BeanFactory f : factories) {
159                        try {
160                                boolean b = f.isPrototype(name);
161                                if (b) {
162                                        return b;
163                                }       
164                        } catch (BeansException e) {
165                                LOG.info("bean exception", e);
166                        }
167                }
168                return false;
169        }
170
171        @Override
172        public boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException {
173                for (BeanFactory f : factories) {
174                        try {
175                                boolean b = f.isTypeMatch(name, targetType);
176                                if (b) {
177                                        return b;
178                                }       
179                        } catch (BeansException e) {
180                                LOG.info("bean exception", e);
181                        }
182                }
183                return false;
184        }
185
186        @Override
187        public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
188                for (BeanFactory f : factories) {
189                        try {
190                                boolean b = f.isTypeMatch(name, typeToMatch);
191                                if (b) {
192                                        return b;
193                                }
194                        } catch (BeansException e) {
195                                LOG.info("bean exception", e);
196                        }
197                }
198                return false;
199        }
200
201        @Override
202        public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
203                for (BeanFactory f : factories) {
204                        try {
205                                Class<?> c = f.getType(name);
206                                if (c != null) {
207                                        return c;
208                                }       
209                        } catch (BeansException e) {
210                                LOG.info("bean exception", e);
211                        }
212                }
213                return null;
214        }
215
216        @Override
217        public String[] getAliases(String name) {
218                for (BeanFactory f : factories) {
219                        try {
220                                String[] s = f.getAliases(name);
221                                if (s != null) {
222                                        return s;
223                                }       
224                        } catch (BeansException e) {
225                                LOG.info("bean exception", e);
226                        }
227                }
228                return null;
229        }
230}