MockContextFactory.java |
package org.mockejb.jndi; import java.util.*; import javax.naming.*; import javax.naming.spi.InitialContextFactory; import org.mockejb.interceptor.InterceptableProxy; /** * Creates {@link MockContext }. In case if delegate * environment was provided, obtains delegate InitialContext. * Delegate context is used by MockContext for unresolved lookups. * * @author Alexander Ananiev * @author Dimitar Gospodinov */ public class MockContextFactory implements InitialContextFactory { private static Map savedSystemProps = new HashMap(); private static Hashtable delegateEnv; private static Context delegateContext; private static Context rootContext; /** * Singleton for initial context. * Instantiates and returns root/initial <code>MockContext</code> object that * will be used as starting point for all naming operations. * <code>MockContext</code> is then used by <code>javax.naming.InitialContext</code> object. * It also creates the delegate context if the delegate environment is set. MockContextFactory * caches the delegate context once it's created. * @see javax.naming.spi.InitialContextFactory#getInitialContext(java.util.Hashtable) * @return <code>MockContext</code> object */ public Context getInitialContext(Hashtable environment) throws NamingException { if ( delegateContext == null && delegateEnv != null ) { delegateContext = new InitialContext( delegateEnv ); } if ( rootContext == null) { rootContext = (Context) InterceptableProxy.create( Context.class, new MockContext(delegateContext) ); } return rootContext; } /** * Sets the environment of the delegate JNDI context. Normally, * this is the environment of the application server. * At the very minimum, the environment includes PROVIDER_URL and INITIAL_CONTEXT_FACTORY. * <code>MockContext</code> first tries to look up the object in its local tree. * If the object is not found, it will look in the delegate context. * * @param env JNDI properties of the delegate environment */ public static void setDelegateEnvironment( Hashtable env ) { delegateEnv = env; } /** * Sets the delegate context. Normally, * this is the initial context of the application server. * * <code>MockContext</code> first tries to look up the object in its local tree. * If the object is not found, it will look in the delegate context. * * Example: * <code> * MockContextFactory.setDelegateContext( new InitialContext() ); * </code> * @param ctx delegate context */ public static void setDelegateContext( Context ctx ) { delegateContext = ctx; } /** * Sets the <code>MockContextFactory</code> as the initial context factory. * This helper method sets the <code>Context.INITIAL_CONTEXT_FACTORY</code> * and <code>Context.URL_PKG_PREFIXES</code> system properties. The second one is needed to * be able to handle java:comp context correctly. * The method also saves the current values of these properties so they can be * restored later on using <code>revertSetAsInitial</code>. * This method is normally called from <code>setUp</code> * <p> * You can also set these properties directly: * <pre> * <code> * java.naming.factory.initial=org.mockejb.jndi.MockContextFactory * java.naming.factory.url.pkgs=org.mockejb.jndi * </code> * <pre> * * * @throws NamingException */ public static void setAsInitial() throws NamingException { // Preserve current set system props String key = Context.INITIAL_CONTEXT_FACTORY; savedSystemProps.put( key, System.getProperty( key ) ); key = Context.URL_PKG_PREFIXES; savedSystemProps.put( key, System.getProperty( key ) ); System.setProperty( Context.INITIAL_CONTEXT_FACTORY, MockContextFactory.class.getName() ); System.setProperty( Context.URL_PKG_PREFIXES, "org.mockejb.jndi" ); } /** * Restores the properties changed by <code>setAsInitial()</code> * This method should be called in <code>tearDown()</code> to clean up * all changes to the environment in case if the test is running in the app * server. * <p> * This method also cleans the initial context. */ public static void revertSetAsInitial() { Iterator i = savedSystemProps.entrySet().iterator(); while( i.hasNext( ) ){ Map.Entry entry = (Map.Entry) i.next(); restoreSystemProperty( (String)entry.getKey(), (String)entry.getValue() ); } rootContext = null; } private static void restoreSystemProperty( String key, String value ){ if ( value != null ) System.setProperty( key, value ); else System.getProperties().remove( key ); } }