diff --git a/spring-test/src/main/java/org/springframework/test/AbstractDependencyInjectionSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/AbstractDependencyInjectionSpringContextTests.java deleted file mode 100644 index 6229a8d3841..00000000000 --- a/spring-test/src/main/java/org/springframework/test/AbstractDependencyInjectionSpringContextTests.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.LinkedList; -import java.util.List; - -import org.springframework.beans.factory.NoSuchBeanDefinitionException; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.util.Assert; - -/** - *

- * Convenient superclass for JUnit 3.8 based tests depending on a Spring - * context. The test instance itself is populated by Dependency Injection. - *

- *

- * Really for integration testing, not unit testing. You should not - * normally use the Spring container for unit tests: simply populate your POJOs - * in plain JUnit tests! - *

- *

- * This supports two modes of populating the test: - *

- * - * - * @author Rod Johnson - * @author Rob Harrop - * @author Rick Evans - * @author Sam Brannen - * @since 1.1.1 - * @see #setDirty - * @see #contextKey - * @see #getContext - * @see #getConfigLocations - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests}) - */ -@Deprecated -@SuppressWarnings({ "unchecked", "rawtypes" }) -public abstract class AbstractDependencyInjectionSpringContextTests extends AbstractSingleSpringContextTests { - - /** - * Constant that indicates no autowiring at all. - * - * @see #setAutowireMode - */ - public static final int AUTOWIRE_NO = 0; - - /** - * Constant that indicates autowiring bean properties by name. - * - * @see #setAutowireMode - */ - public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME; - - /** - * Constant that indicates autowiring bean properties by type. - * - * @see #setAutowireMode - */ - public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE; - - private boolean populateProtectedVariables = false; - - private int autowireMode = AUTOWIRE_BY_TYPE; - - private boolean dependencyCheck = true; - - private String[] managedVariableNames; - - - /** - * Default constructor for AbstractDependencyInjectionSpringContextTests. - */ - public AbstractDependencyInjectionSpringContextTests() { - } - - /** - * Constructor for AbstractDependencyInjectionSpringContextTests with a - * JUnit name. - * @param name the name of this text fixture - */ - public AbstractDependencyInjectionSpringContextTests(String name) { - super(name); - } - - - /** - * Set whether to populate protected variables of this test case. Default is - * {@code false}. - */ - public final void setPopulateProtectedVariables(boolean populateFields) { - this.populateProtectedVariables = populateFields; - } - - /** - * Return whether to populate protected variables of this test case. - */ - public final boolean isPopulateProtectedVariables() { - return this.populateProtectedVariables; - } - - /** - * Set the autowire mode for test properties set by Dependency Injection. - *

The default is {@link #AUTOWIRE_BY_TYPE}. Can be set to - * {@link #AUTOWIRE_BY_NAME} or {@link #AUTOWIRE_NO} instead. - * @see #AUTOWIRE_BY_TYPE - * @see #AUTOWIRE_BY_NAME - * @see #AUTOWIRE_NO - */ - public final void setAutowireMode(final int autowireMode) { - this.autowireMode = autowireMode; - } - - /** - * Return the autowire mode for test properties set by Dependency Injection. - */ - public final int getAutowireMode() { - return this.autowireMode; - } - - /** - * Set whether or not dependency checking should be performed for test - * properties set by Dependency Injection. - *

The default is {@code true}, meaning that tests cannot be run - * unless all properties are populated. - */ - public final void setDependencyCheck(final boolean dependencyCheck) { - this.dependencyCheck = dependencyCheck; - } - - /** - * Return whether or not dependency checking should be performed for test - * properties set by Dependency Injection. - */ - public final boolean isDependencyCheck() { - return this.dependencyCheck; - } - - /** - * Prepare this test instance, injecting dependencies into its protected - * fields and its bean properties. - *

Note: if the {@link ApplicationContext} for this test instance has not - * been configured (e.g., is {@code null}), dependency injection - * will naturally not be performed, but an informational - * message will be written to the log. - * @see #injectDependencies() - */ - protected void prepareTestInstance() throws Exception { - if (getApplicationContext() == null) { - if (this.logger.isInfoEnabled()) { - this.logger.info("ApplicationContext has not been configured for test [" + getClass().getName() - + "]: dependency injection will NOT be performed."); - } - } - else { - injectDependencies(); - } - } - - /** - * Inject dependencies into 'this' instance (that is, this test instance). - *

The default implementation populates protected variables if the - * {@link #populateProtectedVariables() appropriate flag is set}, else uses - * autowiring if autowiring is switched on (which it is by default). - *

Override this method if you need full control over how dependencies are - * injected into the test instance. - * @throws Exception in case of dependency injection failure - * @throws IllegalStateException if the {@link ApplicationContext} for this - * test instance has not been configured - * @see #populateProtectedVariables() - */ - @SuppressWarnings("javadoc") - protected void injectDependencies() throws Exception { - Assert.state(getApplicationContext() != null, - "injectDependencies() called without first configuring an ApplicationContext"); - if (isPopulateProtectedVariables()) { - if (this.managedVariableNames == null) { - initManagedVariableNames(); - } - populateProtectedVariables(); - } - getApplicationContext().getBeanFactory().autowireBeanProperties(this, getAutowireMode(), isDependencyCheck()); - } - - private void initManagedVariableNames() throws IllegalAccessException { - List managedVarNames = new LinkedList(); - Class clazz = getClass(); - do { - Field[] fields = clazz.getDeclaredFields(); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Found " + fields.length + " fields on " + clazz); - } - for (int i = 0; i < fields.length; i++) { - Field field = fields[i]; - field.setAccessible(true); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Candidate field: " + field); - } - if (isProtectedInstanceField(field)) { - Object oldValue = field.get(this); - if (oldValue == null) { - managedVarNames.add(field.getName()); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Added managed variable '" + field.getName() + "'"); - } - } - else { - if (this.logger.isDebugEnabled()) { - this.logger.debug("Rejected managed variable '" + field.getName() + "'"); - } - } - } - } - clazz = clazz.getSuperclass(); - } while (!clazz.equals(AbstractDependencyInjectionSpringContextTests.class)); - - this.managedVariableNames = (String[]) managedVarNames.toArray(new String[managedVarNames.size()]); - } - - private boolean isProtectedInstanceField(Field field) { - int modifiers = field.getModifiers(); - return !Modifier.isStatic(modifiers) && Modifier.isProtected(modifiers); - } - - private void populateProtectedVariables() throws IllegalAccessException { - for (int i = 0; i < this.managedVariableNames.length; i++) { - String varName = this.managedVariableNames[i]; - Object bean = null; - try { - Field field = findField(getClass(), varName); - bean = getApplicationContext().getBean(varName, field.getType()); - field.setAccessible(true); - field.set(this, bean); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Populated field: " + field); - } - } - catch (NoSuchFieldException ex) { - if (this.logger.isWarnEnabled()) { - this.logger.warn("No field with name '" + varName + "'"); - } - } - catch (NoSuchBeanDefinitionException ex) { - if (this.logger.isWarnEnabled()) { - this.logger.warn("No bean with name '" + varName + "'"); - } - } - } - } - - private Field findField(Class clazz, String name) throws NoSuchFieldException { - try { - return clazz.getDeclaredField(name); - } - catch (NoSuchFieldException ex) { - Class superclass = clazz.getSuperclass(); - if (superclass != AbstractSpringContextTests.class) { - return findField(superclass, name); - } - else { - throw ex; - } - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/AbstractSingleSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/AbstractSingleSpringContextTests.java deleted file mode 100644 index 0d5d0784801..00000000000 --- a/spring-test/src/main/java/org/springframework/test/AbstractSingleSpringContextTests.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import org.springframework.beans.factory.support.BeanDefinitionReader; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.util.ClassUtils; -import org.springframework.util.ResourceUtils; -import org.springframework.util.StringUtils; - -/** - *

- * Abstract JUnit 3.8 test class that holds and exposes a single Spring - * {@link org.springframework.context.ApplicationContext ApplicationContext}. - *

- *

- * This class will cache contexts based on a context key: normally the - * config locations String array describing the Spring resource descriptors - * making up the context. Unless the {@link #setDirty()} method is called by a - * test, the context will not be reloaded, even across different subclasses of - * this test. This is particularly beneficial if your context is slow to - * construct, for example if you are using Hibernate and the time taken to load - * the mappings is an issue. - *

- *

- * For such standard usage, simply override the {@link #getConfigLocations()} - * method and provide the desired config files. For alternative configuration - * options, see {@link #getConfigPath()} and {@link #getConfigPaths()}. - *

- *

- * If you don't want to load a standard context from an array of config - * locations, you can override the {@link #contextKey()} method. In conjunction - * with this you typically need to override the {@link #loadContext(Object)} - * method, which by default loads the locations specified in the - * {@link #getConfigLocations()} method. - *

- *

- * WARNING: When doing integration tests from within Eclipse, only use - * classpath resource URLs. Else, you may see misleading failures when changing - * context locations. - *

- * - * @author Juergen Hoeller - * @author Rod Johnson - * @author Sam Brannen - * @since 2.0 - * @see #getConfigLocations() - * @see #contextKey() - * @see #loadContext(Object) - * @see #getApplicationContext() - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests}) - */ -@Deprecated -public abstract class AbstractSingleSpringContextTests extends AbstractSpringContextTests { - - /** Application context this test will run against */ - protected ConfigurableApplicationContext applicationContext; - - private int loadCount = 0; - - - /** - * Default constructor for AbstractSingleSpringContextTests. - */ - public AbstractSingleSpringContextTests() { - } - - /** - * Constructor for AbstractSingleSpringContextTests with a JUnit name. - * @param name the name of this text fixture - */ - public AbstractSingleSpringContextTests(String name) { - super(name); - } - - /** - * This implementation is final. Override {@code onSetUp} for custom behavior. - * @see #onSetUp() - */ - protected final void setUp() throws Exception { - // lazy load, in case getApplicationContext() has not yet been called. - if (this.applicationContext == null) { - this.applicationContext = getContext(contextKey()); - } - prepareTestInstance(); - onSetUp(); - } - - /** - * Prepare this test instance, for example populating its fields. - * The context has already been loaded at the time of this callback. - *

The default implementation does nothing. - * @throws Exception in case of preparation failure - */ - protected void prepareTestInstance() throws Exception { - } - - /** - * Subclasses can override this method in place of the {@code setUp()} - * method, which is final in this class. - *

The default implementation does nothing. - * @throws Exception simply let any exception propagate - */ - protected void onSetUp() throws Exception { - } - - /** - * Called to say that the "applicationContext" instance variable is dirty - * and should be reloaded. We need to do this if a test has modified the - * context (for example, by replacing a bean definition). - */ - protected void setDirty() { - setDirty(contextKey()); - } - - /** - * This implementation is final. Override {@code onTearDown} for - * custom behavior. - * @see #onTearDown() - */ - protected final void tearDown() throws Exception { - onTearDown(); - } - - /** - * Subclasses can override this to add custom behavior on teardown. - * @throws Exception simply let any exception propagate - */ - protected void onTearDown() throws Exception { - } - - /** - * Return a key for this context. Default is the config location array as - * determined by {@link #getConfigLocations()}. - *

If you override this method, you will typically have to override - * {@link #loadContext(Object)} as well, being able to handle the key type - * that this method returns. - * @return the context key - * @see #getConfigLocations() - */ - protected Object contextKey() { - return getConfigLocations(); - } - - /** - * This implementation assumes a key of type String array and loads a - * context from the given locations. - *

If you override {@link #contextKey()}, you will typically have to - * override this method as well, being able to handle the key type that - * {@code contextKey()} returns. - * @see #getConfigLocations() - */ - protected ConfigurableApplicationContext loadContext(Object key) throws Exception { - return loadContextLocations((String[]) key); - } - - /** - * Load a Spring ApplicationContext from the given config locations. - *

The default implementation creates a standard - * {@link #createApplicationContext GenericApplicationContext}, allowing - * for customizing the internal bean factory through - * {@link #customizeBeanFactory}. - * @param locations the config locations (as Spring resource locations, - * e.g. full classpath locations or any kind of URL) - * @return the corresponding ApplicationContext instance (potentially cached) - * @throws Exception if context loading failed - * @see #createApplicationContext(String[]) - */ - protected ConfigurableApplicationContext loadContextLocations(String[] locations) throws Exception { - ++this.loadCount; - if (this.logger.isInfoEnabled()) { - this.logger.info("Loading context for locations: " + StringUtils.arrayToCommaDelimitedString(locations)); - } - return createApplicationContext(locations); - } - - /** - * Create a Spring {@link ConfigurableApplicationContext} for use by this test. - *

The default implementation creates a standard {@link GenericApplicationContext} - * instance, calls the {@link #prepareApplicationContext} prepareApplicationContext} - * method and the {@link #customizeBeanFactory customizeBeanFactory} method to allow - * for customizing the context and its DefaultListableBeanFactory, populates the - * context from the specified config {@code locations} through the configured - * {@link #createBeanDefinitionReader(GenericApplicationContext) BeanDefinitionReader}, - * and finally {@link ConfigurableApplicationContext#refresh() refreshes} the context. - * @param locations the config locations (as Spring resource locations, - * e.g. full classpath locations or any kind of URL) - * @return the GenericApplicationContext instance - * @see #loadContextLocations(String[]) - * @see #customizeBeanFactory(DefaultListableBeanFactory) - * @see #createBeanDefinitionReader(GenericApplicationContext) - */ - protected ConfigurableApplicationContext createApplicationContext(String[] locations) { - GenericApplicationContext context = new GenericApplicationContext(); - prepareApplicationContext(context); - customizeBeanFactory(context.getDefaultListableBeanFactory()); - createBeanDefinitionReader(context).loadBeanDefinitions(locations); - context.refresh(); - return context; - } - - /** - * Prepare the GenericApplicationContext used by this test. - * Called before bean definitions are read. - *

The default implementation is empty. Can be overridden in subclasses to - * customize GenericApplicationContext's standard settings. - * @param context the context for which the BeanDefinitionReader should be created - * @see #createApplicationContext - * @see org.springframework.context.support.GenericApplicationContext#setResourceLoader - * @see org.springframework.context.support.GenericApplicationContext#setId - */ - protected void prepareApplicationContext(GenericApplicationContext context) { - } - - /** - * Customize the internal bean factory of the ApplicationContext used by - * this test. Called before bean definitions are read. - *

The default implementation is empty. Can be overridden in subclasses to - * customize DefaultListableBeanFactory's standard settings. - * @param beanFactory the newly created bean factory for this context - * @see #loadContextLocations - * @see #createApplicationContext - * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowBeanDefinitionOverriding - * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowEagerClassLoading - * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowCircularReferences - * @see org.springframework.beans.factory.support.DefaultListableBeanFactory#setAllowRawInjectionDespiteWrapping - */ - protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { - } - - /** - * Factory method for creating new {@link BeanDefinitionReader}s for - * loading bean definitions into the supplied - * {@link GenericApplicationContext context}. - *

The default implementation creates a new {@link XmlBeanDefinitionReader}. - * Can be overridden in subclasses to provide a different - * BeanDefinitionReader implementation. - * @param context the context for which the BeanDefinitionReader should be created - * @return a BeanDefinitionReader for the supplied context - * @see #createApplicationContext(String[]) - * @see BeanDefinitionReader - * @see XmlBeanDefinitionReader - */ - protected BeanDefinitionReader createBeanDefinitionReader(GenericApplicationContext context) { - return new XmlBeanDefinitionReader(context); - } - - /** - * Subclasses can override this method to return the locations of their - * config files, unless they override {@link #contextKey()} and - * {@link #loadContext(Object)} instead. - *

A plain path will be treated as class path location, e.g.: - * "org/springframework/whatever/foo.xml". Note however that you may prefix - * path locations with standard Spring resource prefixes. Therefore, a - * config location path prefixed with "classpath:" with behave the same as a - * plain path, but a config location such as - * "file:/some/path/path/location/appContext.xml" will be treated as a - * filesystem location. - *

The default implementation builds config locations for the config paths - * specified through {@link #getConfigPaths()}. - * @return an array of config locations - * @see #getConfigPaths() - * @see org.springframework.core.io.ResourceLoader#getResource(String) - */ - protected String[] getConfigLocations() { - String[] paths = getConfigPaths(); - String[] locations = new String[paths.length]; - for (int i = 0; i < paths.length; i++) { - String path = paths[i]; - if (path.startsWith("/")) { - locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + path; - } - else { - locations[i] = ResourceUtils.CLASSPATH_URL_PREFIX + - StringUtils.cleanPath(ClassUtils.classPackageAsResourcePath(getClass()) + "/" + path); - } - } - return locations; - } - - /** - * Subclasses can override this method to return paths to their config - * files, relative to the concrete test class. - *

A plain path, e.g. "context.xml", will be loaded as classpath resource - * from the same package that the concrete test class is defined in. A path - * starting with a slash is treated as fully qualified class path location, - * e.g.: "/org/springframework/whatever/foo.xml". - *

The default implementation builds an array for the config path specified - * through {@link #getConfigPath()}. - * @return an array of config locations - * @see #getConfigPath() - * @see java.lang.Class#getResource(String) - */ - protected String[] getConfigPaths() { - String path = getConfigPath(); - return (path != null ? new String[] { path } : new String[0]); - } - - /** - * Subclasses can override this method to return a single path to a config - * file, relative to the concrete test class. - *

A plain path, e.g. "context.xml", will be loaded as classpath resource - * from the same package that the concrete test class is defined in. A path - * starting with a slash is treated as fully qualified class path location, - * e.g.: "/org/springframework/whatever/foo.xml". - *

The default implementation simply returns {@code null}. - * @return an array of config locations - * @see #getConfigPath() - * @see Class#getResource(String) - */ - protected String getConfigPath() { - return null; - } - - /** - * Return the ApplicationContext that this base class manages; may be - * {@code null}. - */ - public final ConfigurableApplicationContext getApplicationContext() { - // lazy load, in case setUp() has not yet been called. - if (this.applicationContext == null) { - try { - this.applicationContext = getContext(contextKey()); - } - catch (Exception e) { - // log and continue... - if (this.logger.isDebugEnabled()) { - this.logger.debug("Caught exception while retrieving the ApplicationContext for test [" + - getClass().getName() + "." + getName() + "].", e); - } - } - } - - return this.applicationContext; - } - - /** - * Return the current number of context load attempts. - */ - public final int getLoadCount() { - return this.loadCount; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/AbstractSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/AbstractSpringContextTests.java deleted file mode 100644 index d01144ede93..00000000000 --- a/spring-test/src/main/java/org/springframework/test/AbstractSpringContextTests.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - *

- * Superclass for JUnit 3.8 test cases using Spring - * {@link org.springframework.context.ApplicationContext ApplicationContexts}. - *

- *

- * Maintains a static cache of contexts by key. This has significant performance - * benefit if initializing the context would take time. While initializing a - * Spring context itself is very quick, some beans in a context, such as a - * LocalSessionFactoryBean for working with Hibernate, may take some time to - * initialize. Hence it often makes sense to do that initializing once. - *

- *

- * Any ApplicationContext created by this class will be asked to register a JVM - * shutdown hook for itself. Unless the context gets closed early, all context - * instances will be automatically closed on JVM shutdown. This allows for - * freeing external resources held by beans within the context, e.g. temporary - * files. - *

- *

- * Normally you won't extend this class directly but rather one of its - * subclasses. - *

- * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Sam Brannen - * @since 1.1.1 - * @see AbstractSingleSpringContextTests - * @see AbstractDependencyInjectionSpringContextTests - * @see AbstractTransactionalSpringContextTests - * @see AbstractTransactionalDataSourceSpringContextTests - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests}) - */ -@Deprecated -public abstract class AbstractSpringContextTests extends ConditionalTestCase { - - /** - * Map of context keys returned by subclasses of this class, to Spring - * contexts. This needs to be static, as JUnit tests are destroyed and - * recreated between running individual test methods. - */ - private static Map contextKeyToContextMap = - new HashMap(); - - - /** - * Default constructor for AbstractSpringContextTests. - */ - public AbstractSpringContextTests() { - } - - /** - * Constructor for AbstractSpringContextTests with a JUnit name. - */ - public AbstractSpringContextTests(String name) { - super(name); - } - - - /** - * Explicitly add an ApplicationContext instance under a given key. - *

This is not meant to be used by subclasses. It is rather exposed for - * special test suite environments. - * @param key the context key - * @param context the ApplicationContext instance - */ - public final void addContext(Object key, ConfigurableApplicationContext context) { - Assert.notNull(context, "ApplicationContext must not be null"); - contextKeyToContextMap.put(contextKeyString(key), context); - } - - /** - * Return whether there is a cached context for the given key. - * @param key the context key - */ - protected final boolean hasCachedContext(Object key) { - return contextKeyToContextMap.containsKey(contextKeyString(key)); - } - - /** - * Determine if the supplied context {@code key} is empty. - *

By default, {@code null} values, empty strings, and zero-length - * arrays are considered empty. - * @param key the context key to check - * @return {@code true} if the supplied context key is empty - */ - protected boolean isContextKeyEmpty(Object key) { - return (key == null) || ((key instanceof String) && !StringUtils.hasText((String) key)) || - ((key instanceof Object[]) && ObjectUtils.isEmpty((Object[]) key)); - } - - /** - * Obtain an ApplicationContext for the given key, potentially cached. - * @param key the context key; may be {@code null}. - * @return the corresponding ApplicationContext instance (potentially cached), - * or {@code null} if the provided {@code key} is empty - */ - protected final ConfigurableApplicationContext getContext(Object key) throws Exception { - if (isContextKeyEmpty(key)) { - return null; - } - String keyString = contextKeyString(key); - ConfigurableApplicationContext ctx = contextKeyToContextMap.get(keyString); - if (ctx == null) { - ctx = loadContext(key); - ctx.registerShutdownHook(); - contextKeyToContextMap.put(keyString, ctx); - } - return ctx; - } - - /** - * Mark the context with the given key as dirty. This will cause the cached - * context to be reloaded before the next test case is executed. - *

Call this method only if you change the state of a singleton bean, - * potentially affecting future tests. - */ - protected final void setDirty(Object contextKey) { - String keyString = contextKeyString(contextKey); - ConfigurableApplicationContext ctx = contextKeyToContextMap.remove(keyString); - if (ctx != null) { - ctx.close(); - } - } - - /** - * Subclasses can override this to return a String representation of their - * context key for use in caching and logging. - * @param contextKey the context key - */ - protected String contextKeyString(Object contextKey) { - return ObjectUtils.nullSafeToString(contextKey); - } - - /** - * Load a new ApplicationContext for the given key. - *

To be implemented by subclasses. - * @param key the context key - * @return the corresponding ApplicationContext instance (new) - */ - protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception; - -} diff --git a/spring-test/src/main/java/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.java deleted file mode 100644 index 0f697d115f5..00000000000 --- a/spring-test/src/main/java/org/springframework/test/AbstractTransactionalDataSourceSpringContextTests.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import java.io.IOException; -import java.io.LineNumberReader; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import javax.sql.DataSource; - -import org.springframework.core.io.support.EncodedResource; -import org.springframework.dao.DataAccessException; -import org.springframework.dao.DataAccessResourceFailureException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.test.jdbc.JdbcTestUtils; - -/** - * Subclass of AbstractTransactionalSpringContextTests that adds some convenience - * functionality for JDBC access. Expects a {@link javax.sql.DataSource} bean - * to be defined in the Spring application context. - * - *

This class exposes a {@link org.springframework.jdbc.core.JdbcTemplate} - * and provides an easy way to delete from the database in a new transaction. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Thomas Risberg - * @since 1.1.1 - * @see #setDataSource(javax.sql.DataSource) - * @see #getJdbcTemplate() - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests}) - */ -@Deprecated -@SuppressWarnings({ "unchecked", "rawtypes" }) -public abstract class AbstractTransactionalDataSourceSpringContextTests - extends AbstractTransactionalSpringContextTests { - - protected JdbcTemplate jdbcTemplate; - - private String sqlScriptEncoding; - - /** - * Did this test delete any tables? If so, we forbid transaction completion, - * and only allow rollback. - */ - private boolean zappedTables; - - - /** - * Default constructor for AbstractTransactionalDataSourceSpringContextTests. - */ - public AbstractTransactionalDataSourceSpringContextTests() { - } - - /** - * Constructor for AbstractTransactionalDataSourceSpringContextTests with a JUnit name. - */ - public AbstractTransactionalDataSourceSpringContextTests(String name) { - super(name); - } - - - /** - * Setter: DataSource is provided by Dependency Injection. - */ - public void setDataSource(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - /** - * Return the JdbcTemplate that this base class manages. - */ - public final JdbcTemplate getJdbcTemplate() { - return this.jdbcTemplate; - } - - /** - * Specify the encoding for SQL scripts, if different from the platform encoding. - * @see #executeSqlScript - */ - public void setSqlScriptEncoding(String sqlScriptEncoding) { - this.sqlScriptEncoding = sqlScriptEncoding; - } - - - /** - * Convenient method to delete all rows from these tables. - * Calling this method will make avoidance of rollback by calling - * {@code setComplete()} impossible. - * @see #setComplete - */ - protected void deleteFromTables(String[] names) { - for (int i = 0; i < names.length; i++) { - int rowCount = this.jdbcTemplate.update("DELETE FROM " + names[i]); - if (logger.isInfoEnabled()) { - logger.info("Deleted " + rowCount + " rows from table " + names[i]); - } - } - this.zappedTables = true; - } - - /** - * Overridden to prevent the transaction committing if a number of tables have been - * cleared, as a defensive measure against accidental permanent wiping of a database. - * @see org.springframework.test.AbstractTransactionalSpringContextTests#setComplete() - */ - protected final void setComplete() { - if (this.zappedTables) { - throw new IllegalStateException("Cannot set complete after deleting tables"); - } - super.setComplete(); - } - - /** - * Count the rows in the given table - * @param tableName table name to count rows in - * @return the number of rows in the table - */ - protected int countRowsInTable(String tableName) { - return this.jdbcTemplate.queryForInt("SELECT COUNT(0) FROM " + tableName); - } - - - /** - * Execute the given SQL script. Will be rolled back by default, - * according to the fate of the current transaction. - * @param sqlResourcePath Spring resource path for the SQL script. - * Should normally be loaded by classpath. - *

Statements should be delimited with a semicolon. If statements are not delimited with - * a semicolon then there should be one statement per line. Statements are allowed to span - * lines only if they are delimited with a semicolon. - *

Do not use this method to execute DDL if you expect rollback. - * @param continueOnError whether or not to continue without throwing - * an exception in the event of an error - * @throws DataAccessException if there is an error executing a statement - * and continueOnError was false - */ - protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { - if (logger.isInfoEnabled()) { - logger.info("Executing SQL script '" + sqlResourcePath + "'"); - } - - EncodedResource resource = - new EncodedResource(getApplicationContext().getResource(sqlResourcePath), this.sqlScriptEncoding); - long startTime = System.currentTimeMillis(); - List statements = new LinkedList(); - try { - LineNumberReader lnr = new LineNumberReader(resource.getReader()); - String script = JdbcTestUtils.readScript(lnr); - char delimiter = ';'; - if (!JdbcTestUtils.containsSqlScriptDelimiters(script, delimiter)) { - delimiter = '\n'; - } - JdbcTestUtils.splitSqlScript(script, delimiter, statements); - for (Iterator itr = statements.iterator(); itr.hasNext(); ) { - String statement = (String) itr.next(); - try { - int rowsAffected = this.jdbcTemplate.update(statement); - if (logger.isDebugEnabled()) { - logger.debug(rowsAffected + " rows affected by SQL: " + statement); - } - } - catch (DataAccessException ex) { - if (continueOnError) { - if (logger.isWarnEnabled()) { - logger.warn("SQL: " + statement + " failed", ex); - } - } - else { - throw ex; - } - } - } - long elapsedTime = System.currentTimeMillis() - startTime; - logger.info("Done executing SQL scriptBuilder '" + sqlResourcePath + "' in " + elapsedTime + " ms"); - } - catch (IOException ex) { - throw new DataAccessResourceFailureException("Failed to open SQL script '" + sqlResourcePath + "'", ex); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/AbstractTransactionalSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/AbstractTransactionalSpringContextTests.java deleted file mode 100644 index af3c68663e0..00000000000 --- a/spring-test/src/main/java/org/springframework/test/AbstractTransactionalSpringContextTests.java +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionException; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; - -/** - * Convenient base class for JUnit 3.8 based tests that should occur in a - * transaction, but normally will roll the transaction back on the completion of - * each test. - * - *

This is useful in a range of circumstances, allowing the following benefits: - *

- * - *

This class is typically very fast, compared to traditional setup/teardown - * scripts. - * - *

If data should be left in the database, call the {@link #setComplete()} - * method in each test. The {@link #setDefaultRollback "defaultRollback"} - * property, which defaults to "true", determines whether transactions will - * complete by default. - * - *

It is even possible to end the transaction early; for example, to verify lazy - * loading behavior of an O/R mapping tool. (This is a valuable away to avoid - * unexpected errors when testing a web UI, for example.) Simply call the - * {@link #endTransaction()} method. Execution will then occur without a - * transactional context. - * - *

The {@link #startNewTransaction()} method may be called after a call to - * {@link #endTransaction()} if you wish to create a new transaction, quite - * independent of the old transaction. The new transaction's default fate will - * be to roll back, unless {@link #setComplete()} is called again during the - * scope of the new transaction. Any number of transactions may be created and - * ended in this way. The final transaction will automatically be rolled back - * when the test case is torn down. - * - *

Transactional behavior requires a single bean in the context implementing the - * {@link PlatformTransactionManager} interface. This will be set by the - * superclass's Dependency Injection mechanism. If using the superclass's Field - * Injection mechanism, the implementation should be named "transactionManager". - * This mechanism allows the use of the - * {@link AbstractDependencyInjectionSpringContextTests} superclass even when - * there is more than one transaction manager in the context. - * - *

This base class can also be used without transaction management, if no - * PlatformTransactionManager bean is found in the context provided. Be - * careful about using this mode, as it allows the potential to permanently - * modify data. This mode is available only if dependency checking is turned off - * in the {@link AbstractDependencyInjectionSpringContextTests} superclass. The - * non-transactional capability is provided to enable use of the same subclass - * in different environments. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @author Sam Brannen - * @since 1.1.1 - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests}) - */ -@Deprecated -public abstract class AbstractTransactionalSpringContextTests extends AbstractDependencyInjectionSpringContextTests { - - /** The transaction manager to use */ - protected PlatformTransactionManager transactionManager; - - /** Should we roll back by default? */ - private boolean defaultRollback = true; - - /** Should we commit the current transaction? */ - private boolean complete = false; - - /** Number of transactions started */ - private int transactionsStarted = 0; - - /** - * Transaction definition used by this test class: by default, a plain - * DefaultTransactionDefinition. Subclasses can change this to cause - * different behavior. - */ - protected TransactionDefinition transactionDefinition= new DefaultTransactionDefinition(); - - /** - * TransactionStatus for this test. Typical subclasses won't need to use it. - */ - protected TransactionStatus transactionStatus; - - - /** - * Default constructor for AbstractTransactionalSpringContextTests. - */ - public AbstractTransactionalSpringContextTests() { - } - - /** - * Constructor for AbstractTransactionalSpringContextTests with a JUnit name. - */ - public AbstractTransactionalSpringContextTests(String name) { - super(name); - } - - - /** - * Specify the transaction manager to use. No transaction management will be - * available if this is not set. Populated through dependency injection by - * the superclass. - *

- * This mode works only if dependency checking is turned off in the - * {@link AbstractDependencyInjectionSpringContextTests} superclass. - */ - public void setTransactionManager(PlatformTransactionManager transactionManager) { - this.transactionManager = transactionManager; - } - - /** - * Subclasses can set this value in their constructor to change the default, - * which is always to roll the transaction back. - */ - public void setDefaultRollback(final boolean defaultRollback) { - this.defaultRollback = defaultRollback; - } - /** - * Get the default rollback flag for this test. - * @see #setDefaultRollback(boolean) - * @return The default rollback flag. - */ - protected boolean isDefaultRollback() { - return this.defaultRollback; - } - - /** - * Determines whether or not to rollback transactions for the current test. - *

The default implementation delegates to {@link #isDefaultRollback()}. - * Subclasses can override as necessary. - */ - protected boolean isRollback() { - return isDefaultRollback(); - } - - /** - * Call this method in an overridden {@link #runBare()} method to prevent - * transactional execution. - */ - protected void preventTransaction() { - this.transactionDefinition = null; - } - - /** - * Call this method in an overridden {@link #runBare()} method to override - * the transaction attributes that will be used, so that {@link #setUp()} - * and {@link #tearDown()} behavior is modified. - * @param customDefinition the custom transaction definition - */ - protected void setTransactionDefinition(TransactionDefinition customDefinition) { - this.transactionDefinition = customDefinition; - } - - /** - * This implementation creates a transaction before test execution. - *

Override {@link #onSetUpBeforeTransaction()} and/or - * {@link #onSetUpInTransaction()} to add custom set-up behavior for - * transactional execution. Alternatively, override this method for general - * set-up behavior, calling {@code super.onSetUp()} as part of your - * method implementation. - * @throws Exception simply let any exception propagate - * @see #onTearDown() - */ - protected void onSetUp() throws Exception { - this.complete = !this.isRollback(); - - if (this.transactionManager == null) { - this.logger.info("No transaction manager set: test will NOT run within a transaction"); - } - else if (this.transactionDefinition == null) { - this.logger.info("No transaction definition set: test will NOT run within a transaction"); - } - else { - onSetUpBeforeTransaction(); - startNewTransaction(); - try { - onSetUpInTransaction(); - } - catch (final Exception ex) { - endTransaction(); - throw ex; - } - } - } - - /** - * Subclasses can override this method to perform any setup operations, such - * as populating a database table, before the transaction created by - * this class. Only invoked if there is a transaction: that is, if - * {@link #preventTransaction()} has not been invoked in an overridden - * {@link #runTest()} method. - * @throws Exception simply let any exception propagate - */ - protected void onSetUpBeforeTransaction() throws Exception { - } - - /** - * Subclasses can override this method to perform any setup operations, such - * as populating a database table, within the transaction created by - * this class. - *

NB: Not called if there is no transaction management, due to no - * transaction manager being provided in the context. - *

If any {@link Throwable} is thrown, the transaction that has been started - * prior to the execution of this method will be - * {@link #endTransaction() ended} (or rather an attempt will be made to - * {@link #endTransaction() end it gracefully}); The offending - * {@link Throwable} will then be rethrown. - * @throws Exception simply let any exception propagate - */ - protected void onSetUpInTransaction() throws Exception { - } - - /** - * This implementation ends the transaction after test execution. - *

Override {@link #onTearDownInTransaction()} and/or - * {@link #onTearDownAfterTransaction()} to add custom tear-down behavior - * for transactional execution. Alternatively, override this method for - * general tear-down behavior, calling {@code super.onTearDown()} as - * part of your method implementation. - *

Note that {@link #onTearDownInTransaction()} will only be called if a - * transaction is still active at the time of the test shutdown. In - * particular, it will not be called if the transaction has been - * completed with an explicit {@link #endTransaction()} call before. - * @throws Exception simply let any exception propagate - * @see #onSetUp() - */ - protected void onTearDown() throws Exception { - // Call onTearDownInTransaction and end transaction if the transaction - // is still active. - if (this.transactionStatus != null && !this.transactionStatus.isCompleted()) { - try { - onTearDownInTransaction(); - } - finally { - endTransaction(); - } - } - - // Call onTearDownAfterTransaction if there was at least one - // transaction, even if it has been completed early through an - // endTransaction() call. - if (this.transactionsStarted > 0) { - onTearDownAfterTransaction(); - } - } - - /** - * Subclasses can override this method to run invariant tests here. The - * transaction is still active at this point, so any changes made in - * the transaction will still be visible. However, there is no need to clean - * up the database, as a rollback will follow automatically. - *

NB: Not called if there is no actual transaction, for example due - * to no transaction manager being provided in the application context. - * @throws Exception simply let any exception propagate - */ - protected void onTearDownInTransaction() throws Exception { - } - - /** - * Subclasses can override this method to perform cleanup after a - * transaction here. At this point, the transaction is not active anymore. - * @throws Exception simply let any exception propagate - */ - protected void onTearDownAfterTransaction() throws Exception { - } - - /** - * Cause the transaction to commit for this test method, even if the test - * method is configured to {@link #isRollback() rollback}. - * @throws IllegalStateException if the operation cannot be set to complete - * as no transaction manager was provided - */ - protected void setComplete() { - if (this.transactionManager == null) { - throw new IllegalStateException("No transaction manager set"); - } - this.complete = true; - } - - /** - * Immediately force a commit or rollback of the transaction, according to - * the {@code complete} and {@link #isRollback() rollback} flags. - *

Can be used to explicitly let the transaction end early, for example to - * check whether lazy associations of persistent objects work outside of a - * transaction (that is, have been initialized properly). - * @see #setComplete() - */ - protected void endTransaction() { - final boolean commit = this.complete || !isRollback(); - if (this.transactionStatus != null) { - try { - if (commit) { - this.transactionManager.commit(this.transactionStatus); - this.logger.debug("Committed transaction after execution of test [" + getName() + "]."); - } - else { - this.transactionManager.rollback(this.transactionStatus); - this.logger.debug("Rolled back transaction after execution of test [" + getName() + "]."); - } - } - finally { - this.transactionStatus = null; - } - } - } - - /** - * Start a new transaction. Only call this method if - * {@link #endTransaction()} has been called. {@link #setComplete()} can be - * used again in the new transaction. The fate of the new transaction, by - * default, will be the usual rollback. - * @throws TransactionException if starting the transaction failed - */ - protected void startNewTransaction() throws TransactionException { - if (this.transactionStatus != null) { - throw new IllegalStateException("Cannot start new transaction without ending existing transaction: " - + "Invoke endTransaction() before startNewTransaction()"); - } - if (this.transactionManager == null) { - throw new IllegalStateException("No transaction manager set"); - } - - this.transactionStatus = this.transactionManager.getTransaction(this.transactionDefinition); - ++this.transactionsStarted; - this.complete = !this.isRollback(); - - if (this.logger.isDebugEnabled()) { - this.logger.debug("Began transaction (" + this.transactionsStarted + "): transaction manager [" - + this.transactionManager + "]; rollback [" + this.isRollback() + "]."); - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/ConditionalTestCase.java b/spring-test/src/main/java/org/springframework/test/ConditionalTestCase.java deleted file mode 100644 index 2869f258b78..00000000000 --- a/spring-test/src/main/java/org/springframework/test/ConditionalTestCase.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2002-2012 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; - -import junit.framework.TestCase; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Superclass for JUnit 3.8 based tests that allows conditional test execution - * at the individual test method level. The - * {@link #isDisabledInThisEnvironment(String) isDisabledInThisEnvironment()} - * method is invoked before the execution of each test method. Subclasses can - * override that method to return whether or not the given test should be - * executed. Note that the tests will still appear to have executed and passed; - * however, log output will show that the test was not executed. - * - * @author Rod Johnson - * @since 2.0 - * @see #isDisabledInThisEnvironment - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests}) - */ -@Deprecated -public abstract class ConditionalTestCase extends TestCase { - - private static int disabledTestCount; - - - /** - * Return the number of tests disabled in this environment. - */ - public static int getDisabledTestCount() { - return disabledTestCount; - } - - - /** Logger available to subclasses */ - protected final Log logger = LogFactory.getLog(getClass()); - - - /** - * Default constructor for ConditionalTestCase. - */ - public ConditionalTestCase() { - } - - /** - * Constructor for ConditionalTestCase with a JUnit name. - */ - public ConditionalTestCase(String name) { - super(name); - } - - public void runBare() throws Throwable { - // getName will return the name of the method being run - if (isDisabledInThisEnvironment(getName())) { - recordDisabled(); - this.logger.info("**** " + getClass().getName() + "." + getName() + " is disabled in this environment: " - + "Total disabled tests = " + getDisabledTestCount()); - return; - } - - // Let JUnit handle execution - super.runBare(); - } - - /** - * Should this test run? - * @param testMethodName name of the test method - * @return whether the test should execute in the current environment - */ - protected boolean isDisabledInThisEnvironment(String testMethodName) { - return false; - } - - /** - * Record a disabled test. - * @return the current disabled test count - */ - protected int recordDisabled() { - return ++disabledTestCount; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/annotation/AbstractAnnotationAwareTransactionalTests.java b/spring-test/src/main/java/org/springframework/test/annotation/AbstractAnnotationAwareTransactionalTests.java deleted file mode 100644 index 30c08a22cb9..00000000000 --- a/spring-test/src/main/java/org/springframework/test/annotation/AbstractAnnotationAwareTransactionalTests.java +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright 2002-2012 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.annotation; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Map; - -import javax.sql.DataSource; - -import junit.framework.AssertionFailedError; - -import org.springframework.context.ApplicationContext; -import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource; -import org.springframework.transaction.interceptor.TransactionAttributeSource; -import org.springframework.util.Assert; - -/** - *

- * Java 5 specific subclass of - * {@link AbstractTransactionalDataSourceSpringContextTests}, exposing a - * {@link SimpleJdbcTemplate} and obeying annotations for transaction control. - *

- *

- * For example, test methods can be annotated with the regular Spring - * {@link org.springframework.transaction.annotation.Transactional @Transactional} - * annotation (e.g., to force execution in a read-only transaction) or with the - * {@link NotTransactional @NotTransactional} annotation to prevent any - * transaction being created at all. In addition, individual test methods can be - * annotated with {@link Rollback @Rollback} to override the - * {@link #isDefaultRollback() default rollback} settings. - *

- *

- * The following list constitutes all annotations currently supported by - * AbstractAnnotationAwareTransactionalTests: - *

- * - * - * @author Rod Johnson - * @author Sam Brannen - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests}) - */ -@Deprecated -public abstract class AbstractAnnotationAwareTransactionalTests extends - AbstractTransactionalDataSourceSpringContextTests { - - protected SimpleJdbcTemplate simpleJdbcTemplate; - - private final TransactionAttributeSource transactionAttributeSource = new AnnotationTransactionAttributeSource(); - - /** - * {@link ProfileValueSource} available to subclasses but primarily intended - * for use in {@link #isDisabledInThisEnvironment(Method)}. - *

Set to {@link SystemProfileValueSource} by default for backwards - * compatibility; however, the value may be changed in the - * {@link #AbstractAnnotationAwareTransactionalTests(String)} constructor. - */ - protected ProfileValueSource profileValueSource = SystemProfileValueSource.getInstance(); - - - /** - * Default constructor for AbstractAnnotationAwareTransactionalTests, which - * delegates to {@link #AbstractAnnotationAwareTransactionalTests(String)}. - */ - public AbstractAnnotationAwareTransactionalTests() { - this(null); - } - - /** - * Constructs a new AbstractAnnotationAwareTransactionalTests instance with - * the specified JUnit {@code name} and retrieves the configured (or - * default) {@link ProfileValueSource}. - * @param name the name of the current test - * @see ProfileValueUtils#retrieveProfileValueSource(Class) - */ - public AbstractAnnotationAwareTransactionalTests(String name) { - super(name); - this.profileValueSource = ProfileValueUtils.retrieveProfileValueSource(getClass()); - } - - - @Override - public void setDataSource(DataSource dataSource) { - super.setDataSource(dataSource); - // JdbcTemplate will be identically configured - this.simpleJdbcTemplate = new SimpleJdbcTemplate(this.jdbcTemplate); - } - - /** - * Search for a unique {@link ProfileValueSource} in the supplied - * {@link ApplicationContext}. If found, the - * {@code profileValueSource} for this test will be set to the unique - * {@link ProfileValueSource}. - * @param applicationContext the ApplicationContext in which to search for - * the ProfileValueSource; may not be {@code null} - * @deprecated Use {@link ProfileValueSourceConfiguration @ProfileValueSourceConfiguration} instead. - */ - @Deprecated - protected void findUniqueProfileValueSourceFromContext(ApplicationContext applicationContext) { - Assert.notNull(applicationContext, "Can not search for a ProfileValueSource in a null ApplicationContext."); - ProfileValueSource uniqueProfileValueSource = null; - Map beans = applicationContext.getBeansOfType(ProfileValueSource.class); - if (beans.size() == 1) { - uniqueProfileValueSource = (ProfileValueSource) beans.values().iterator().next(); - } - if (uniqueProfileValueSource != null) { - this.profileValueSource = uniqueProfileValueSource; - } - } - - /** - * Overridden to populate transaction definition from annotations. - */ - @Override - public void runBare() throws Throwable { - - // getName will return the name of the method being run. - if (isDisabledInThisEnvironment(getName())) { - // Let superclass log that we didn't run the test. - super.runBare(); - return; - } - - final Method testMethod = getTestMethod(); - - if (isDisabledInThisEnvironment(testMethod)) { - recordDisabled(); - this.logger.info("**** " + getClass().getName() + "." + getName() + " is disabled in this environment: " - + "Total disabled tests=" + getDisabledTestCount()); - return; - } - - TransactionDefinition explicitTransactionDefinition = - this.transactionAttributeSource.getTransactionAttribute(testMethod, getClass()); - if (explicitTransactionDefinition != null) { - this.logger.info("Custom transaction definition [" + explicitTransactionDefinition + "] for test method [" - + getName() + "]."); - setTransactionDefinition(explicitTransactionDefinition); - } - else if (testMethod.isAnnotationPresent(NotTransactional.class)) { - // Don't have any transaction... - preventTransaction(); - } - - // Let JUnit handle execution. We're just changing the state of the test class first. - runTestTimed(new TestExecutionCallback() { - public void run() throws Throwable { - try { - AbstractAnnotationAwareTransactionalTests.super.runBare(); - } - finally { - // Mark the context to be blown away if the test was - // annotated to result in setDirty being invoked - // automatically. - if (testMethod.isAnnotationPresent(DirtiesContext.class)) { - AbstractAnnotationAwareTransactionalTests.this.setDirty(); - } - } - } - }, testMethod); - } - - /** - * Determine if the test for the supplied {@code testMethod} should - * run in the current environment. - *

The default implementation is based on - * {@link IfProfileValue @IfProfileValue} semantics. - * @param testMethod the test method - * @return {@code true} if the test is disabled in the current environment - * @see ProfileValueUtils#isTestEnabledInThisEnvironment - */ - protected boolean isDisabledInThisEnvironment(Method testMethod) { - return !ProfileValueUtils.isTestEnabledInThisEnvironment(this.profileValueSource, testMethod, getClass()); - } - - /** - * Get the current test method. - */ - protected Method getTestMethod() { - assertNotNull("TestCase.getName() cannot be null", getName()); - Method testMethod = null; - try { - // Use same algorithm as JUnit itself to retrieve the test method - // about to be executed (the method name is returned by getName). It - // has to be public so we can retrieve it. - testMethod = getClass().getMethod(getName(), (Class[]) null); - } - catch (NoSuchMethodException ex) { - fail("Method '" + getName() + "' not found"); - } - if (!Modifier.isPublic(testMethod.getModifiers())) { - fail("Method '" + getName() + "' should be public"); - } - return testMethod; - } - - /** - * Determine whether or not to rollback transactions for the current test - * by taking into consideration the - * {@link #isDefaultRollback() default rollback} flag and a possible - * method-level override via the {@link Rollback @Rollback} annotation. - * @return the rollback flag for the current test - */ - @Override - protected boolean isRollback() { - boolean rollback = isDefaultRollback(); - Rollback rollbackAnnotation = getTestMethod().getAnnotation(Rollback.class); - if (rollbackAnnotation != null) { - boolean rollbackOverride = rollbackAnnotation.value(); - if (this.logger.isDebugEnabled()) { - this.logger.debug("Method-level @Rollback(" + rollbackOverride + ") overrides default rollback [" - + rollback + "] for test [" + getName() + "]."); - } - rollback = rollbackOverride; - } - else { - if (this.logger.isDebugEnabled()) { - this.logger.debug("No method-level @Rollback override: using default rollback [" + rollback - + "] for test [" + getName() + "]."); - } - } - return rollback; - } - - private void runTestTimed(TestExecutionCallback tec, Method testMethod) throws Throwable { - Timed timed = testMethod.getAnnotation(Timed.class); - if (timed == null) { - runTest(tec, testMethod); - } - else { - long startTime = System.currentTimeMillis(); - try { - runTest(tec, testMethod); - } - finally { - long elapsed = System.currentTimeMillis() - startTime; - if (elapsed > timed.millis()) { - fail("Took " + elapsed + " ms; limit was " + timed.millis()); - } - } - } - } - - private void runTest(TestExecutionCallback tec, Method testMethod) throws Throwable { - ExpectedException expectedExceptionAnnotation = testMethod.getAnnotation(ExpectedException.class); - boolean exceptionIsExpected = (expectedExceptionAnnotation != null && expectedExceptionAnnotation.value() != null); - Class expectedException = (exceptionIsExpected ? expectedExceptionAnnotation.value() : null); - - Repeat repeat = testMethod.getAnnotation(Repeat.class); - int runs = ((repeat != null) && (repeat.value() > 1)) ? repeat.value() : 1; - - for (int i = 0; i < runs; i++) { - try { - if (runs > 1 && this.logger != null && this.logger.isInfoEnabled()) { - this.logger.info("Repetition " + (i + 1) + " of test " + testMethod.getName()); - } - tec.run(); - if (exceptionIsExpected) { - fail("Expected exception: " + expectedException.getName()); - } - } - catch (Throwable t) { - if (!exceptionIsExpected) { - throw t; - } - if (!expectedException.isAssignableFrom(t.getClass())) { - // Wrap the unexpected throwable with an explicit message. - AssertionFailedError assertionError = new AssertionFailedError("Unexpected exception, expected<" + - expectedException.getName() + "> but was<" + t.getClass().getName() + ">"); - assertionError.initCause(t); - throw assertionError; - } - } - } - } - - - private static interface TestExecutionCallback { - - void run() throws Throwable; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/jpa/AbstractAspectjJpaTests.java b/spring-test/src/main/java/org/springframework/test/jpa/AbstractAspectjJpaTests.java deleted file mode 100644 index dd55d0e78b1..00000000000 --- a/spring-test/src/main/java/org/springframework/test/jpa/AbstractAspectjJpaTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2002-2012 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.jpa; - -import org.aspectj.weaver.loadtime.ClassPreProcessorAgentAdapter; - -import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader; - -/** - * Subclass of {@link AbstractJpaTests} that activates AspectJ load-time weaving and - * allows for specifying a custom location for AspectJ's {@code aop.xml} file. - * - * @author Rod Johnson - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) - */ -@Deprecated -public abstract class AbstractAspectjJpaTests extends AbstractJpaTests { - - /** - * Default location of the {@code aop.xml} file in the class path: - * "META-INF/aop.xml" - */ - public static final String DEFAULT_AOP_XML_LOCATION = "META-INF/aop.xml"; - - - @Override - protected void customizeResourceOverridingShadowingClassLoader(ClassLoader shadowingClassLoader) { - ResourceOverridingShadowingClassLoader orxl = (ResourceOverridingShadowingClassLoader) shadowingClassLoader; - orxl.override(DEFAULT_AOP_XML_LOCATION, getActualAopXmlLocation()); - orxl.addTransformer(new ClassPreProcessorAgentAdapter()); - } - - /** - * Return the actual location of the {@code aop.xml} file - * in the class path. The default is "META-INF/aop.xml". - *

Override this method to point to a specific {@code aop.xml} - * file within your test suite, allowing for different config files - * to co-exist within the same class path. - */ - protected String getActualAopXmlLocation() { - return DEFAULT_AOP_XML_LOCATION; - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/jpa/AbstractJpaTests.java b/spring-test/src/main/java/org/springframework/test/jpa/AbstractJpaTests.java deleted file mode 100644 index 005c19e3d84..00000000000 --- a/spring-test/src/main/java/org/springframework/test/jpa/AbstractJpaTests.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright 2002-2013 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.jpa; - -import java.lang.instrument.ClassFileTransformer; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; - -import junit.framework.TestCase; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver; -import org.springframework.instrument.classloading.LoadTimeWeaver; -import org.springframework.instrument.classloading.ResourceOverridingShadowingClassLoader; -import org.springframework.instrument.classloading.ShadowingClassLoader; -import org.springframework.orm.jpa.ExtendedEntityManagerCreator; -import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; -import org.springframework.orm.jpa.SharedEntityManagerCreator; -import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager; -import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests; -import org.springframework.util.StringUtils; - -/** - * Convenient support class for JPA-related tests. Offers the same contract as - * AbstractTransactionalDataSourceSpringContextTests and equally good performance, - * even when performing the instrumentation required by the JPA specification. - * - *

Exposes an EntityManagerFactory and a shared EntityManager. - * Requires an EntityManagerFactory to be injected, plus the DataSource and - * JpaTransactionManager through the superclass. - * - *

When using Xerces, make sure a post 2.0.2 version is available on the classpath - * to avoid a critical - * bug - * that leads to StackOverflow. Maven users are likely to encounter this problem since - * 2.0.2 is used by default. - * - *

A workaround is to explicitly specify the Xerces version inside the Maven POM: - *

- * <dependency>
- *   <groupId>xerces</groupId>
- *     <artifactId>xercesImpl</artifactId>
- *   <version>2.8.1</version>
- * </dependency>
- * 
- * - * @author Rod Johnson - * @author Rob Harrop - * @author Juergen Hoeller - * @since 2.0 - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) - */ -@Deprecated -public abstract class AbstractJpaTests extends AbstractAnnotationAwareTransactionalTests { - - private static final String DEFAULT_ORM_XML_LOCATION = "META-INF/orm.xml"; - - /** - * Map from String defining unique combination of config locations, to ApplicationContext. - * Values are intentionally not strongly typed, to avoid potential class cast exceptions - * through use between different class loaders. - */ - private static Map contextCache = new HashMap(); - - private static Map classLoaderCache = new HashMap(); - - protected EntityManagerFactory entityManagerFactory; - - /** - * If this instance is in a shadow loader, this variable - * will contain the parent instance of the subclass. - * The class will not be the same as the class of the - * shadow instance, as it was loaded by a different class loader, - * but it can be invoked reflectively. The shadowParent - * and the shadow loader can communicate reflectively - * but not through direct invocation. - */ - private Object shadowParent; - - /** - * Subclasses can use this in test cases. - * It will participate in any current transaction. - */ - protected EntityManager sharedEntityManager; - - - public void setEntityManagerFactory(EntityManagerFactory entityManagerFactory) { - this.entityManagerFactory = entityManagerFactory; - this.sharedEntityManager = SharedEntityManagerCreator.createSharedEntityManager(this.entityManagerFactory); - } - - /** - * Create an EntityManager that will always automatically enlist itself in current - * transactions, in contrast to an EntityManager returned by - * {@code EntityManagerFactory.createEntityManager()} - * (which requires an explicit {@code joinTransaction()} call). - */ - protected EntityManager createContainerManagedEntityManager() { - return ExtendedEntityManagerCreator.createContainerManagedEntityManager(this.entityManagerFactory); - } - - /** - * Subclasses should override this method if they wish to disable shadow class loading. - *

The default implementation deactivates shadow class loading if Spring's - * InstrumentationSavingAgent has been configured on VM startup. - */ - protected boolean shouldUseShadowLoader() { - return !InstrumentationLoadTimeWeaver.isInstrumentationAvailable(); - } - - @Override - public void setDirty() { - super.setDirty(); - contextCache.remove(cacheKeys()); - classLoaderCache.remove(cacheKeys()); - - // If we are a shadow loader, we need to invoke - // the shadow parent to set it dirty, as - // it is the shadow parent that maintains the cache state, - // not the child - if (this.shadowParent != null) { - try { - Method m = shadowParent.getClass().getMethod("setDirty", (Class[]) null); - m.invoke(shadowParent, (Object[]) null); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - } - - - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void runBare() throws Throwable { - - // getName will return the name of the method being run. - if (isDisabledInThisEnvironment(getName())) { - // Let superclass log that we didn't run the test. - super.runBare(); - return; - } - - final Method testMethod = getTestMethod(); - - if (isDisabledInThisEnvironment(testMethod)) { - recordDisabled(); - this.logger.info("**** " + getClass().getName() + "." + getName() + " is disabled in this environment: " - + "Total disabled tests=" + getDisabledTestCount()); - return; - } - - if (!shouldUseShadowLoader()) { - super.runBare(); - return; - } - - String combinationOfContextLocationsForThisTestClass = cacheKeys(); - ClassLoader classLoaderForThisTestClass = getClass().getClassLoader(); - // save the TCCL - ClassLoader initialClassLoader = Thread.currentThread().getContextClassLoader(); - - if (this.shadowParent != null) { - Thread.currentThread().setContextClassLoader(classLoaderForThisTestClass); - super.runBare(); - } - - else { - ShadowingClassLoader shadowingClassLoader = (ShadowingClassLoader) classLoaderCache.get(combinationOfContextLocationsForThisTestClass); - - if (shadowingClassLoader == null) { - shadowingClassLoader = (ShadowingClassLoader) createShadowingClassLoader(classLoaderForThisTestClass); - classLoaderCache.put(combinationOfContextLocationsForThisTestClass, shadowingClassLoader); - } - try { - Thread.currentThread().setContextClassLoader(shadowingClassLoader); - String[] configLocations = getConfigLocations(); - - // Do not strongly type, to avoid ClassCastException. - Object cachedContext = contextCache.get(combinationOfContextLocationsForThisTestClass); - - if (cachedContext == null) { - - // Create the LoadTimeWeaver. - Class shadowingLoadTimeWeaverClass = shadowingClassLoader.loadClass(ShadowingLoadTimeWeaver.class.getName()); - Constructor constructor = shadowingLoadTimeWeaverClass.getConstructor(ClassLoader.class); - constructor.setAccessible(true); - Object ltw = constructor.newInstance(shadowingClassLoader); - - // Create the BeanFactory. - Class beanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName()); - Object beanFactory = BeanUtils.instantiateClass(beanFactoryClass); - - // Create the BeanDefinitionReader. - Class beanDefinitionReaderClass = shadowingClassLoader.loadClass(XmlBeanDefinitionReader.class.getName()); - Class beanDefinitionRegistryClass = shadowingClassLoader.loadClass(BeanDefinitionRegistry.class.getName()); - Object reader = beanDefinitionReaderClass.getConstructor(beanDefinitionRegistryClass).newInstance(beanFactory); - - // Load the bean definitions into the BeanFactory. - Method loadBeanDefinitions = beanDefinitionReaderClass.getMethod("loadBeanDefinitions", String[].class); - loadBeanDefinitions.invoke(reader, new Object[] {configLocations}); - - // Create LoadTimeWeaver-injecting BeanPostProcessor. - Class loadTimeWeaverInjectingBeanPostProcessorClass = shadowingClassLoader.loadClass(LoadTimeWeaverInjectingBeanPostProcessor.class.getName()); - Class loadTimeWeaverClass = shadowingClassLoader.loadClass(LoadTimeWeaver.class.getName()); - Constructor bppConstructor = loadTimeWeaverInjectingBeanPostProcessorClass.getConstructor(loadTimeWeaverClass); - bppConstructor.setAccessible(true); - Object beanPostProcessor = bppConstructor.newInstance(ltw); - - // Add LoadTimeWeaver-injecting BeanPostProcessor. - Class beanPostProcessorClass = shadowingClassLoader.loadClass(BeanPostProcessor.class.getName()); - Method addBeanPostProcessor = beanFactoryClass.getMethod("addBeanPostProcessor", beanPostProcessorClass); - addBeanPostProcessor.invoke(beanFactory, beanPostProcessor); - - // Create the GenericApplicationContext. - Class genericApplicationContextClass = shadowingClassLoader.loadClass(GenericApplicationContext.class.getName()); - Class defaultListableBeanFactoryClass = shadowingClassLoader.loadClass(DefaultListableBeanFactory.class.getName()); - cachedContext = genericApplicationContextClass.getConstructor(defaultListableBeanFactoryClass).newInstance(beanFactory); - - // Invoke the context's "refresh" method. - genericApplicationContextClass.getMethod("refresh").invoke(cachedContext); - - // Store the context reference in the cache. - contextCache.put(combinationOfContextLocationsForThisTestClass, cachedContext); - } - // create the shadowed test - Class shadowedTestClass = shadowingClassLoader.loadClass(getClass().getName()); - - // So long as JUnit is excluded from shadowing we - // can minimize reflective invocation here - TestCase shadowedTestCase = (TestCase) BeanUtils.instantiateClass(shadowedTestClass); - - /* shadowParent = this */ - Class thisShadowedClass = shadowingClassLoader.loadClass(AbstractJpaTests.class.getName()); - Field shadowed = thisShadowedClass.getDeclaredField("shadowParent"); - shadowed.setAccessible(true); - shadowed.set(shadowedTestCase, this); - - /* AbstractSpringContextTests.addContext(Object, ApplicationContext) */ - Class applicationContextClass = shadowingClassLoader.loadClass(ConfigurableApplicationContext.class.getName()); - Method addContextMethod = shadowedTestClass.getMethod("addContext", Object.class, applicationContextClass); - addContextMethod.invoke(shadowedTestCase, configLocations, cachedContext); - - // Invoke tests on shadowed test case - shadowedTestCase.setName(getName()); - shadowedTestCase.runBare(); - } - catch (InvocationTargetException ex) { - // Unwrap this for better exception reporting - // when running tests - throw ex.getTargetException(); - } - finally { - Thread.currentThread().setContextClassLoader(initialClassLoader); - } - } - } - - protected String cacheKeys() { - return StringUtils.arrayToCommaDelimitedString(getConfigLocations()); - } - - /** - * NB: This method must not have a return type of ShadowingClassLoader as that would cause that - * class to be loaded eagerly when this test case loads, creating verify errors at runtime. - */ - protected ClassLoader createShadowingClassLoader(ClassLoader classLoader) { - OrmXmlOverridingShadowingClassLoader orxl = new OrmXmlOverridingShadowingClassLoader(classLoader, - getActualOrmXmlLocation()); - customizeResourceOverridingShadowingClassLoader(orxl); - return orxl; - } - - /** - * Customize the shadowing class loader. - * @param shadowingClassLoader this parameter is actually of type - * ResourceOverridingShadowingClassLoader, and can safely to be cast to - * that type. However, the signature must not be of that type as that - * would cause the present class loader to load that type. - */ - protected void customizeResourceOverridingShadowingClassLoader(ClassLoader shadowingClassLoader) { - // empty - } - - /** - * Subclasses can override this to return the real location path for - * orm.xml or null if they do not wish to find any orm.xml - * @return orm.xml path or null to hide any such file - */ - protected String getActualOrmXmlLocation() { - return DEFAULT_ORM_XML_LOCATION; - } - - - private static class LoadTimeWeaverInjectingBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { - - private final LoadTimeWeaver ltw; - - @SuppressWarnings("unused") - public LoadTimeWeaverInjectingBeanPostProcessor(LoadTimeWeaver ltw) { - this.ltw = ltw; - } - - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (bean instanceof LocalContainerEntityManagerFactoryBean) { - ((LocalContainerEntityManagerFactoryBean) bean).setLoadTimeWeaver(this.ltw); - } - if (bean instanceof DefaultPersistenceUnitManager) { - ((DefaultPersistenceUnitManager) bean).setLoadTimeWeaver(this.ltw); - } - return bean; - } - } - - - private static class ShadowingLoadTimeWeaver implements LoadTimeWeaver { - - private final ClassLoader shadowingClassLoader; - - @SuppressWarnings("unused") - public ShadowingLoadTimeWeaver(ClassLoader shadowingClassLoader) { - this.shadowingClassLoader = shadowingClassLoader; - } - - public void addTransformer(ClassFileTransformer transformer) { - try { - Method addClassFileTransformer = - this.shadowingClassLoader.getClass().getMethod("addTransformer", ClassFileTransformer.class); - addClassFileTransformer.setAccessible(true); - addClassFileTransformer.invoke(this.shadowingClassLoader, transformer); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - } - - public ClassLoader getInstrumentableClassLoader() { - return this.shadowingClassLoader; - } - - public ClassLoader getThrowawayClassLoader() { - // Be sure to copy the same resource overrides and same class file transformers: - // We want the throwaway class loader to behave like the instrumentable class loader. - ResourceOverridingShadowingClassLoader roscl = - new ResourceOverridingShadowingClassLoader(getClass().getClassLoader()); - if (this.shadowingClassLoader instanceof ShadowingClassLoader) { - roscl.copyTransformers((ShadowingClassLoader) this.shadowingClassLoader); - } - if (this.shadowingClassLoader instanceof ResourceOverridingShadowingClassLoader) { - roscl.copyOverrides((ResourceOverridingShadowingClassLoader) this.shadowingClassLoader); - } - return roscl; - } - } - -} diff --git a/spring-test/src/main/java/org/springframework/test/web/AbstractModelAndViewTests.java b/spring-test/src/main/java/org/springframework/test/web/AbstractModelAndViewTests.java deleted file mode 100644 index fefc31e1615..00000000000 --- a/spring-test/src/main/java/org/springframework/test/web/AbstractModelAndViewTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2002-2012 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.web; - -import java.util.Comparator; -import java.util.List; -import java.util.Map; - -import junit.framework.AssertionFailedError; -import junit.framework.TestCase; - -import org.springframework.web.servlet.ModelAndView; - -/** - * Convenient JUnit 3.8 base class for tests dealing with Spring Web MVC - * {@link org.springframework.web.servlet.ModelAndView ModelAndView} objects. - * - *

All {@code assert*()} methods throw {@link AssertionFailedError}s. - * - *

Consider the use of {@link ModelAndViewAssert} with JUnit 4 and TestNG. - * - * @author Alef Arendsen - * @author Bram Smeets - * @author Sam Brannen - * @since 2.0 - * @see org.springframework.web.servlet.ModelAndView - * @see ModelAndViewAssert - * @deprecated as of Spring 3.0, in favor of using the listener-based test context framework - * ({@link org.springframework.test.context.junit38.AbstractJUnit38SpringContextTests}) - * or {@link ModelAndViewAssert} with JUnit 4 and TestNG. - */ -@Deprecated -public abstract class AbstractModelAndViewTests extends TestCase { - - /** - * Checks whether the model value under the given {@code modelName} - * exists and checks it type, based on the {@code expectedType}. If - * the model entry exists and the type matches, the model value is returned. - * @param mav ModelAndView to test against (never {@code null}) - * @param modelName name of the object to add to the model (never - * {@code null}) - * @param expectedType expected type of the model value - * @return the model value - */ - protected T assertAndReturnModelAttributeOfType(ModelAndView mav, String modelName, Class expectedType) { - try { - return ModelAndViewAssert.assertAndReturnModelAttributeOfType(mav, modelName, expectedType); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Compare each individual entry in a list, without first sorting the lists. - * @param mav ModelAndView to test against (never {@code null}) - * @param modelName name of the object to add to the model (never - * {@code null}) - * @param expectedList the expected list - */ - @SuppressWarnings("rawtypes") - protected void assertCompareListModelAttribute(ModelAndView mav, String modelName, List expectedList) { - try { - ModelAndViewAssert.assertCompareListModelAttribute(mav, modelName, expectedList); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Assert whether or not a model attribute is available. - * @param mav ModelAndView to test against (never {@code null}) - * @param modelName name of the object to add to the model (never - * {@code null}) - */ - protected void assertModelAttributeAvailable(ModelAndView mav, String modelName) { - try { - ModelAndViewAssert.assertModelAttributeAvailable(mav, modelName); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Compare a given {@code expectedValue} to the value from the model - * bound under the given {@code modelName}. - * @param mav ModelAndView to test against (never {@code null}) - * @param modelName name of the object to add to the model (never - * {@code null}) - * @param expectedValue the model value - */ - protected void assertModelAttributeValue(ModelAndView mav, String modelName, Object expectedValue) { - try { - ModelAndViewAssert.assertModelAttributeValue(mav, modelName, expectedValue); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Inspect the {@code expectedModel} to see if all elements in the - * model appear and are equal. - * @param mav ModelAndView to test against (never {@code null}) - * @param expectedModel the expected model - */ - protected void assertModelAttributeValues(ModelAndView mav, Map expectedModel) { - try { - ModelAndViewAssert.assertModelAttributeValues(mav, expectedModel); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Compare each individual entry in a list after having sorted both lists - * (optionally using a comparator). - * @param mav ModelAndView to test against (never {@code null}) - * @param modelName name of the object to add to the model (never - * {@code null}) - * @param expectedList the expected list - * @param comparator the comparator to use (may be {@code null}). If - * not specifying the comparator, both lists will be sorted not using - * any comparator. - */ - @SuppressWarnings("rawtypes") - protected void assertSortAndCompareListModelAttribute( - ModelAndView mav, String modelName, List expectedList, Comparator comparator) { - try { - ModelAndViewAssert.assertSortAndCompareListModelAttribute(mav, modelName, expectedList, comparator); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - - /** - * Check to see if the view name in the ModelAndView matches the given - * {@code expectedName}. - * @param mav ModelAndView to test against (never {@code null}) - * @param expectedName the name of the model value - */ - protected void assertViewName(ModelAndView mav, String expectedName) { - try { - ModelAndViewAssert.assertViewName(mav, expectedName); - } - catch (AssertionError e) { - throw new AssertionFailedError(e.getMessage()); - } - } - -}