From ad9c858bd2470b1e0644c667056b74a4aec72c24 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Sun, 3 Apr 2011 16:37:24 +0000 Subject: [PATCH] [SPR-6184] Introduced ResourceTypeAwareContextLoader interface and removed dependency on AnnotationConfigContextLoader in TestContext. --- .../test/context/ContextLoader.java | 4 +- .../ResourceTypeAwareContextLoader.java | 42 +++++++++++++++++++ .../test/context/TestContext.java | 12 +++--- .../support/AbstractContextLoader.java | 30 ++++++++++--- .../AnnotationConfigContextLoader.java | 16 +++++++ ...figSpringJUnit4ClassRunnerAppCtxTests.java | 2 +- ...tsConfig.java => PojoAndStringConfig.java} | 2 +- 7 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 org.springframework.test/src/main/java/org/springframework/test/context/ResourceTypeAwareContextLoader.java rename org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/{AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig.java => PojoAndStringConfig.java} (95%) diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java index 5c125c717d3..3371b880e98 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ContextLoader.java @@ -19,8 +19,7 @@ package org.springframework.test.context; import org.springframework.context.ApplicationContext; /** - * Strategy interface for loading an - * {@link ApplicationContext application context}. + * Strategy interface for loading an {@link ApplicationContext application context}. * *

Clients of a ContextLoader should call * {@link #processLocations(Class,String...) processLocations()} prior to @@ -34,6 +33,7 @@ import org.springframework.context.ApplicationContext; * *

Spring provides the following out-of-the-box implementations: *

diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/ResourceTypeAwareContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/ResourceTypeAwareContextLoader.java new file mode 100644 index 00000000000..a3874d9c0ef --- /dev/null +++ b/org.springframework.test/src/main/java/org/springframework/test/context/ResourceTypeAwareContextLoader.java @@ -0,0 +1,42 @@ +/* + * Copyright 2002-2011 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.test.context; + +/** + * TODO Document ResourceTypeAwareContextLoader. + * + * @author Sam Brannen + * @since 3.1 + */ +public interface ResourceTypeAwareContextLoader extends ContextLoader { + + /** + * @return true if this ContextLoader supports + * String-based resource locations + * @see ContextConfiguration#locations() + * @see ContextConfiguration#value() + */ + boolean supportsStringResources(); + + /** + * @return true if this ContextLoader supports + * Class-based resource locations + * @see ContextConfiguration#classes() + */ + boolean supportsClassResources(); + +} diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java index 77dd4a901ec..e741f233417 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/TestContext.java @@ -29,7 +29,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.AttributeAccessorSupport; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.style.ToStringCreator; -import org.springframework.test.context.support.AnnotationConfigContextLoader; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -231,9 +230,9 @@ public class TestContext extends AttributeAccessorSupport { // TODO [SPR-6184] Implement recursive search for configuration classes. // This needs to integrate seamlessly (i.e., analogous yet mutually - // exclusive) with the existing locations search. Furthermore, the - // solution must not depend on an explicit ACCL check. - if (contextLoader instanceof AnnotationConfigContextLoader) { + // exclusive) with the existing locations search. + if ((contextLoader instanceof ResourceTypeAwareContextLoader) + && ((ResourceTypeAwareContextLoader) contextLoader).supportsClassResources()) { ContextConfiguration cc = declaringClass.getAnnotation(annotationType); if (logger.isTraceEnabled()) { @@ -317,11 +316,12 @@ public class TestContext extends AttributeAccessorSupport { */ public ApplicationContext getApplicationContext() { synchronized (this.contextCache) { - ApplicationContext context = this.contextCache.get(contextKeyString(this.locations)); + String contextKeyString = contextKeyString(this.locations); + ApplicationContext context = this.contextCache.get(contextKeyString); if (context == null) { try { context = loadApplicationContext(); - this.contextCache.put(contextKeyString(this.locations), context); + this.contextCache.put(contextKeyString, context); } catch (Exception ex) { throw new IllegalStateException("Failed to load ApplicationContext", ex); 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 0db4bae0e9d..27882beab64 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 @@ -19,6 +19,7 @@ package org.springframework.test.context.support; import org.springframework.context.ApplicationContext; import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.test.context.ContextLoader; +import org.springframework.test.context.ResourceTypeAwareContextLoader; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -37,7 +38,7 @@ import org.springframework.util.StringUtils; * @see #generateDefaultLocations * @see #modifyLocations */ -public abstract class AbstractContextLoader implements ContextLoader { +public abstract class AbstractContextLoader implements ResourceTypeAwareContextLoader { /** * If the supplied locations are null or @@ -58,8 +59,8 @@ public abstract class AbstractContextLoader implements ContextLoader { * @see org.springframework.test.context.ContextLoader#processLocations */ 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); } /** @@ -80,8 +81,8 @@ public abstract class AbstractContextLoader implements ContextLoader { 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 + "/" + - ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix }; + return new String[] { ResourceUtils.CLASSPATH_URL_PREFIX + "/" + + ClassUtils.convertClassNameToResourcePath(clazz.getName()) + suffix }; } /** @@ -119,7 +120,6 @@ public abstract class AbstractContextLoader implements ContextLoader { return modifiedLocations; } - /** * Determine whether or not default resource locations should be * generated if the locations provided to @@ -141,4 +141,22 @@ public abstract class AbstractContextLoader implements ContextLoader { */ protected abstract String getResourceSuffix(); + /** + * TODO Document supportsStringResources() implementation. + * + * @return true + */ + public boolean supportsStringResources() { + return true; + } + + /** + * TODO Document supportsClassResources() implementations. + * + * @return false + */ + public boolean supportsClassResources() { + return false; + } + } diff --git a/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java b/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java index 6c13bb1095f..a8f23ee3ebc 100644 --- a/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java +++ b/org.springframework.test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoader.java @@ -127,4 +127,20 @@ public class AnnotationConfigContextLoader extends AbstractGenericContextLoader return "Config"; } + /** + * @return true + */ + @Override + public boolean supportsClassResources() { + return true; + } + + /** + * @return false + */ + @Override + public boolean supportsStringResources() { + return false; + } + } diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java index 2252a9e2a95..50d1f3a3374 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java +++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests.java @@ -26,7 +26,7 @@ import org.springframework.test.context.support.AnnotationConfigContextLoader; * @author Sam Brannen * @since 3.1 */ -@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig.class, inheritLocations = false) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = PojoAndStringConfig.class) public class AnnotationConfigSpringJUnit4ClassRunnerAppCtxTests extends SpringJUnit4ClassRunnerAppCtxTests { /* all tests are in the parent class. */ } diff --git a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig.java b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java similarity index 95% rename from org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig.java rename to org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java index e72c4c8edab..440f5cbc33c 100644 --- a/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig.java +++ b/org.springframework.test/src/test/java/org/springframework/test/context/junit4/annotation/PojoAndStringConfig.java @@ -28,7 +28,7 @@ import org.springframework.context.annotation.Configuration; * @since 3.1 */ @Configuration -public class AnnotationConfigSpringJUnit4ClassRunnerAppCtxTestsConfig { +public class PojoAndStringConfig { @Bean public Employee employee() {