| /* |
| * 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.eclipse.gemini.blueprint.test.legacyspringsupport; |
| |
| import org.springframework.context.ConfigurableApplicationContext; |
| import org.springframework.util.Assert; |
| import org.springframework.util.ObjectUtils; |
| import org.springframework.util.StringUtils; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| /** |
| * <p> |
| * Superclass for JUnit 3.8 test cases using Spring |
| * {@link org.springframework.context.ApplicationContext ApplicationContexts}. |
| * </p> |
| * <p> |
| * 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. |
| * </p> |
| * <p> |
| * 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. |
| * </p> |
| * <p> |
| * Normally you won't extend this class directly but rather one of its |
| * subclasses. |
| * </p> |
| * |
| * @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<String, ConfigurableApplicationContext> contextKeyToContextMap = |
| new HashMap<String, ConfigurableApplicationContext>(); |
| |
| |
| /** |
| * 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. |
| * <p>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 <em>empty</em>. |
| * <p>By default, {@code null} values, empty strings, and zero-length |
| * arrays are considered <em>empty</em>. |
| * @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 <em>empty</em> |
| */ |
| 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. |
| * <p>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. |
| * <p>To be implemented by subclasses. |
| * @param key the context key |
| * @return the corresponding ApplicationContext instance (new) |
| */ |
| protected abstract ConfigurableApplicationContext loadContext(Object key) throws Exception; |
| |
| } |