KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > test > AbstractSingleSpringContextTests


1 /*
2  * Copyright 2002-2007 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;
18
19 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
20 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
21 import org.springframework.context.ConfigurableApplicationContext;
22 import org.springframework.context.support.GenericApplicationContext;
23 import org.springframework.util.ClassUtils;
24 import org.springframework.util.ResourceUtils;
25 import org.springframework.util.StringUtils;
26
27 /**
28  * Abstract JUnit test class that holds and exposes a single Spring
29  * {@link org.springframework.context.ApplicationContext ApplicationContext}.
30  *
31  * <p>This class will cache contexts based on a <i>context key</i>: normally the
32  * config locations String array describing the Spring resource descriptors making
33  * up the context. Unless the {@link #setDirty()} method is called by a test, the
34  * context will not be reloaded, even across different subclasses of this test.
35  * This is particularly beneficial if your context is slow to construct, for example
36  * if you are using Hibernate and the time taken to load the mappings is an issue.
37  *
38  * <p>For such standard usage, simply override the {@link #getConfigLocations()}
39  * method and provide the desired config files.
40  *
41  * <p>If you don't want to load a standard context from an array of config locations,
42  * you can override the {@link #contextKey()} method. In conjunction with this you
43  * typically need to override the {@link #loadContext(Object)} method, which by
44  * default loads the locations specified in the {@link #getConfigLocations()} method.
45  *
46  * <p><b>WARNING:</b> When doing integration tests from within Eclipse, only use
47  * classpath resource URLs. Else, you may see misleading failures when changing
48  * context locations.
49  *
50  * @author Juergen Hoeller
51  * @author Rod Johnson
52  * @since 2.0
53  * @see #getConfigLocations()
54  * @see #contextKey()
55  * @see #loadContext(Object)
56  * @see #getApplicationContext()
57  */

58 public abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests {
59
60     /** Application context this test will run against */
61     protected ConfigurableApplicationContext applicationContext;
62
63     private int loadCount = 0;
64
65
66     /**
67      * Default constructor for AbstractDependencyInjectionSpringContextTests.
68      */

69     public AbstractSingleSpringContextTests() {
70     }
71
72     /**
73      * Constructor for AbstractDependencyInjectionSpringContextTests with a JUnit name.
74      * @param name the name of this text fixture
75      */

76     public AbstractSingleSpringContextTests(String JavaDoc name) {
77         super(name);
78     }
79
80
81     /**
82      * This implementation is final.
83      * Override <code>onSetUp</code> for custom behavior.
84      * @see #onSetUp()
85      */

86     protected final void setUp() throws Exception JavaDoc {
87         this.applicationContext = getContext(contextKey());
88         prepareTestInstance();
89         onSetUp();
90     }
91
92     /**
93      * Prepare this test instance, for example populating its fields.
94      * The context has already been loaded at the time of this callback.
95      * <p>The default implementation does nothing.
96      * @throws Exception in case of preparation failure
97      */

98     protected void prepareTestInstance() throws Exception JavaDoc {
99     }
100
101     /**
102      * Subclasses can override this method in place of the
103      * <code>setUp()</code> method, which is final in this class.
104      * This implementation does nothing.
105      * @throws Exception simply let any exception propagate
106      */

107     protected void onSetUp() throws Exception JavaDoc {
108     }
109
110     /**
111      * Called to say that the "applicationContext" instance variable is dirty and
112      * should be reloaded. We need to do this if a test has modified the context
113      * (for example, by replacing a bean definition).
114      */

115     protected void setDirty() {
116         setDirty(contextKey());
117     }
118
119     /**
120      * This implementation is final.
121      * Override <code>onTearDown</code> for custom behavior.
122      * @see #onTearDown()
123      */

124     protected final void tearDown() throws Exception JavaDoc {
125         onTearDown();
126     }
127
128     /**
129      * Subclasses can override this to add custom behavior on teardown.
130      * @throws Exception simply let any exception propagate
131      */

132     protected void onTearDown() throws Exception JavaDoc {
133     }
134
135
136     /**
137      * Return a key for this context. Default is the config location array
138      * as determined by {@link #getConfigLocations()}.
139      * <p>If you override this method, you will typically have to override
140      * {@link #loadContext(Object)} as well, being able to handle the key type
141      * that this method returns.
142      * @return the context key
143      * @see #getConfigLocations()
144      */

145     protected Object JavaDoc contextKey() {
146         return getConfigLocations();
147     }
148
149     /**
150      * This implementation assumes a key of type String array and loads
151      * a context from the given locations.
152      * <p>If you override {@link #contextKey()}, you will typically have to
153      * override this method as well, being able to handle the key type
154      * that <code>contextKey()</code> returns.
155      * @see #getConfigLocations()
156      */

157     protected ConfigurableApplicationContext loadContext(Object JavaDoc key) throws Exception JavaDoc {
158         return loadContextLocations((String JavaDoc[]) key);
159     }
160
161     /**
162      * Load a Spring ApplicationContext from the given config locations.
163      * <p>The default implementation creates a standard
164      * {@link #createApplicationContext GenericApplicationContext},
165      * allowing for customizing the internal bean factory through
166      * {@link #customizeBeanFactory}.
167      * @param locations the config locations (as Spring resource locations,
168      * e.g. full classpath locations or any kind of URL)
169      * @return the corresponding ApplicationContext instance (potentially cached)
170      * @throws Exception if context loading failed
171      * @see #createApplicationContext
172      * @see #customizeBeanFactory
173      */

174     protected ConfigurableApplicationContext loadContextLocations(String JavaDoc[] locations) throws Exception JavaDoc {
175         ++this.loadCount;
176         if (logger.isInfoEnabled()) {
177             logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations));
178         }
179         return createApplicationContext(locations);
180     }
181
182     /**
183      * Create a Spring ApplicationContext for use by this test.
184      * <p>The default implementation creates a standard GenericApplicationContext
185      * instance, populates it from the specified config locations through a
186      * {@link org.springframework.beans.factory.xml.XmlBeanDefinitionReader},
187      * and calls {@link #customizeBeanFactory} to allow for customizing the
188      * context's DefaultListableBeanFactory.
189      * @param locations the config locations (as Spring resource locations,
190      * e.g. full classpath locations or any kind of URL)
191      * @return the GenericApplicationContext instance
192      * @see #loadContextLocations
193      * @see #customizeBeanFactory
194      */

195     protected ConfigurableApplicationContext createApplicationContext(String JavaDoc[] locations) {
196         GenericApplicationContext context = new GenericApplicationContext();
197         customizeBeanFactory(context.getDefaultListableBeanFactory());
198         new XmlBeanDefinitionReader(context).loadBeanDefinitions(locations);
199         context.refresh();
200         return context;
201     }
202
203     /**
204      * Customize the internal bean factory of the ApplicationContext used by this test.
205      * <p>The default implementation is empty. Can be overridden in subclasses
206      * to customize DefaultListableBeanFactory's standard settings.
207      * @param beanFactory the newly created bean factory for this context
208      * @see #loadContextLocations
209      * @see #createApplicationContext
210      * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding
211      * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading
212      * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences
213      * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping
214      */

215     protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
216     }
217
218
219     /**
220      * Subclasses can override this method to return the locations of their
221      * config files, unless they override {@link #contextKey()} and
222      * {@link #loadContext(Object)} instead.
223      * <p>A plain path will be treated as class path location, e.g.:
224      * "org/springframework/whatever/foo.xml". Note however that you may prefix path
225      * locations with standard Spring resource prefixes. Therefore, a config location
226      * path prefixed with "classpath:" with behave the same as a plain path, but a
227      * config location such as "file:/some/path/path/location/appContext.xml" will
228      * be treated as a filesystem location.
229      * <p>The default implementation builds config locations for the config paths
230      * specified through {@link #getConfigPaths()}.
231      * @return an array of config locations
232      * @see #getConfigPaths()
233      * @see org.springframework.core.io.ResourceLoader#getResource(String)
234      */

235     protected String JavaDoc[] getConfigLocations() {
236         String JavaDoc[] paths = getConfigPaths();
237         String JavaDoc[] locations = new String JavaDoc[paths.length];
238         for (int i = 0; i < paths.length; i++) {
239             String JavaDoc path = paths[i];
240             if (path.startsWith("/")) {
241                 locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
242             }
243             else {
244                 locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX +
245                         StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path);
246             }
247         }
248         return locations;
249     }
250
251     /**
252      * Subclasses can override this method to return paths to their
253      * config files, relative to the concrete test class.
254      * <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
255      * from the same package that the concrete test class is defined in.
256      * A path starting with a slash is treated as fully qualified class path
257      * location, e.g.: "/org/springframework/whatever/foo.xml".
258      * <p>The default implementation builds an array for the config path
259      * specified through {@link #getConfigPath()}.
260      * @return an array of config locations
261      * @see #getConfigPath()
262      * @see java.lang.Class#getResource(String)
263      */

264     protected String JavaDoc[] getConfigPaths() {
265         String JavaDoc path = getConfigPath();
266         return (path != null ? new String JavaDoc[] {path} : new String JavaDoc[0]);
267     }
268
269     /**
270      * Subclasses can override this method to return a single path to a
271      * config file, relative to the concrete test class.
272      * <p>A plain path, e.g. "context.xml", will be loaded as classpath resource
273      * from the same package that the concrete test class is defined in.
274      * A path starting with a slash is treated as fully qualified class path
275      * location, e.g.: "/org/springframework/whatever/foo.xml".
276      * <p>The default implementation simply returns <code>null</code>.
277      * @return an array of config locations
278      * @see #getConfigPath()
279      * @see java.lang.Class#getResource(String)
280      */

281     protected String JavaDoc getConfigPath() {
282         return null;
283     }
284
285
286     /**
287      * Return the ApplicationContext that this base class manages.
288      */

289     public final ConfigurableApplicationContext getApplicationContext() {
290         return this.applicationContext;
291     }
292
293     /**
294      * Return the current number of context load attempts.
295      */

296     public final int getLoadCount() {
297         return this.loadCount;
298     }
299
300 }
301
Popular Tags