@ -61,11 +61,12 @@ import org.springframework.util.StringUtils;
@@ -61,11 +61,12 @@ import org.springframework.util.StringUtils;
* /
public abstract class AbstractContextLoader implements SmartContextLoader {
private static final Log logger = LogFactory . getLog ( AbstractContextLoader . class ) ;
private static final String [ ] EMPTY_STRING_ARRAY = new String [ 0 ] ;
private static final String SLASH = "/" ;
private static final Log logger = LogFactory . getLog ( AbstractContextLoader . class ) ;
// --- SmartContextLoader -----------------------------------------------
@ -79,24 +80,20 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -79,24 +80,20 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* processed locations are then
* { @link ContextConfigurationAttributes # setLocations ( String [ ] ) set } in
* the supplied configuration attributes .
*
* < p > Can be overridden in subclasses & mdash ; for example , to process
* annotated classes instead of resource locations .
*
* @since 3 . 1
* @see # processLocations ( Class , String . . . )
* /
@Override
public void processContextConfiguration ( ContextConfigurationAttributes configAttributes ) {
String [ ] processedLocations = processLocations ( configAttributes . getDeclaringClass ( ) ,
configAttributes . getLocations ( ) ) ;
String [ ] processedLocations = processLocations ( configAttributes . getDeclaringClass ( ) , configAttributes . getLocations ( ) ) ;
configAttributes . setLocations ( processedLocations ) ;
}
/ * *
* Prepare the { @link ConfigurableApplicationContext } created by this
* { @code SmartContextLoader } < i > before < / i > bean definitions are read .
*
* < p > The default implementation :
* < ul >
* < li > Sets the < em > active bean definition profiles < / em > from the supplied
@ -107,17 +104,15 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -107,17 +104,15 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* { @linkplain ApplicationContextInitializer # initialize invokes each } with the
* given application context . < / li >
* < / ul >
*
* < p > Any { @code ApplicationContextInitializers } implementing
* { @link org . springframework . core . Ordered Ordered } or marked with { @link
* org . springframework . core . annotation . Order @Order } will be sorted appropriately .
*
* @param context the newly created application context
* @param mergedConfig the merged context configuration
* @since 3 . 2
* @see ApplicationContextInitializer # initialize ( ConfigurableApplicationContext )
* @see # loadContext ( MergedContextConfiguration )
* @see ConfigurableApplicationContext # setId
* @since 3 . 2
* /
@SuppressWarnings ( "unchecked" )
protected void prepareContext ( ConfigurableApplicationContext context , MergedContextConfiguration mergedConfig ) {
@ -130,16 +125,17 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -130,16 +125,17 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
return ;
}
final List < ApplicationContextInitializer < ConfigurableApplicationContext > > initializerInstances = new ArrayList < ApplicationContextInitializer < ConfigurableApplicationContext > > ( ) ;
final Class < ? > contextClass = context . getClass ( ) ;
List < ApplicationContextInitializer < ConfigurableApplicationContext > > initializerInstances =
new ArrayList < ApplicationContextInitializer < ConfigurableApplicationContext > > ( ) ;
Class < ? > contextClass = context . getClass ( ) ;
for ( Class < ? extends ApplicationContextInitializer < ? extends ConfigurableApplicationContext > > initializerClass : initializerClasses ) {
Class < ? > initializerContextClass = GenericTypeResolver . resolveTypeArgument ( initializerClass ,
ApplicationContextInitializer . class ) ;
Assert . isAssignable ( initializerContextClass , contextClass , String . format (
"Could not add context initializer [%s] since its generic parameter [%s] "
+ "is not assignable from the type of application context used by this "
+ "context loader [%s]: " , initializerClass . getName ( ) , initializerContextClass . getName ( ) ,
"Could not add context initializer [%s] since its generic parameter [%s] " +
"is not assignable from the type of application context used by this " +
"context loader [%s]: " , initializerClass . getName ( ) , initializerContextClass . getName ( ) ,
contextClass . getName ( ) ) ) ;
initializerInstances . add ( ( ApplicationContextInitializer < ConfigurableApplicationContext > ) BeanUtils . instantiateClass ( initializerClass ) ) ;
}
@ -161,7 +157,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -161,7 +157,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* { @link # getResourceSuffix ( ) resource suffix } ; otherwise , the supplied
* { @code locations } will be { @link # modifyLocations modified } if
* necessary and returned .
*
* @param clazz the class with which the locations are associated : to be
* used when generating default locations
* @param locations the unmodified locations to use for loading the
@ -176,29 +171,25 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -176,29 +171,25 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* /
@Override
public final String [ ] processLocations ( Class < ? > clazz , String . . . locations ) {
return ( ObjectUtils . isEmpty ( locations ) & & isGenerateDefaultLocations ( ) ) ? generateDefaultLocations ( clazz )
: modifyLocations ( clazz , locations ) ;
return ( ObjectUtils . isEmpty ( locations ) & & isGenerateDefaultLocations ( ) ) ?
generateDefaultLocations ( clazz ) : modifyLocations ( clazz , locations ) ;
}
/ * *
* Generate the default classpath resource locations array based on the
* supplied class .
*
* < p > For example , if the supplied class is { @code com . example . MyTest } ,
* the generated locations will contain a single string with a value of
* & quot ; classpath : / com / example / MyTest { @code < suffix > } & quot ; ,
* where { @code < suffix > } is the value of the
* { @link # getResourceSuffix ( ) resource suffix } string .
*
* < p > As of Spring 3 . 1 , the implementation of this method adheres to the
* contract defined in the { @link SmartContextLoader } SPI . Specifically ,
* this method will < em > preemptively < / em > verify that the generated default
* location actually exists . If it does not exist , this method will log a
* warning and return an empty array .
*
* < p > Subclasses can override this method to implement a different
* < em > default location generation < / em > strategy .
*
* @param clazz the class for which the default locations are to be generated
* @return an array of default application context resource locations
* @since 2 . 5
@ -214,23 +205,22 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -214,23 +205,22 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
if ( classPathResource . exists ( ) ) {
if ( logger . isInfoEnabled ( ) ) {
logger . info ( String . format ( "Detected default resource location \"%s\" for test class [%s]. " ,
logger . info ( String . format ( "Detected default resource location \"%s\" for test class [%s]" ,
prefixedResourcePath , clazz . getName ( ) ) ) ;
}
return new String [ ] { prefixedResourcePath } ;
return new String [ ] { prefixedResourcePath } ;
}
// else
else {
if ( logger . isInfoEnabled ( ) ) {
logger . info ( String . format ( "Could not detect default resource locations for test class [%s]: "
+ "%s does not exist. ", clazz . getName ( ) , classPathResource ) ) ;
logger . info ( String . format ( "Could not detect default resource locations for test class [%s]: " +
"%s does not exist " , clazz . getName ( ) , classPathResource ) ) ;
}
return EMPTY_STRING_ARRAY ;
}
}
/ * *
* Generate a modified version of the supplied locations array and return it .
*
* < p > A plain path & mdash ; for example , & quot ; context . xml & quot ; & mdash ; will
* be treated as a classpath resource that is relative to the package in which
* the specified class is defined . A path starting with a slash is treated
@ -240,10 +230,8 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -240,10 +230,8 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* { @link ResourceUtils # CLASSPATH_URL_PREFIX classpath : } ,
* { @link ResourceUtils # FILE_URL_PREFIX file : } , { @code http : } ,
* etc . ) will be added to the results unchanged .
*
* < p > Subclasses can override this method to implement a different
* < em > location modification < / em > strategy .
*
* @param clazz the class with which the locations are associated
* @param locations the resource locations to be modified
* @return an array of modified application context resource locations
@ -255,10 +243,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -255,10 +243,12 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
String path = locations [ i ] ;
if ( path . startsWith ( SLASH ) ) {
modifiedLocations [ i ] = ResourceUtils . CLASSPATH_URL_PREFIX + path ;
} else if ( ! ResourcePatternUtils . isUrl ( path ) ) {
modifiedLocations [ i ] = ResourceUtils . CLASSPATH_URL_PREFIX + SLASH
+ StringUtils . cleanPath ( ClassUtils . classPackageAsResourcePath ( clazz ) + SLASH + path ) ;
} else {
}
else if ( ! ResourcePatternUtils . isUrl ( path ) ) {
modifiedLocations [ i ] = ResourceUtils . CLASSPATH_URL_PREFIX + SLASH +
StringUtils . cleanPath ( ClassUtils . classPackageAsResourcePath ( clazz ) + SLASH + path ) ;
}
else {
modifiedLocations [ i ] = StringUtils . cleanPath ( path ) ;
}
}
@ -269,7 +259,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -269,7 +259,6 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* Determine whether or not < em > default < / em > resource locations should be
* generated if the { @code locations } provided to
* { @link # processLocations ( Class , String . . . ) } are { @code null } or empty .
*
* < p > As of Spring 3 . 1 , the semantics of this method have been overloaded
* to include detection of either default resource locations or default
* configuration classes . Consequently , this method can also be used to
@ -278,9 +267,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -278,9 +267,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
* { @link ContextConfigurationAttributes configuration attributes } supplied
* to { @link # processContextConfiguration ( ContextConfigurationAttributes ) }
* are { @code null } or empty .
*
* < p > Can be overridden by subclasses to change the default behavior .
*
* @return always { @code true } by default
* @since 2 . 5
* /
@ -291,9 +278,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
@@ -291,9 +278,7 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
/ * *
* Get the suffix to append to { @link ApplicationContext } resource locations
* when generating default locations .
*
* < p > Must be implemented by subclasses .
*
* @return the resource suffix ; should not be { @code null } or empty
* @since 2 . 5
* @see # generateDefaultLocations ( Class )