diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java b/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java
index 2781e4cdf78..207ba69fee8 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/ActiveProfiles.java
@@ -31,8 +31,8 @@ import java.lang.annotation.Target;
*
* @author Sam Brannen
* @since 3.1
+ * @see SmartContextLoader
* @see ContextConfiguration
- * @see ContextLoader
* @see org.springframework.context.ApplicationContext
* @see org.springframework.context.annotation.Profile
*/
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java
index 05e94fe7bbb..c9e92ab89f4 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/MergedContextConfiguration.java
@@ -25,16 +25,33 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
- * TODO [SPR-8386] Document MergedContextConfiguration.
+ * MergedContextConfiguration encapsulates the merged
+ * context configuration declared on a test class and all of its superclasses
+ * via {@link ContextConfiguration @ContextConfiguration} and
+ * {@link ActiveProfiles @ActiveProfiles}.
+ *
+ *
Merged resource locations, configuration classes, and active profiles + * represent all declared values in the test class hierarchy taking into + * consideration the semantics of the + * {@link ContextConfiguration#inheritLocations inheritLocations} and + * {@link ActiveProfiles#inheritProfiles inheritProfiles} flags in + * {@code @ContextConfiguration} and {@code @ActiveProfiles}, respectively. + * + *
A {@link SmartContextLoader} uses MergedContextConfiguration
+ * to load an {@link org.springframework.context.ApplicationContext ApplicationContext}.
*
* @author Sam Brannen
* @since 3.1
* @see ContextConfiguration
* @see ActiveProfiles
* @see ContextConfigurationAttributes
+ * @see SmartContextLoader#loadContext(MergedContextConfiguration)
*/
public class MergedContextConfiguration {
+ private static final String[] EMPTY_STRING_ARRAY = new String[] {};
+ private static final Class>[] EMPTY_CLASS_ARRAY = new Class>[] {};
+
private final Class> testClass;
private final String[] locations;
@@ -49,16 +66,16 @@ public class MergedContextConfiguration {
private static String[] processLocations(String[] locations) {
- return locations == null ? new String[] {} : locations;
+ return locations == null ? EMPTY_STRING_ARRAY : locations;
}
private static Class>[] processClasses(Class>[] classes) {
- return classes == null ? new Class>[] {} : classes;
+ return classes == null ? EMPTY_CLASS_ARRAY : classes;
}
private static String[] processActiveProfiles(String[] activeProfiles) {
if (activeProfiles == null) {
- return new String[] {};
+ return EMPTY_STRING_ARRAY;
}
// Active profiles must be unique and sorted in order to support proper
@@ -69,7 +86,7 @@ public class MergedContextConfiguration {
}
/**
- * Generates a context key from the supplied values.
+ * Generate a context key from the supplied values.
*/
private static String generateContextKey(String[] locations, Class>[] classes, String[] activeProfiles,
ContextLoader contextLoader) {
@@ -84,7 +101,18 @@ public class MergedContextConfiguration {
}
/**
- * TODO Document MergedContextConfiguration constructor.
+ * Create a new MergedContextConfiguration instance for the
+ * supplied {@link Class test class}, resource locations, configuration
+ * classes, active profiles, and {@link ContextLoader}.
+ *
If a null value is supplied for locations,
+ * classes, or activeProfiles an empty array will
+ * be stored instead. Furthermore, active profiles will be sorted, and duplicate
+ * profiles will be removed.
+ * @param testClass the test class for which the configuration was merged
+ * @param locations the merged resource locations
+ * @param classes the merged configuration classes
+ * @param activeProfiles the merged active bean definition profiles
+ * @param contextLoader the resolved ContextLoader
*/
public MergedContextConfiguration(Class> testClass, String[] locations, Class>[] classes,
String[] activeProfiles, ContextLoader contextLoader) {
@@ -97,49 +125,60 @@ public class MergedContextConfiguration {
}
/**
- * TODO Document getTestClass().
+ * Get the {@link Class test class} associated with this
+ * MergedContextConfiguration.
*/
public Class> getTestClass() {
return this.testClass;
}
/**
- * TODO Document getLocations().
+ * Get the merged resource locations for the
+ * {@link #getTestClass() test class}.
*/
public String[] getLocations() {
return this.locations;
}
/**
- * TODO Document getClasses().
+ * Get the merged configuration classes for the
+ * {@link #getTestClass() test class}.
*/
public Class>[] getClasses() {
return this.classes;
}
/**
- * TODO Document getActiveProfiles().
+ * Get the merged active bean definition profiles for the
+ * {@link #getTestClass() test class}.
*/
public String[] getActiveProfiles() {
return this.activeProfiles;
}
/**
- * TODO Document getContextLoader().
+ * Get the resolved {@link ContextLoader} for the
+ * {@link #getTestClass() test class}.
*/
public ContextLoader getContextLoader() {
return this.contextLoader;
}
/**
- * TODO Document getContextKey().
+ * Get the unique context key for all properties of this
+ * MergedContextConfiguration excluding the
+ * {@link #getTestClass() test class}.
+ *
Intended to be used for caching an
+ * {@link org.springframework.context.ApplicationContext ApplicationContext}
+ * that was loaded using properties of this MergedContextConfiguration.
*/
public String getContextKey() {
return this.contextKey;
}
/**
- * TODO Document overridden toString().
+ * Provide a String representation of the test class, merged context
+ * configuration, and context key.
*/
@Override
public String toString() {
diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java
index 10bdd556265..ee062096fab 100644
--- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java
+++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AbstractContextLoader.java
@@ -41,24 +41,25 @@ import org.springframework.util.StringUtils;
*/
public abstract class AbstractContextLoader implements SmartContextLoader {
+ private static final String SLASH = "/";
+
+
// --- SmartContextLoader -----------------------------------------------
/**
- * Determine whether or not default resource locations should be
- * generated if the locations provided to
- * {@link #processLocations(Class,String...) processLocations()} are
- * null or empty.
- *
Can be overridden by subclasses to change the default behavior.
- * @return always true by default
+ * TODO Document generatesDefaults() implementation.
*
- * @see SmartContextLoader#generatesDefaults
+ * @see org.springframework.test.context.SmartContextLoader#generatesDefaults()
+ * @see #isGenerateDefaultLocations()
*/
public boolean generatesDefaults() {
return isGenerateDefaultLocations();
}
/**
- * TODO Document processContextConfiguration().
+ * TODO Document processContextConfiguration() implementation.
+ *
+ * @see #processLocations(Class, String...)
*/
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
String[] processedLocations = processLocations(configAttributes.getDeclaringClass(),
@@ -110,7 +111,11 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
Assert.notNull(clazz, "Class must not be null");
String suffix = getResourceSuffix();
Assert.hasText(suffix, "Resource suffix must not be empty");
- return new String[] { ResourceUtils.CLASSPATH_URL_PREFIX + "/"
+
+ // TODO Adhere to SmartContextLoader contract: verify existence of
+ // default and return an empty array if non-existent, in which case a
+ // warning should be logged as well.
+ return new String[] { ResourceUtils.CLASSPATH_URL_PREFIX + SLASH
+ ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix };
}
@@ -135,12 +140,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
String[] modifiedLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
String path = locations[i];
- if (path.startsWith("/")) {
+ if (path.startsWith(SLASH)) {
modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
}
else if (!ResourcePatternUtils.isUrl(path)) {
- modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + "/"
- + StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + "/" + path);
+ modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH
+ + StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path);
}
else {
modifiedLocations[i] = StringUtils.cleanPath(path);