11/*
2- * Copyright 2002-2013 the original author or authors.
2+ * Copyright 2002-2014 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3434/**
3535 * {@code MergedContextConfiguration} encapsulates the <em>merged</em>
3636 * context configuration declared on a test class and all of its superclasses
37- * via {@link ContextConfiguration @ContextConfiguration} and
38- * {@link ActiveProfiles @ActiveProfiles}.
37+ * via {@link ContextConfiguration @ContextConfiguration},
38+ * {@link ActiveProfiles @ActiveProfiles}, and
39+ * {@link TestPropertySource @TestPropertySource}.
3940 *
40- * <p>Merged resource locations, annotated classes, and active profiles
41- * represent all declared values in the test class hierarchy taking into
42- * consideration the semantics of the
43- * {@link ContextConfiguration#inheritLocations inheritLocations} and
44- * {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in
45- * {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively.
41+ * <p>Merged context resource locations, annotated classes, active profiles,
42+ * property resource locations, and in-lined properties represent all declared
43+ * values in the test class hierarchy taking into consideration the semantics
44+ * of the {@link ContextConfiguration#inheritLocations},
45+ * {@link ActiveProfiles#inheritProfiles},
46+ * {@link TestPropertySource#inheritLocations}, and
47+ * {@link TestPropertySource#inheritProperties} flags.
4648 *
4749 * <p>A {@link SmartContextLoader} uses {@code MergedContextConfiguration}
4850 * to load an {@link org.springframework.context.ApplicationContext ApplicationContext}.
@@ -73,13 +75,15 @@ public class MergedContextConfiguration implements Serializable {
7375 private final Class <?>[] classes ;
7476 private final Set <Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >>> contextInitializerClasses ;
7577 private final String [] activeProfiles ;
78+ private final String [] propertySourceLocations ;
79+ private final String [] propertySourceProperties ;
7680 private final ContextLoader contextLoader ;
7781 private final CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate ;
7882 private final MergedContextConfiguration parent ;
7983
8084
81- private static String [] processLocations (String [] locations ) {
82- return locations == null ? EMPTY_STRING_ARRAY : locations ;
85+ private static String [] processStrings (String [] array ) {
86+ return array == null ? EMPTY_STRING_ARRAY : array ;
8387 }
8488
8589 private static Class <?>[] processClasses (Class <?>[] classes ) {
@@ -115,20 +119,15 @@ protected static String nullSafeToString(ContextLoader contextLoader) {
115119
116120 /**
117121 * Create a new {@code MergedContextConfiguration} instance for the
118- * supplied test class, resource locations, annotated classes, active
119- * profiles, and {@code ContextLoader}.
120- *
121- * <p>If a {@code null} value is supplied for {@code locations},
122- * {@code classes}, or {@code activeProfiles} an empty array will
123- * be stored instead. Furthermore, active profiles will be sorted, and duplicate
124- * profiles will be removed.
122+ * supplied parameters.
123+ * <p>Delegates to
124+ * {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
125125 *
126126 * @param testClass the test class for which the configuration was merged
127- * @param locations the merged resource locations
127+ * @param locations the merged context resource locations
128128 * @param classes the merged annotated classes
129129 * @param activeProfiles the merged active bean definition profiles
130130 * @param contextLoader the resolved {@code ContextLoader}
131- * @see #MergedContextConfiguration(Class, String[], Class[], Set, String[], ContextLoader)
132131 */
133132 public MergedContextConfiguration (Class <?> testClass , String [] locations , Class <?>[] classes ,
134133 String [] activeProfiles , ContextLoader contextLoader ) {
@@ -137,18 +136,12 @@ public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<
137136
138137 /**
139138 * Create a new {@code MergedContextConfiguration} instance for the
140- * supplied test class, resource locations, annotated classes, context
141- * initializers, active profiles, and {@code ContextLoader}.
142- *
143- * <p>If a {@code null} value is supplied for {@code locations},
144- * {@code classes}, or {@code activeProfiles} an empty array will
145- * be stored instead. If a {@code null} value is supplied for the
146- * {@code contextInitializerClasses} an empty set will be stored instead.
147- * Furthermore, active profiles will be sorted, and duplicate profiles will
148- * be removed.
139+ * supplied parameters.
140+ * <p>Delegates to
141+ * {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
149142 *
150143 * @param testClass the test class for which the configuration was merged
151- * @param locations the merged resource locations
144+ * @param locations the merged context resource locations
152145 * @param classes the merged annotated classes
153146 * @param contextInitializerClasses the merged context initializer classes
154147 * @param activeProfiles the merged active bean definition profiles
@@ -166,19 +159,12 @@ public MergedContextConfiguration(
166159
167160 /**
168161 * Create a new {@code MergedContextConfiguration} instance for the
169- * supplied test class, resource locations, annotated classes, context
170- * initializers, active profiles, {@code ContextLoader}, and parent
171- * configuration.
172- *
173- * <p>If a {@code null} value is supplied for {@code locations},
174- * {@code classes}, or {@code activeProfiles} an empty array will
175- * be stored instead. If a {@code null} value is supplied for the
176- * {@code contextInitializerClasses} an empty set will be stored instead.
177- * Furthermore, active profiles will be sorted, and duplicate profiles will
178- * be removed.
162+ * supplied parameters.
163+ * <p>Delegates to
164+ * {@link #MergedContextConfiguration(Class, String[], Class[], Set, String[], String[], String[], ContextLoader, CacheAwareContextLoaderDelegate, MergedContextConfiguration)}.
179165 *
180166 * @param testClass the test class for which the configuration was merged
181- * @param locations the merged resource locations
167+ * @param locations the merged context resource locations
182168 * @param classes the merged annotated classes
183169 * @param contextInitializerClasses the merged context initializer classes
184170 * @param activeProfiles the merged active bean definition profiles
@@ -195,11 +181,50 @@ public MergedContextConfiguration(
195181 Set <Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >>> contextInitializerClasses ,
196182 String [] activeProfiles , ContextLoader contextLoader ,
197183 CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate , MergedContextConfiguration parent ) {
184+ this (testClass , locations , classes , contextInitializerClasses , activeProfiles , null , null , contextLoader ,
185+ cacheAwareContextLoaderDelegate , parent );
186+ }
187+
188+ /**
189+ * Create a new {@code MergedContextConfiguration} instance for the
190+ * supplied parameters.
191+ *
192+ * <p>If a {@code null} value is supplied for {@code locations},
193+ * {@code classes}, {@code activeProfiles}, {@code propertySourceLocations},
194+ * or {@code propertySourceProperties} an empty array will be stored instead.
195+ * If a {@code null} value is supplied for the
196+ * {@code contextInitializerClasses} an empty set will be stored instead.
197+ * Furthermore, active profiles will be sorted, and duplicate profiles
198+ * will be removed.
199+ *
200+ * @param testClass the test class for which the configuration was merged
201+ * @param locations the merged context resource locations
202+ * @param classes the merged annotated classes
203+ * @param contextInitializerClasses the merged context initializer classes
204+ * @param activeProfiles the merged active bean definition profiles
205+ * @param propertySourceLocations the merged {@code PropertySource} locations
206+ * @param propertySourceProperties the merged {@code PropertySource} properties
207+ * @param contextLoader the resolved {@code ContextLoader}
208+ * @param cacheAwareContextLoaderDelegate a cache-aware context loader
209+ * delegate with which to retrieve the parent context
210+ * @param parent the parent configuration or {@code null} if there is no parent
211+ * @since 4.1
212+ */
213+ public MergedContextConfiguration (
214+ Class <?> testClass ,
215+ String [] locations ,
216+ Class <?>[] classes ,
217+ Set <Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >>> contextInitializerClasses ,
218+ String [] activeProfiles , String [] propertySourceLocations , String [] propertySourceProperties ,
219+ ContextLoader contextLoader , CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate ,
220+ MergedContextConfiguration parent ) {
198221 this .testClass = testClass ;
199- this .locations = processLocations (locations );
222+ this .locations = processStrings (locations );
200223 this .classes = processClasses (classes );
201224 this .contextInitializerClasses = processContextInitializerClasses (contextInitializerClasses );
202225 this .activeProfiles = processActiveProfiles (activeProfiles );
226+ this .propertySourceLocations = processStrings (propertySourceLocations );
227+ this .propertySourceProperties = processStrings (propertySourceProperties );
203228 this .contextLoader = contextLoader ;
204229 this .cacheAwareContextLoaderDelegate = cacheAwareContextLoaderDelegate ;
205230 this .parent = parent ;
@@ -213,7 +238,10 @@ public Class<?> getTestClass() {
213238 }
214239
215240 /**
216- * Get the merged resource locations for the {@linkplain #getTestClass() test class}.
241+ * Get the merged resource locations for {@code ApplicationContext}
242+ * configuration files for the {@linkplain #getTestClass() test class}.
243+ * <p>Context resource locations typically represent XML configuration
244+ * files or Groovy scripts.
217245 */
218246 public String [] getLocations () {
219247 return locations ;
@@ -228,7 +256,7 @@ public Class<?>[] getClasses() {
228256
229257 /**
230258 * Determine if this {@code MergedContextConfiguration} instance has
231- * path-based resource locations.
259+ * path-based context resource locations.
232260 *
233261 * @return {@code true} if the {@link #getLocations() locations} array is not empty
234262 * @since 4.0.4
@@ -254,7 +282,7 @@ public boolean hasClasses() {
254282
255283 /**
256284 * Determine if this {@code MergedContextConfiguration} instance has
257- * either path-based resource locations or class-based resources.
285+ * either path-based context resource locations or class-based resources.
258286 *
259287 * @return {@code true} if either the {@link #getLocations() locations}
260288 * or the {@link #getClasses() classes} array is not empty
@@ -275,12 +303,36 @@ public Set<Class<? extends ApplicationContextInitializer<? extends ConfigurableA
275303 }
276304
277305 /**
278- * Get the merged active bean definition profiles for the {@linkplain #getTestClass() test class}.
306+ * Get the merged active bean definition profiles for the
307+ * {@linkplain #getTestClass() test class}.
308+ * @see ActiveProfiles
279309 */
280310 public String [] getActiveProfiles () {
281311 return activeProfiles ;
282312 }
283313
314+ /**
315+ * Get the merged resource locations for test {@code PropertySources} for the
316+ * {@linkplain #getTestClass() test class}.
317+ * @see TestPropertySource#locations
318+ * @see java.util.Properties
319+ */
320+ public String [] getPropertySourceLocations () {
321+ return propertySourceLocations ;
322+ }
323+
324+ /**
325+ * Get the merged test {@code PropertySource} properties for the
326+ * {@linkplain #getTestClass() test class}.
327+ * <p>Properties will be loaded into the {@code Environment}'s set of
328+ * {@code PropertySources}.
329+ * @see TestPropertySource#properties
330+ * @see java.util.Properties
331+ */
332+ public String [] getPropertySourceProperties () {
333+ return propertySourceProperties ;
334+ }
335+
284336 /**
285337 * Get the resolved {@link ContextLoader} for the {@linkplain #getTestClass() test class}.
286338 */
@@ -334,6 +386,8 @@ public int hashCode() {
334386 result = prime * result + Arrays .hashCode (classes );
335387 result = prime * result + contextInitializerClasses .hashCode ();
336388 result = prime * result + Arrays .hashCode (activeProfiles );
389+ result = prime * result + Arrays .hashCode (propertySourceLocations );
390+ result = prime * result + Arrays .hashCode (propertySourceProperties );
337391 result = prime * result + (parent == null ? 0 : parent .hashCode ());
338392 result = prime * result + nullSafeToString (contextLoader ).hashCode ();
339393 return result ;
@@ -345,6 +399,8 @@ public int hashCode() {
345399 * {@linkplain #getClasses() annotated classes},
346400 * {@linkplain #getContextInitializerClasses() context initializer classes},
347401 * {@linkplain #getActiveProfiles() active profiles},
402+ * {@linkplain #getPropertySourceLocations() property source locations},
403+ * {@linkplain #getPropertySourceProperties() property source properties},
348404 * {@linkplain #getParent() parents}, and the fully qualified names of their
349405 * {@link #getContextLoader() ContextLoaders}.
350406 */
@@ -376,6 +432,14 @@ public boolean equals(Object obj) {
376432 return false ;
377433 }
378434
435+ if (!Arrays .equals (this .propertySourceLocations , that .propertySourceLocations )) {
436+ return false ;
437+ }
438+
439+ if (!Arrays .equals (this .propertySourceProperties , that .propertySourceProperties )) {
440+ return false ;
441+ }
442+
379443 if (this .parent == null ) {
380444 if (that .parent != null ) {
381445 return false ;
@@ -396,8 +460,10 @@ else if (!this.parent.equals(that.parent)) {
396460 * Provide a String representation of the {@linkplain #getTestClass() test class},
397461 * {@linkplain #getLocations() locations}, {@linkplain #getClasses() annotated classes},
398462 * {@linkplain #getContextInitializerClasses() context initializer classes},
399- * {@linkplain #getActiveProfiles() active profiles}, the name of the
400- * {@link #getContextLoader() ContextLoader}, and the
463+ * {@linkplain #getActiveProfiles() active profiles},
464+ * {@linkplain #getPropertySourceLocations() property source locations},
465+ * {@linkplain #getPropertySourceProperties() property source properties},
466+ * the name of the {@link #getContextLoader() ContextLoader}, and the
401467 * {@linkplain #getParent() parent configuration}.
402468 */
403469 @ Override
@@ -408,6 +474,8 @@ public String toString() {
408474 .append ("classes" , ObjectUtils .nullSafeToString (classes ))//
409475 .append ("contextInitializerClasses" , ObjectUtils .nullSafeToString (contextInitializerClasses ))//
410476 .append ("activeProfiles" , ObjectUtils .nullSafeToString (activeProfiles ))//
477+ .append ("propertySourceLocations" , ObjectUtils .nullSafeToString (propertySourceLocations ))//
478+ .append ("propertySourceProperties" , ObjectUtils .nullSafeToString (propertySourceProperties ))//
411479 .append ("contextLoader" , nullSafeToString (contextLoader ))//
412480 .append ("parent" , parent )//
413481 .toString ();
0 commit comments