View Javadoc
1   /*
2    * Copyright 2002-2014 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  
17  package org.springframework.test.web.servlet.setup;
18  
19  import java.io.IOException;
20  import java.lang.annotation.Annotation;
21  import java.util.List;
22  import java.util.Locale;
23  import java.util.Map;
24  import java.util.Set;
25  import javax.servlet.ServletContext;
26  
27  import org.springframework.beans.BeansException;
28  import org.springframework.beans.TypeConverter;
29  import org.springframework.beans.factory.BeanFactory;
30  import org.springframework.beans.factory.NoSuchBeanDefinitionException;
31  import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
32  import org.springframework.beans.factory.config.DependencyDescriptor;
33  import org.springframework.beans.factory.support.StaticListableBeanFactory;
34  import org.springframework.context.ApplicationContext;
35  import org.springframework.context.ApplicationContextAware;
36  import org.springframework.context.ApplicationEvent;
37  import org.springframework.context.MessageSource;
38  import org.springframework.context.MessageSourceResolvable;
39  import org.springframework.context.NoSuchMessageException;
40  import org.springframework.context.support.DelegatingMessageSource;
41  import org.springframework.core.env.Environment;
42  import org.springframework.core.env.StandardEnvironment;
43  import org.springframework.core.io.Resource;
44  import org.springframework.core.io.support.ResourcePatternResolver;
45  import org.springframework.util.ObjectUtils;
46  import org.springframework.web.context.WebApplicationContext;
47  import org.springframework.web.context.support.ServletContextResourcePatternResolver;
48  
49  /**
50   * A mock WebApplicationContext that accepts registrations of object instances.
51   *
52   * <p>As registered object instances are instantiated and initialized
53   * externally, there is no wiring, bean initialization, lifecycle events, as
54   * well as no pre-processing and post-processing hooks typically associated with
55   * beans managed by an {@link ApplicationContext}. Just a simple lookup into a
56   * {@link StaticListableBeanFactory}.
57   *
58   * @author Rossen Stoyanchev
59   * @since 3.2
60   */
61  class StubWebApplicationContext implements WebApplicationContext {
62  
63  	private final ServletContext servletContext;
64  
65  	private final StubBeanFactory beanFactory = new StubBeanFactory();
66  
67  	private final String id = ObjectUtils.identityToString(this);
68  
69  	private final String displayName = ObjectUtils.identityToString(this);
70  
71  	private final long startupDate = System.currentTimeMillis();
72  
73  	private final Environment environment = new StandardEnvironment();
74  
75  	private final MessageSource messageSource = new DelegatingMessageSource();
76  
77  	private final ResourcePatternResolver resourcePatternResolver;
78  
79  
80  	/**
81  	 * Class constructor.
82  	 */
83  	public StubWebApplicationContext(ServletContext servletContext) {
84  		this.servletContext = servletContext;
85  		this.resourcePatternResolver = new ServletContextResourcePatternResolver(servletContext);
86  	}
87  
88  	/**
89  	 * Returns an instance that can initialize {@link ApplicationContextAware} beans.
90  	 */
91  	@Override
92  	public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
93  		return this.beanFactory;
94  	}
95  
96  	@Override
97  	public ServletContext getServletContext() {
98  		return this.servletContext;
99  	}
100 
101 	//---------------------------------------------------------------------
102 	// Implementation of ApplicationContext interface
103 	//---------------------------------------------------------------------
104 
105 	@Override
106 	public String getId() {
107 		return this.id;
108 	}
109 
110 	@Override
111 	public String getApplicationName() {
112 		return "";
113 	}
114 
115 	@Override
116 	public String getDisplayName() {
117 		return this.displayName;
118 	}
119 
120 	@Override
121 	public long getStartupDate() {
122 		return this.startupDate;
123 	}
124 
125 	@Override
126 	public ApplicationContext getParent() {
127 		return null;
128 	}
129 
130 	@Override
131 	public Environment getEnvironment() {
132 		return this.environment ;
133 	}
134 
135 	public void addBean(String name, Object bean) {
136 		this.beanFactory.addBean(name, bean);
137 	}
138 
139 	public void addBeans(List<?> beans) {
140 		for (Object bean : beans) {
141 			String name = bean.getClass().getName() + "#" +  ObjectUtils.getIdentityHexString(bean);
142 			this.beanFactory.addBean(name, bean);
143 		}
144 	}
145 
146 	//---------------------------------------------------------------------
147 	// Implementation of BeanFactory interface
148 	//---------------------------------------------------------------------
149 
150 	@Override
151 	public Object getBean(String name) throws BeansException {
152 		return this.beanFactory.getBean(name);
153 	}
154 
155 	@Override
156 	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
157 		return this.beanFactory.getBean(name, requiredType);
158 	}
159 
160 	@Override
161 	public <T> T getBean(Class<T> requiredType) throws BeansException {
162 		return this.beanFactory.getBean(requiredType);
163 	}
164 
165 	@Override
166 	public Object getBean(String name, Object... args) throws BeansException {
167 		return this.beanFactory.getBean(name, args);
168 	}
169 
170 	@Override
171 	public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
172 		return this.beanFactory.getBean(requiredType, args);
173 	}
174 
175 	@Override
176 	public boolean containsBean(String name) {
177 		return this.beanFactory.containsBean(name);
178 	}
179 
180 	@Override
181 	public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
182 		return this.beanFactory.isSingleton(name);
183 	}
184 
185 	@Override
186 	public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
187 		return this.beanFactory.isPrototype(name);
188 	}
189 
190 	@Override
191 	public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
192 		return this.beanFactory.isTypeMatch(name, targetType);
193 	}
194 
195 	@Override
196 	public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
197 		return this.beanFactory.getType(name);
198 	}
199 
200 	@Override
201 	public String[] getAliases(String name) {
202 		return this.beanFactory.getAliases(name);
203 	}
204 
205 	//---------------------------------------------------------------------
206 	// Implementation of ListableBeanFactory interface
207 	//---------------------------------------------------------------------
208 
209 	@Override
210 	public boolean containsBeanDefinition(String beanName) {
211 		return this.beanFactory.containsBeanDefinition(beanName);
212 	}
213 
214 	@Override
215 	public int getBeanDefinitionCount() {
216 		return this.beanFactory.getBeanDefinitionCount();
217 	}
218 
219 	@Override
220 	public String[] getBeanDefinitionNames() {
221 		return this.beanFactory.getBeanDefinitionNames();
222 	}
223 
224 	@Override
225 	public String[] getBeanNamesForType(Class<?> type) {
226 		return this.beanFactory.getBeanNamesForType(type);
227 	}
228 
229 	@Override
230 	public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
231 		return this.beanFactory.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
232 	}
233 
234 	@Override
235 	public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
236 		return this.beanFactory.getBeansOfType(type);
237 	}
238 
239 	@Override
240 	public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
241 			throws BeansException {
242 
243 		return this.beanFactory.getBeansOfType(type, includeNonSingletons, allowEagerInit);
244 	}
245 
246 	@Override
247 	public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
248 		return this.beanFactory.getBeanNamesForAnnotation(annotationType);
249 	}
250 
251 	@Override
252 	public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
253 			throws BeansException {
254 
255 		return this.beanFactory.getBeansWithAnnotation(annotationType);
256 	}
257 
258 	@Override
259 	public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
260 			throws NoSuchBeanDefinitionException{
261 
262 		return this.beanFactory.findAnnotationOnBean(beanName, annotationType);
263 	}
264 
265 	//---------------------------------------------------------------------
266 	// Implementation of HierarchicalBeanFactory interface
267 	//---------------------------------------------------------------------
268 
269 	@Override
270 	public BeanFactory getParentBeanFactory() {
271 		return null;
272 	}
273 
274 	@Override
275 	public boolean containsLocalBean(String name) {
276 		return this.beanFactory.containsBean(name);
277 	}
278 
279 	//---------------------------------------------------------------------
280 	// Implementation of MessageSource interface
281 	//---------------------------------------------------------------------
282 
283 	@Override
284 	public String getMessage(String code, Object args[], String defaultMessage, Locale locale) {
285 		return this.messageSource.getMessage(code, args, defaultMessage, locale);
286 	}
287 
288 	@Override
289 	public String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {
290 		return this.messageSource.getMessage(code, args, locale);
291 	}
292 
293 	@Override
294 	public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
295 		return this.messageSource.getMessage(resolvable, locale);
296 	}
297 
298 	//---------------------------------------------------------------------
299 	// Implementation of ResourceLoader interface
300 	//---------------------------------------------------------------------
301 
302 	@Override
303 	public ClassLoader getClassLoader() {
304 		return null;
305 	}
306 
307 	@Override
308 	public Resource getResource(String location) {
309 		return this.resourcePatternResolver.getResource(location);
310 	}
311 
312 	//---------------------------------------------------------------------
313 	// Other
314 	//---------------------------------------------------------------------
315 
316 	@Override
317 	public void publishEvent(ApplicationEvent event) {
318 	}
319 
320 	@Override
321 	public Resource[] getResources(String locationPattern) throws IOException {
322 		return this.resourcePatternResolver.getResources(locationPattern);
323 	}
324 
325 
326 	/**
327 	 * An extension of StaticListableBeanFactory that implements
328 	 * AutowireCapableBeanFactory in order to allow bean initialization of
329 	 * {@link ApplicationContextAware} singletons.
330 	 */
331 	private class StubBeanFactory extends StaticListableBeanFactory implements AutowireCapableBeanFactory {
332 
333 		@Override
334 		public Object initializeBean(Object existingBean, String beanName) throws BeansException {
335 			if (existingBean instanceof ApplicationContextAware) {
336 				((ApplicationContextAware) existingBean).setApplicationContext(StubWebApplicationContext.this);
337 			}
338 			return existingBean;
339 		}
340 
341 		@Override
342 		public <T> T createBean(Class<T> beanClass) {
343 			throw new UnsupportedOperationException();
344 		}
345 
346 		@Override
347 		@SuppressWarnings("rawtypes")
348 		public Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) {
349 			throw new UnsupportedOperationException();
350 		}
351 
352 		@Override
353 		@SuppressWarnings("rawtypes")
354 		public Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) {
355 			throw new UnsupportedOperationException();
356 		}
357 
358 		@Override
359 		public void autowireBean(Object existingBean) throws BeansException {
360 			throw new UnsupportedOperationException();
361 		}
362 
363 		@Override
364 		public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) {
365 			throw new UnsupportedOperationException();
366 		}
367 
368 		@Override
369 		public Object configureBean(Object existingBean, String beanName) {
370 			throw new UnsupportedOperationException();
371 		}
372 
373 		@Override
374 		public Object resolveDependency(DependencyDescriptor descriptor, String beanName) {
375 			throw new UnsupportedOperationException();
376 		}
377 
378 		@Override
379 		public Object resolveDependency(DependencyDescriptor descriptor, String beanName,
380 				Set<String> autowiredBeanNames, TypeConverter typeConverter) {
381 			throw new UnsupportedOperationException();
382 		}
383 
384 		@Override
385 		public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
386 			throw new UnsupportedOperationException();
387 		}
388 
389 		@Override
390 		public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
391 			throw new UnsupportedOperationException();
392 		}
393 
394 		@Override
395 		public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
396 			throw new UnsupportedOperationException();
397 		}
398 
399 		@Override
400 		public void destroyBean(Object existingBean) {
401 			throw new UnsupportedOperationException();
402 		}
403 	}
404 
405 }