use of org.springframework.test.context.SmartContextLoader in project spring-framework by spring-projects.
the class AbstractTestContextBootstrapper method buildMergedContextConfiguration.
/**
* Build the {@link MergedContextConfiguration merged context configuration}
* for the supplied {@link Class testClass}, context configuration attributes,
* and parent context configuration.
* @param testClass the test class for which the {@code MergedContextConfiguration}
* should be built (must not be {@code null})
* @param configAttributesList the list of context configuration attributes for the
* specified test class, ordered <em>bottom-up</em> (i.e., as if we were
* traversing up the class hierarchy); never {@code null} or empty
* @param parentConfig the merged context configuration for the parent application
* context in a context hierarchy, or {@code null} if there is no parent
* @param cacheAwareContextLoaderDelegate the cache-aware context loader delegate to
* be passed to the {@code MergedContextConfiguration} constructor
* @param requireLocationsClassesOrInitializers whether locations, classes, or
* initializers are required; typically {@code true} but may be set to {@code false}
* if the configured loader supports empty configuration
* @return the merged context configuration
* @see #resolveContextLoader
* @see ContextLoaderUtils#resolveContextConfigurationAttributes
* @see SmartContextLoader#processContextConfiguration
* @see ContextLoader#processLocations
* @see ActiveProfilesUtils#resolveActiveProfiles
* @see ApplicationContextInitializerUtils#resolveInitializerClasses
* @see MergedContextConfiguration
*/
private MergedContextConfiguration buildMergedContextConfiguration(Class<?> testClass, List<ContextConfigurationAttributes> configAttributesList, MergedContextConfiguration parentConfig, CacheAwareContextLoaderDelegate cacheAwareContextLoaderDelegate, boolean requireLocationsClassesOrInitializers) {
Assert.notEmpty(configAttributesList, "ContextConfigurationAttributes list must not be null or empty");
ContextLoader contextLoader = resolveContextLoader(testClass, configAttributesList);
List<String> locations = new ArrayList<>();
List<Class<?>> classes = new ArrayList<>();
List<Class<?>> initializers = new ArrayList<>();
for (ContextConfigurationAttributes configAttributes : configAttributesList) {
if (logger.isTraceEnabled()) {
logger.trace(String.format("Processing locations and classes for context configuration attributes %s", configAttributes));
}
if (contextLoader instanceof SmartContextLoader) {
SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader;
smartContextLoader.processContextConfiguration(configAttributes);
locations.addAll(0, Arrays.asList(configAttributes.getLocations()));
classes.addAll(0, Arrays.asList(configAttributes.getClasses()));
} else {
String[] processedLocations = contextLoader.processLocations(configAttributes.getDeclaringClass(), configAttributes.getLocations());
locations.addAll(0, Arrays.asList(processedLocations));
// Legacy ContextLoaders don't know how to process classes
}
initializers.addAll(0, Arrays.asList(configAttributes.getInitializers()));
if (!configAttributes.isInheritLocations()) {
break;
}
}
Set<ContextCustomizer> contextCustomizers = getContextCustomizers(testClass, Collections.unmodifiableList(configAttributesList));
Assert.state(!(requireLocationsClassesOrInitializers && areAllEmpty(locations, classes, initializers, contextCustomizers)), () -> String.format("%s was unable to detect defaults, and no ApplicationContextInitializers " + "or ContextCustomizers were declared for context configuration attributes %s", contextLoader.getClass().getSimpleName(), configAttributesList));
MergedTestPropertySources mergedTestPropertySources = TestPropertySourceUtils.buildMergedTestPropertySources(testClass);
MergedContextConfiguration mergedConfig = new MergedContextConfiguration(testClass, StringUtils.toStringArray(locations), ClassUtils.toClassArray(classes), ApplicationContextInitializerUtils.resolveInitializerClasses(configAttributesList), ActiveProfilesUtils.resolveActiveProfiles(testClass), mergedTestPropertySources.getLocations(), mergedTestPropertySources.getProperties(), contextCustomizers, contextLoader, cacheAwareContextLoaderDelegate, parentConfig);
return processMergedContextConfiguration(mergedConfig);
}
use of org.springframework.test.context.SmartContextLoader in project spring-framework by spring-projects.
the class DefaultCacheAwareContextLoaderDelegate method loadContextInternal.
/**
* Load the {@code ApplicationContext} for the supplied merged context configuration.
* <p>Supports both the {@link SmartContextLoader} and {@link ContextLoader} SPIs.
* @throws Exception if an error occurs while loading the application context
*/
protected ApplicationContext loadContextInternal(MergedContextConfiguration mergedContextConfiguration) throws Exception {
ContextLoader contextLoader = mergedContextConfiguration.getContextLoader();
Assert.notNull(contextLoader, "Cannot load an ApplicationContext with a NULL 'contextLoader'. " + "Consider annotating your test class with @ContextConfiguration or @ContextHierarchy.");
ApplicationContext applicationContext;
if (contextLoader instanceof SmartContextLoader) {
SmartContextLoader smartContextLoader = (SmartContextLoader) contextLoader;
applicationContext = smartContextLoader.loadContext(mergedContextConfiguration);
} else {
String[] locations = mergedContextConfiguration.getLocations();
Assert.notNull(locations, "Cannot load an ApplicationContext with a NULL 'locations' array. " + "Consider annotating your test class with @ContextConfiguration or @ContextHierarchy.");
applicationContext = contextLoader.loadContext(locations);
}
return applicationContext;
}
use of org.springframework.test.context.SmartContextLoader in project spring-framework by spring-projects.
the class AbstractDelegatingSmartContextLoader method loadContext.
/**
* Delegates to an appropriate candidate {@code SmartContextLoader} to load
* an {@link ApplicationContext}.
* <p>Delegation is based on explicit knowledge of the implementations of the
* default loaders for {@linkplain #getXmlLoader() XML configuration files and
* Groovy scripts} and {@linkplain #getAnnotationConfigLoader() annotated classes}.
* Specifically, the delegation algorithm is as follows:
* <ul>
* <li>If the resource locations in the supplied {@code MergedContextConfiguration}
* are not empty and the annotated classes are empty,
* the XML-based loader will load the {@code ApplicationContext}.</li>
* <li>If the annotated classes in the supplied {@code MergedContextConfiguration}
* are not empty and the resource locations are empty,
* the annotation-based loader will load the {@code ApplicationContext}.</li>
* </ul>
* @param mergedConfig the merged context configuration to use to load the application context
* @throws IllegalArgumentException if the supplied merged configuration is {@code null}
* @throws IllegalStateException if neither candidate loader is capable of loading an
* {@code ApplicationContext} from the supplied merged context configuration
*/
@Override
public ApplicationContext loadContext(MergedContextConfiguration mergedConfig) throws Exception {
Assert.notNull(mergedConfig, "mergedConfig must not be null");
List<SmartContextLoader> candidates = Arrays.asList(getXmlLoader(), getAnnotationConfigLoader());
Assert.state(!(mergedConfig.hasLocations() && mergedConfig.hasClasses()), () -> String.format("Neither %s nor %s supports loading an ApplicationContext from %s: " + "declare either 'locations' or 'classes' but not both.", name(getXmlLoader()), name(getAnnotationConfigLoader()), mergedConfig));
for (SmartContextLoader loader : candidates) {
// can, let it; otherwise, keep iterating.
if (supports(loader, mergedConfig)) {
return delegateLoading(loader, mergedConfig);
}
}
// loader.
if (!mergedConfig.getContextInitializerClasses().isEmpty() || !mergedConfig.getContextCustomizers().isEmpty()) {
return delegateLoading(getAnnotationConfigLoader(), mergedConfig);
}
// else...
throw new IllegalStateException(String.format("Neither %s nor %s was able to load an ApplicationContext from %s.", name(getXmlLoader()), name(getAnnotationConfigLoader()), mergedConfig));
}
Aggregations