11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 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.
2525
2626import org .springframework .beans .BeanUtils ;
2727import org .springframework .context .ApplicationContext ;
28+ import org .springframework .context .ApplicationContextException ;
2829import org .springframework .context .ApplicationContextInitializer ;
2930import org .springframework .context .ConfigurableApplicationContext ;
3031import org .springframework .core .GenericTypeResolver ;
@@ -86,8 +87,8 @@ public abstract class AbstractContextLoader implements SmartContextLoader {
8687 */
8788 @ Override
8889 public void processContextConfiguration (ContextConfigurationAttributes configAttributes ) {
89- String [] processedLocations = processLocations ( configAttributes . getDeclaringClass (),
90- configAttributes .getLocations ());
90+ String [] processedLocations =
91+ processLocations ( configAttributes . getDeclaringClass (), configAttributes .getLocations ());
9192 configAttributes .setLocations (processedLocations );
9293 }
9394
@@ -135,7 +136,9 @@ protected void prepareContext(ConfigurableApplicationContext context, MergedCont
135136 @ SuppressWarnings ("unchecked" )
136137 private void invokeApplicationContextInitializers (ConfigurableApplicationContext context ,
137138 MergedContextConfiguration mergedConfig ) {
138- Set <Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >>> initializerClasses = mergedConfig .getContextInitializerClasses ();
139+
140+ Set <Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >>> initializerClasses =
141+ mergedConfig .getContextInitializerClasses ();
139142 if (initializerClasses .isEmpty ()) {
140143 // no ApplicationContextInitializers have been declared -> nothing to do
141144 return ;
@@ -145,13 +148,15 @@ private void invokeApplicationContextInitializers(ConfigurableApplicationContext
145148 Class <?> contextClass = context .getClass ();
146149
147150 for (Class <? extends ApplicationContextInitializer <? extends ConfigurableApplicationContext >> initializerClass : initializerClasses ) {
148- Class <?> initializerContextClass = GenericTypeResolver .resolveTypeArgument (initializerClass ,
149- ApplicationContextInitializer .class );
150- Assert .isAssignable (initializerContextClass , contextClass , String .format (
151- "Could not add context initializer [%s] since its generic parameter [%s] "
152- + "is not assignable from the type of application context used by this "
153- + "context loader [%s]: " , initializerClass .getName (), initializerContextClass .getName (),
154- contextClass .getName ()));
151+ Class <?> initializerContextClass =
152+ GenericTypeResolver .resolveTypeArgument (initializerClass , ApplicationContextInitializer .class );
153+ if (initializerContextClass != null && !initializerContextClass .isInstance (context )) {
154+ throw new ApplicationContextException (String .format (
155+ "Could not apply context initializer [%s] since its generic parameter [%s] " +
156+ "is not assignable from the type of application context used by this " +
157+ "context loader: [%s]" , initializerClass .getName (), initializerContextClass .getName (),
158+ contextClass .getName ()));
159+ }
155160 initializerInstances .add ((ApplicationContextInitializer <ConfigurableApplicationContext >) BeanUtils .instantiateClass (initializerClass ));
156161 }
157162
@@ -161,6 +166,7 @@ private void invokeApplicationContextInitializers(ConfigurableApplicationContext
161166 }
162167 }
163168
169+
164170 // --- ContextLoader -------------------------------------------------------
165171
166172 /**
@@ -171,7 +177,6 @@ private void invokeApplicationContextInitializers(ConfigurableApplicationContext
171177 * and the configured {@linkplain #getResourceSuffixes() resource suffixes};
172178 * otherwise, the supplied {@code locations} will be
173179 * {@linkplain #modifyLocations modified} if necessary and returned.
174- *
175180 * @param clazz the class with which the locations are associated: to be
176181 * used when generating default locations
177182 * @param locations the unmodified locations to use for loading the
@@ -186,30 +191,26 @@ private void invokeApplicationContextInitializers(ConfigurableApplicationContext
186191 */
187192 @ Override
188193 public final String [] processLocations (Class <?> clazz , String ... locations ) {
189- return (ObjectUtils .isEmpty (locations ) && isGenerateDefaultLocations ()) ? generateDefaultLocations ( clazz )
190- : modifyLocations (clazz , locations );
194+ return (ObjectUtils .isEmpty (locations ) && isGenerateDefaultLocations ()) ?
195+ generateDefaultLocations ( clazz ) : modifyLocations (clazz , locations );
191196 }
192197
193198 /**
194199 * Generate the default classpath resource locations array based on the
195200 * supplied class.
196- *
197201 * <p>For example, if the supplied class is {@code com.example.MyTest},
198202 * the generated locations will contain a single string with a value of
199203 * {@code "classpath:com/example/MyTest<suffix>"}, where {@code <suffix>}
200204 * is the value of the first configured
201205 * {@linkplain #getResourceSuffixes() resource suffix} for which the
202206 * generated location actually exists in the classpath.
203- *
204207 * <p>As of Spring 3.1, the implementation of this method adheres to the
205208 * contract defined in the {@link SmartContextLoader} SPI. Specifically,
206209 * this method will <em>preemptively</em> verify that the generated default
207210 * location actually exists. If it does not exist, this method will log a
208211 * warning and return an empty array.
209- *
210212 * <p>Subclasses can override this method to implement a different
211213 * <em>default location generation</em> strategy.
212- *
213214 * @param clazz the class for which the default locations are to be generated
214215 * @return an array of default application context resource locations
215216 * @since 2.5
@@ -224,23 +225,22 @@ protected String[] generateDefaultLocations(Class<?> clazz) {
224225 String resourcePath = ClassUtils .convertClassNameToResourcePath (clazz .getName ()) + suffix ;
225226 String prefixedResourcePath = ResourceUtils .CLASSPATH_URL_PREFIX + resourcePath ;
226227 ClassPathResource classPathResource = new ClassPathResource (resourcePath );
227-
228228 if (classPathResource .exists ()) {
229229 if (logger .isInfoEnabled ()) {
230230 logger .info (String .format ("Detected default resource location \" %s\" for test class [%s]" ,
231- prefixedResourcePath , clazz .getName ()));
231+ prefixedResourcePath , clazz .getName ()));
232232 }
233- return new String [] { prefixedResourcePath };
233+ return new String [] {prefixedResourcePath };
234234 }
235235 else if (logger .isDebugEnabled ()) {
236- logger .debug (String .format ("Did not detect default resource location for test class [%s]: "
237- + "%s does not exist" , clazz .getName (), classPathResource ));
236+ logger .debug (String .format ("Did not detect default resource location for test class [%s]: " +
237+ "%s does not exist" , clazz .getName (), classPathResource ));
238238 }
239239 }
240240
241241 if (logger .isInfoEnabled ()) {
242- logger .info (String .format ("Could not detect default resource locations for test class [%s]: "
243- + "no resource found for suffixes %s." , clazz .getName (), ObjectUtils .nullSafeToString (suffixes )));
242+ logger .info (String .format ("Could not detect default resource locations for test class [%s]: " +
243+ "no resource found for suffixes %s." , clazz .getName (), ObjectUtils .nullSafeToString (suffixes )));
244244 }
245245
246246 return EMPTY_STRING_ARRAY ;
@@ -282,36 +282,31 @@ protected boolean isGenerateDefaultLocations() {
282282 }
283283
284284 /**
285- * Get the suffix to append to {@link ApplicationContext} resource
286- * locations when detecting default locations.
287- *
288- * <p>Subclasses must provide an implementation of this method that
289- * returns a single suffix. Alternatively subclasses may provide a
290- * <em>no-op</em> implementation of this method and override
291- * {@link #getResourceSuffixes()} in order to provide multiple custom
292- * suffixes.
293- *
294- * @return the resource suffix; never {@code null} or empty
295- * @since 2.5
296- * @see #generateDefaultLocations(Class)
297- * @see #getResourceSuffixes()
298- */
299- protected abstract String getResourceSuffix ();
300-
301- /**
302- * Get the suffixes to append to {@link ApplicationContext} resource
303- * locations when detecting default locations.
304- *
285+ * Get the suffixes to append to {@link ApplicationContext} resource locations
286+ * when detecting default locations.
305287 * <p>The default implementation simply wraps the value returned by
306288 * {@link #getResourceSuffix()} in a single-element array, but this
307289 * can be overridden by subclasses in order to support multiple suffixes.
308- *
309290 * @return the resource suffixes; never {@code null} or empty
310291 * @since 4.1
311292 * @see #generateDefaultLocations(Class)
312293 */
313294 protected String [] getResourceSuffixes () {
314- return new String [] { getResourceSuffix () };
295+ return new String [] {getResourceSuffix ()};
315296 }
316297
298+ /**
299+ * Get the suffix to append to {@link ApplicationContext} resource locations
300+ * when detecting default locations.
301+ * <p>Subclasses must provide an implementation of this method that returns
302+ * a single suffix. Alternatively subclasses may provide a <em>no-op</em>
303+ * implementation of this method and override {@link #getResourceSuffixes()}
304+ * in order to provide multiple custom suffixes.
305+ * @return the resource suffix; never {@code null} or empty
306+ * @since 2.5
307+ * @see #generateDefaultLocations(Class)
308+ * @see #getResourceSuffixes()
309+ */
310+ protected abstract String getResourceSuffix ();
311+
317312}
0 commit comments