提交 95ae6344 编写于 作者: S Sam Brannen

[SPR-8386] refining JavaDoc for MergedContextConfiguration and related classes.

上级 60078015
...@@ -31,8 +31,8 @@ import java.lang.annotation.Target; ...@@ -31,8 +31,8 @@ import java.lang.annotation.Target;
* *
* @author Sam Brannen * @author Sam Brannen
* @since 3.1 * @since 3.1
* @see SmartContextLoader
* @see ContextConfiguration * @see ContextConfiguration
* @see ContextLoader
* @see org.springframework.context.ApplicationContext * @see org.springframework.context.ApplicationContext
* @see org.springframework.context.annotation.Profile * @see org.springframework.context.annotation.Profile
*/ */
......
...@@ -25,16 +25,33 @@ import org.springframework.util.ObjectUtils; ...@@ -25,16 +25,33 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* TODO [SPR-8386] Document MergedContextConfiguration. * <code>MergedContextConfiguration</code> encapsulates the <em>merged</em>
* context configuration declared on a test class and all of its superclasses
* via {@link ContextConfiguration @ContextConfiguration} and
* {@link ActiveProfiles @ActiveProfiles}.
*
* <p>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.
*
* <p>A {@link SmartContextLoader} uses <code>MergedContextConfiguration</code>
* to load an {@link org.springframework.context.ApplicationContext ApplicationContext}.
* *
* @author Sam Brannen * @author Sam Brannen
* @since 3.1 * @since 3.1
* @see ContextConfiguration * @see ContextConfiguration
* @see ActiveProfiles * @see ActiveProfiles
* @see ContextConfigurationAttributes * @see ContextConfigurationAttributes
* @see SmartContextLoader#loadContext(MergedContextConfiguration)
*/ */
public class 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 Class<?> testClass;
private final String[] locations; private final String[] locations;
...@@ -49,16 +66,16 @@ public class MergedContextConfiguration { ...@@ -49,16 +66,16 @@ public class MergedContextConfiguration {
private static String[] processLocations(String[] locations) { 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) { 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) { private static String[] processActiveProfiles(String[] activeProfiles) {
if (activeProfiles == null) { if (activeProfiles == null) {
return new String[] {}; return EMPTY_STRING_ARRAY;
} }
// Active profiles must be unique and sorted in order to support proper // Active profiles must be unique and sorted in order to support proper
...@@ -69,7 +86,7 @@ public class MergedContextConfiguration { ...@@ -69,7 +86,7 @@ public class MergedContextConfiguration {
} }
/** /**
* Generates a context <code>key</code> from the supplied values. * Generate a context <em>key</em> from the supplied values.
*/ */
private static String generateContextKey(String[] locations, Class<?>[] classes, String[] activeProfiles, private static String generateContextKey(String[] locations, Class<?>[] classes, String[] activeProfiles,
ContextLoader contextLoader) { ContextLoader contextLoader) {
...@@ -84,7 +101,18 @@ public class MergedContextConfiguration { ...@@ -84,7 +101,18 @@ public class MergedContextConfiguration {
} }
/** /**
* TODO Document MergedContextConfiguration constructor. * Create a new <code>MergedContextConfiguration</code> instance for the
* supplied {@link Class test class}, resource locations, configuration
* classes, active profiles, and {@link ContextLoader}.
* <p>If a <code>null</code> value is supplied for <code>locations</code>,
* <code>classes</code>, or <code>activeProfiles</code> 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 <code>ContextLoader</code>
*/ */
public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes, public MergedContextConfiguration(Class<?> testClass, String[] locations, Class<?>[] classes,
String[] activeProfiles, ContextLoader contextLoader) { String[] activeProfiles, ContextLoader contextLoader) {
...@@ -97,49 +125,60 @@ public class MergedContextConfiguration { ...@@ -97,49 +125,60 @@ public class MergedContextConfiguration {
} }
/** /**
* TODO Document getTestClass(). * Get the {@link Class test class} associated with this
* <code>MergedContextConfiguration</code>.
*/ */
public Class<?> getTestClass() { public Class<?> getTestClass() {
return this.testClass; return this.testClass;
} }
/** /**
* TODO Document getLocations(). * Get the merged resource locations for the
* {@link #getTestClass() test class}.
*/ */
public String[] getLocations() { public String[] getLocations() {
return this.locations; return this.locations;
} }
/** /**
* TODO Document getClasses(). * Get the merged configuration classes for the
* {@link #getTestClass() test class}.
*/ */
public Class<?>[] getClasses() { public Class<?>[] getClasses() {
return this.classes; return this.classes;
} }
/** /**
* TODO Document getActiveProfiles(). * Get the merged active bean definition profiles for the
* {@link #getTestClass() test class}.
*/ */
public String[] getActiveProfiles() { public String[] getActiveProfiles() {
return this.activeProfiles; return this.activeProfiles;
} }
/** /**
* TODO Document getContextLoader(). * Get the resolved {@link ContextLoader} for the
* {@link #getTestClass() test class}.
*/ */
public ContextLoader getContextLoader() { public ContextLoader getContextLoader() {
return this.contextLoader; return this.contextLoader;
} }
/** /**
* TODO Document getContextKey(). * Get the unique context key for all properties of this
* <code>MergedContextConfiguration</code> excluding the
* {@link #getTestClass() test class}.
* <p>Intended to be used for caching an
* {@link org.springframework.context.ApplicationContext ApplicationContext}
* that was loaded using properties of this <code>MergedContextConfiguration</code>.
*/ */
public String getContextKey() { public String getContextKey() {
return this.contextKey; return this.contextKey;
} }
/** /**
* TODO Document overridden toString(). * Provide a String representation of the test class, merged context
* configuration, and context key.
*/ */
@Override @Override
public String toString() { public String toString() {
......
...@@ -41,24 +41,25 @@ import org.springframework.util.StringUtils; ...@@ -41,24 +41,25 @@ import org.springframework.util.StringUtils;
*/ */
public abstract class AbstractContextLoader implements SmartContextLoader { public abstract class AbstractContextLoader implements SmartContextLoader {
private static final String SLASH = "/";
// --- SmartContextLoader ----------------------------------------------- // --- SmartContextLoader -----------------------------------------------
/** /**
* Determine whether or not <em>default</em> resource locations should be * TODO Document generatesDefaults() implementation.
* generated if the <code>locations</code> provided to
* {@link #processLocations(Class,String...) processLocations()} are
* <code>null</code> or empty.
* <p>Can be overridden by subclasses to change the default behavior.
* @return always <code>true</code> by default
* *
* @see SmartContextLoader#generatesDefaults * @see org.springframework.test.context.SmartContextLoader#generatesDefaults()
* @see #isGenerateDefaultLocations()
*/ */
public boolean generatesDefaults() { public boolean generatesDefaults() {
return isGenerateDefaultLocations(); return isGenerateDefaultLocations();
} }
/** /**
* TODO Document processContextConfiguration(). * TODO Document processContextConfiguration() implementation.
*
* @see #processLocations(Class, String...)
*/ */
public void processContextConfiguration(ContextConfigurationAttributes configAttributes) { public void processContextConfiguration(ContextConfigurationAttributes configAttributes) {
String[] processedLocations = processLocations(configAttributes.getDeclaringClass(), String[] processedLocations = processLocations(configAttributes.getDeclaringClass(),
...@@ -110,7 +111,11 @@ public abstract class AbstractContextLoader implements SmartContextLoader { ...@@ -110,7 +111,11 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
Assert.notNull(clazz, "Class must not be null"); Assert.notNull(clazz, "Class must not be null");
String suffix = getResourceSuffix(); String suffix = getResourceSuffix();
Assert.hasText(suffix, "Resource suffix must not be empty"); 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 }; + ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix };
} }
...@@ -135,12 +140,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader { ...@@ -135,12 +140,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
String[] modifiedLocations = new String[locations.length]; String[] modifiedLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) { for (int i = 0; i < locations.length; i++) {
String path = locations[i]; String path = locations[i];
if (path.startsWith("/")) { if (path.startsWith(SLASH)) {
modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path; modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path;
} }
else if (!ResourcePatternUtils.isUrl(path)) { else if (!ResourcePatternUtils.isUrl(path)) {
modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + "/" modifiedLocations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + SLASH
+ StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + "/" + path); + StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(clazz) + SLASH + path);
} }
else { else {
modifiedLocations[i] = StringUtils.cleanPath(path); modifiedLocations[i] = StringUtils.cleanPath(path);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册