View Javadoc

1   /*
2    * Copyright 2006-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.springframework.batch.core.configuration.support;
17  
18  import java.util.ArrayList;
19  import java.util.Arrays;
20  import java.util.List;
21  
22  import org.springframework.beans.BeansException;
23  import org.springframework.beans.factory.BeanFactoryAware;
24  import org.springframework.beans.factory.FactoryBean;
25  import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
26  import org.springframework.beans.factory.config.BeanPostProcessor;
27  import org.springframework.beans.factory.config.CustomEditorConfigurer;
28  import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
29  import org.springframework.context.ApplicationContext;
30  import org.springframework.context.ApplicationContextAware;
31  import org.springframework.core.io.Resource;
32  
33  /**
34   * A convenient factory for creating a set of {@link ApplicationContextFactory}
35   * components from a set of {@link Resource resources}.
36   *
37   * @author Dave Syer
38   *
39   */
40  public class ClasspathXmlApplicationContextsFactoryBean implements FactoryBean, ApplicationContextAware {
41  
42  	private List<Resource> resources = new ArrayList<Resource>();
43  
44  	private boolean copyConfiguration = true;
45  
46  	private Class<? extends BeanFactoryPostProcessor>[] beanFactoryPostProcessorClasses;
47  
48  	private Class<?>[] beanPostProcessorExcludeClasses;
49  
50  	private ApplicationContext applicationContext;
51  
52  	/**
53  	 * A set of resources to load using a
54  	 * {@link GenericApplicationContextFactory}. Each resource should be a
55  	 * Spring configuration file which is loaded into an application context
56  	 * whose parent is the current context. In a configuration file the
57  	 * resources can be given as a pattern (e.g.
58  	 * <code>classpath*:/config/*-context.xml</code>).
59  	 *
60  	 * @param resources
61  	 */
62  	public void setResources(Resource[] resources) {
63  		this.resources = Arrays.asList(resources);
64  	}
65  
66  	/**
67  	 * Flag to indicate that configuration such as bean post processors and
68  	 * custom editors should be copied from the parent context. Defaults to
69  	 * true.
70  	 *
71  	 * @param copyConfiguration the flag value to set
72  	 */
73  	public void setCopyConfiguration(boolean copyConfiguration) {
74  		this.copyConfiguration = copyConfiguration;
75  	}
76  
77  	/**
78  	 * Determines which bean factory post processors (like property
79  	 * placeholders) should be copied from the parent context. Defaults to
80  	 * {@link PropertyPlaceholderConfigurer} and {@link CustomEditorConfigurer}.
81  	 *
82  	 * @param beanFactoryPostProcessorClasses post processor types to be copied
83  	 */
84  
85  	public void setBeanFactoryPostProcessorClasses(
86  			Class<? extends BeanFactoryPostProcessor>[] beanFactoryPostProcessorClasses) {
87  		this.beanFactoryPostProcessorClasses = beanFactoryPostProcessorClasses;
88  	}
89  
90  	/**
91  	 * Determines by exclusion which bean post processors should be copied from
92  	 * the parent context. Defaults to {@link BeanFactoryAware} (so any post
93  	 * processors that have a reference to the parent bean factory are not
94  	 * copied into the child). Note that these classes do not themselves have to
95  	 * be {@link BeanPostProcessor} implementations or sub-interfaces.
96  	 *
97  	 * @param beanPostProcessorExcludeClasses the classes to set
98  	 */
99  	public void setBeanPostProcessorExcludeClasses(Class<?>[] beanPostProcessorExcludeClasses) {
100 		this.beanPostProcessorExcludeClasses = beanPostProcessorExcludeClasses;
101 	}
102 
103 	/**
104 	 * Create an {@link ApplicationContextFactory} from each resource provided
105 	 * in {@link #setResources(Resource[])}.
106 	 *
107 	 * @return an array of {@link ApplicationContextFactory}
108 	 * @throws Exception
109 	 * @see org.springframework.beans.factory.FactoryBean#getObject()
110 	 */
111 	@Override
112 	public Object getObject() throws Exception {
113 
114 		if (resources == null) {
115 			return new ApplicationContextFactory[0];
116 		}
117 
118 		List<ApplicationContextFactory> applicationContextFactories = new ArrayList<ApplicationContextFactory>();
119 		for (Resource resource : resources) {
120 			GenericApplicationContextFactory factory = new GenericApplicationContextFactory(resource);
121 			factory.setCopyConfiguration(copyConfiguration);
122 			if (beanFactoryPostProcessorClasses != null) {
123 				factory.setBeanFactoryPostProcessorClasses(beanFactoryPostProcessorClasses);
124 			}
125 			if (beanPostProcessorExcludeClasses != null) {
126 				factory.setBeanPostProcessorExcludeClasses(beanPostProcessorExcludeClasses);
127 			}
128 			factory.setApplicationContext(applicationContext);
129 			applicationContextFactories.add(factory);
130 		}
131 		return applicationContextFactories.toArray(new ApplicationContextFactory[applicationContextFactories.size()]);
132 	}
133 
134 	/**
135 	 * The type of object returned by this factory - an array of
136 	 * {@link ApplicationContextFactory}.
137 	 *
138 	 * @return array of {@link ApplicationContextFactory}
139 	 * @see FactoryBean#getObjectType()
140 	 */
141 	@Override
142 	public Class<?> getObjectType() {
143 		return ApplicationContextFactory[].class;
144 	}
145 
146 	/**
147 	 * Optimization hint for bean factory.
148 	 * @return true
149 	 * @see FactoryBean#isSingleton()
150 	 */
151 	@Override
152 	public boolean isSingleton() {
153 		return true;
154 	}
155 
156 	/**
157 	 * An application context that can be used as a parent context for all the
158 	 * factories.
159 	 *
160 	 * @param applicationContext the {@link ApplicationContext} to set
161 	 * @throws BeansException
162 	 * @see ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
163 	 */
164 	@Override
165 	public void setApplicationContext(ApplicationContext applicationContext) {
166 		this.applicationContext = applicationContext;
167 	}
168 
169 }