Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@474 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
3 changed files with 661 additions and 0 deletions
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.mock.jndi; |
||||
|
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import javax.naming.NamingException; |
||||
|
||||
import org.springframework.core.CollectionFactory; |
||||
import org.springframework.jndi.JndiTemplate; |
||||
|
||||
/** |
||||
* Simple extension of the JndiTemplate class that always returns |
||||
* a given object. Very useful for testing. Effectively a mock object. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Juergen Hoeller |
||||
*/ |
||||
public class ExpectedLookupTemplate extends JndiTemplate { |
||||
|
||||
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>(); |
||||
|
||||
|
||||
/** |
||||
* Construct a new JndiTemplate that will always return given objects |
||||
* for given names. To be populated through <code>addObject</code> calls. |
||||
* @see #addObject(String, Object) |
||||
*/ |
||||
public ExpectedLookupTemplate() { |
||||
} |
||||
|
||||
/** |
||||
* Construct a new JndiTemplate that will always return the |
||||
* given object, but honour only requests for the given name. |
||||
* @param name the name the client is expected to look up |
||||
* @param object the object that will be returned |
||||
*/ |
||||
public ExpectedLookupTemplate(String name, Object object) { |
||||
addObject(name, object); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Add the given object to the list of JNDI objects that this |
||||
* template will expose. |
||||
* @param name the name the client is expected to look up |
||||
* @param object the object that will be returned |
||||
*/ |
||||
public void addObject(String name, Object object) { |
||||
this.jndiObjects.put(name, object); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* If the name is the expected name specified in the constructor, |
||||
* return the object provided in the constructor. If the name is |
||||
* unexpected, a respective NamingException gets thrown. |
||||
*/ |
||||
public Object lookup(String name) throws NamingException { |
||||
Object object = this.jndiObjects.get(name); |
||||
if (object == null) { |
||||
throw new NamingException("Unexpected JNDI name '" + name + "': expecting " + this.jndiObjects.keySet()); |
||||
} |
||||
return object; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,345 @@
@@ -0,0 +1,345 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.mock.jndi; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Hashtable; |
||||
import java.util.Iterator; |
||||
import java.util.Map; |
||||
import javax.naming.Binding; |
||||
import javax.naming.Context; |
||||
import javax.naming.Name; |
||||
import javax.naming.NameClassPair; |
||||
import javax.naming.NameNotFoundException; |
||||
import javax.naming.NameParser; |
||||
import javax.naming.NamingEnumeration; |
||||
import javax.naming.NamingException; |
||||
import javax.naming.OperationNotSupportedException; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.util.StringUtils; |
||||
|
||||
/** |
||||
* Simple implementation of a JNDI naming context. |
||||
* Only supports binding plain Objects to String names. |
||||
* Mainly for test environments, but also usable for standalone applications. |
||||
* |
||||
* <p>This class is not intended for direct usage by applications, although it |
||||
* can be used for example to override JndiTemplate's <code>createInitialContext</code> |
||||
* method in unit tests. Typically, SimpleNamingContextBuilder will be used to |
||||
* set up a JVM-level JNDI environment. |
||||
* |
||||
* @author Rod Johnson |
||||
* @author Juergen Hoeller |
||||
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder |
||||
* @see org.springframework.jndi.JndiTemplate#createInitialContext |
||||
*/ |
||||
public class SimpleNamingContext implements Context { |
||||
|
||||
private final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private final String root; |
||||
|
||||
private final Hashtable<String, Object> boundObjects; |
||||
|
||||
private final Hashtable<String, Object> environment = new Hashtable<String, Object>(); |
||||
|
||||
|
||||
/** |
||||
* Create a new naming context. |
||||
*/ |
||||
public SimpleNamingContext() { |
||||
this(""); |
||||
} |
||||
|
||||
/** |
||||
* Create a new naming context with the given naming root. |
||||
*/ |
||||
public SimpleNamingContext(String root) { |
||||
this.root = root; |
||||
this.boundObjects = new Hashtable<String, Object>(); |
||||
} |
||||
|
||||
/** |
||||
* Create a new naming context with the given naming root, |
||||
* the given name/object map, and the JNDI environment entries. |
||||
*/ |
||||
public SimpleNamingContext(String root, Hashtable<String, Object> boundObjects, Hashtable<String, Object> env) { |
||||
this.root = root; |
||||
this.boundObjects = boundObjects; |
||||
if (env != null) { |
||||
this.environment.putAll(env); |
||||
} |
||||
} |
||||
|
||||
|
||||
// Actual implementations of Context methods follow
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(String root) throws NamingException { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Listing name/class pairs under [" + root + "]"); |
||||
} |
||||
return new NameClassPairEnumeration(this, root); |
||||
} |
||||
|
||||
public NamingEnumeration<Binding> listBindings(String root) throws NamingException { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Listing bindings under [" + root + "]"); |
||||
} |
||||
return new BindingEnumeration(this, root); |
||||
} |
||||
|
||||
/** |
||||
* Look up the object with the given name. |
||||
* <p>Note: Not intended for direct use by applications. |
||||
* Will be used by any standard InitialContext JNDI lookups. |
||||
* @throws javax.naming.NameNotFoundException if the object could not be found |
||||
*/ |
||||
public Object lookup(String lookupName) throws NameNotFoundException { |
||||
String name = this.root + lookupName; |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Static JNDI lookup: [" + name + "]"); |
||||
} |
||||
if ("".equals(name)) { |
||||
return new SimpleNamingContext(this.root, this.boundObjects, this.environment); |
||||
} |
||||
Object found = this.boundObjects.get(name); |
||||
if (found == null) { |
||||
if (!name.endsWith("/")) { |
||||
name = name + "/"; |
||||
} |
||||
for (String boundName : this.boundObjects.keySet()) { |
||||
if (boundName.startsWith(name)) { |
||||
return new SimpleNamingContext(name, this.boundObjects, this.environment); |
||||
} |
||||
} |
||||
throw new NameNotFoundException( |
||||
"Name [" + this.root + lookupName + "] not bound; " + this.boundObjects.size() + " bindings: [" + |
||||
StringUtils.collectionToDelimitedString(this.boundObjects.keySet(), ",") + "]"); |
||||
} |
||||
return found; |
||||
} |
||||
|
||||
public Object lookupLink(String name) throws NameNotFoundException { |
||||
return lookup(name); |
||||
} |
||||
|
||||
/** |
||||
* Bind the given object to the given name. |
||||
* Note: Not intended for direct use by applications |
||||
* if setting up a JVM-level JNDI environment. |
||||
* Use SimpleNamingContextBuilder to set up JNDI bindings then. |
||||
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder#bind |
||||
*/ |
||||
public void bind(String name, Object obj) { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Static JNDI binding: [" + this.root + name + "] = [" + obj + "]"); |
||||
} |
||||
this.boundObjects.put(this.root + name, obj); |
||||
} |
||||
|
||||
public void unbind(String name) { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Static JNDI remove: [" + this.root + name + "]"); |
||||
} |
||||
this.boundObjects.remove(this.root + name); |
||||
} |
||||
|
||||
public void rebind(String name, Object obj) { |
||||
bind(name, obj); |
||||
} |
||||
|
||||
public void rename(String oldName, String newName) throws NameNotFoundException { |
||||
Object obj = lookup(oldName); |
||||
unbind(oldName); |
||||
bind(newName, obj); |
||||
} |
||||
|
||||
public Context createSubcontext(String name) { |
||||
String subcontextName = this.root + name; |
||||
if (!subcontextName.endsWith("/")) { |
||||
subcontextName += "/"; |
||||
} |
||||
Context subcontext = new SimpleNamingContext(subcontextName, this.boundObjects, this.environment); |
||||
bind(name, subcontext); |
||||
return subcontext; |
||||
} |
||||
|
||||
public void destroySubcontext(String name) { |
||||
unbind(name); |
||||
} |
||||
|
||||
public String composeName(String name, String prefix) { |
||||
return prefix + name; |
||||
} |
||||
|
||||
public Hashtable<String, Object> getEnvironment() { |
||||
return this.environment; |
||||
} |
||||
|
||||
public Object addToEnvironment(String propName, Object propVal) { |
||||
return this.environment.put(propName, propVal); |
||||
} |
||||
|
||||
public Object removeFromEnvironment(String propName) { |
||||
return this.environment.remove(propName); |
||||
} |
||||
|
||||
public void close() { |
||||
} |
||||
|
||||
|
||||
// Unsupported methods follow: no support for javax.naming.Name
|
||||
|
||||
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public Object lookup(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public Object lookupLink(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public void bind(Name name, Object obj) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public void unbind(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public void rebind(Name name, Object obj) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public void rename(Name oldName, Name newName) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public Context createSubcontext(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public void destroySubcontext(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public String getNameInNamespace() throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public NameParser getNameParser(Name name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public NameParser getNameParser(String name) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
public Name composeName(Name name, Name prefix) throws NamingException { |
||||
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]"); |
||||
} |
||||
|
||||
|
||||
private static abstract class AbstractNamingEnumeration<T> implements NamingEnumeration<T> { |
||||
|
||||
private Iterator<T> iterator; |
||||
|
||||
private AbstractNamingEnumeration(SimpleNamingContext context, String proot) throws NamingException { |
||||
if (!"".equals(proot) && !proot.endsWith("/")) { |
||||
proot = proot + "/"; |
||||
} |
||||
String root = context.root + proot; |
||||
Map<String, T> contents = new HashMap<String, T>(); |
||||
for (String boundName : context.boundObjects.keySet()) { |
||||
if (boundName.startsWith(root)) { |
||||
int startIndex = root.length(); |
||||
int endIndex = boundName.indexOf('/', startIndex); |
||||
String strippedName = |
||||
(endIndex != -1 ? boundName.substring(startIndex, endIndex) : boundName.substring(startIndex)); |
||||
if (!contents.containsKey(strippedName)) { |
||||
try { |
||||
contents.put(strippedName, createObject(strippedName, context.lookup(proot + strippedName))); |
||||
} |
||||
catch (NameNotFoundException ex) { |
||||
// cannot happen
|
||||
} |
||||
} |
||||
} |
||||
} |
||||
if (contents.size() == 0) { |
||||
throw new NamingException("Invalid root: [" + context.root + proot + "]"); |
||||
} |
||||
this.iterator = contents.values().iterator(); |
||||
} |
||||
|
||||
protected abstract T createObject(String strippedName, Object obj); |
||||
|
||||
public boolean hasMore() { |
||||
return this.iterator.hasNext(); |
||||
} |
||||
|
||||
public T next() { |
||||
return this.iterator.next(); |
||||
} |
||||
|
||||
public boolean hasMoreElements() { |
||||
return this.iterator.hasNext(); |
||||
} |
||||
|
||||
public T nextElement() { |
||||
return this.iterator.next(); |
||||
} |
||||
|
||||
public void close() { |
||||
} |
||||
} |
||||
|
||||
|
||||
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> { |
||||
|
||||
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException { |
||||
super(context, root); |
||||
} |
||||
|
||||
protected NameClassPair createObject(String strippedName, Object obj) { |
||||
return new NameClassPair(strippedName, obj.getClass().getName()); |
||||
} |
||||
} |
||||
|
||||
|
||||
private static class BindingEnumeration extends AbstractNamingEnumeration<Binding> { |
||||
|
||||
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException { |
||||
super(context, root); |
||||
} |
||||
|
||||
protected Binding createObject(String strippedName, Object obj) { |
||||
return new Binding(strippedName, obj); |
||||
} |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,234 @@
@@ -0,0 +1,234 @@
|
||||
/* |
||||
* Copyright 2002-2008 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.mock.jndi; |
||||
|
||||
import java.util.Hashtable; |
||||
|
||||
import javax.naming.Context; |
||||
import javax.naming.NamingException; |
||||
import javax.naming.spi.InitialContextFactory; |
||||
import javax.naming.spi.InitialContextFactoryBuilder; |
||||
import javax.naming.spi.NamingManager; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
|
||||
import org.springframework.util.ClassUtils; |
||||
|
||||
/** |
||||
* Simple implementation of a JNDI naming context builder. |
||||
* |
||||
* <p>Mainly targeted at test environments, where each test case can |
||||
* configure JNDI appropriately, so that <code>new InitialContext()</code> |
||||
* will expose the required objects. Also usable for standalone applications, |
||||
* e.g. for binding a JDBC DataSource to a well-known JNDI location, to be |
||||
* able to use traditional J2EE data access code outside of a J2EE container. |
||||
* |
||||
* <p>There are various choices for DataSource implementations: |
||||
* <ul> |
||||
* <li>SingleConnectionDataSource (using the same Connection for all getConnection calls); |
||||
* <li>DriverManagerDataSource (creating a new Connection on each getConnection call); |
||||
* <li>Apache's Jakarta Commons DBCP offers BasicDataSource (a real pool). |
||||
* </ul> |
||||
* |
||||
* <p>Typical usage in bootstrap code: |
||||
* |
||||
* <pre class="code"> |
||||
* SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); |
||||
* DataSource ds = new DriverManagerDataSource(...); |
||||
* builder.bind("java:comp/env/jdbc/myds", ds); |
||||
* builder.activate();</pre> |
||||
* |
||||
* Note that it's impossible to activate multiple builders within the same JVM, |
||||
* due to JNDI restrictions. Thus to configure a fresh builder repeatedly, use |
||||
* the following code to get a reference to either an already activated builder |
||||
* or a newly activated one: |
||||
* |
||||
* <pre class="code"> |
||||
* SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder(); |
||||
* DataSource ds = new DriverManagerDataSource(...); |
||||
* builder.bind("java:comp/env/jdbc/myds", ds);</pre> |
||||
* |
||||
* Note that you <i>should not</i> call <code>activate()</code> on a builder from |
||||
* this factory method, as there will already be an activated one in any case. |
||||
* |
||||
* <p>An instance of this class is only necessary at setup time. |
||||
* An application does not need to keep a reference to it after activation. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @author Rod Johnson |
||||
* @see #emptyActivatedContextBuilder() |
||||
* @see #bind(String, Object) |
||||
* @see #activate() |
||||
* @see org.springframework.mock.jndi.SimpleNamingContext |
||||
* @see org.springframework.jdbc.datasource.SingleConnectionDataSource |
||||
* @see org.springframework.jdbc.datasource.DriverManagerDataSource |
||||
* @see org.apache.commons.dbcp.BasicDataSource |
||||
*/ |
||||
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder { |
||||
|
||||
/** An instance of this class bound to JNDI */ |
||||
private static volatile SimpleNamingContextBuilder activated; |
||||
|
||||
private static boolean initialized = false; |
||||
|
||||
private static final Object initializationLock = new Object(); |
||||
|
||||
|
||||
/** |
||||
* Checks if a SimpleNamingContextBuilder is active. |
||||
* @return the current SimpleNamingContextBuilder instance, |
||||
* or <code>null</code> if none |
||||
*/ |
||||
public static SimpleNamingContextBuilder getCurrentContextBuilder() { |
||||
return activated; |
||||
} |
||||
|
||||
/** |
||||
* If no SimpleNamingContextBuilder is already configuring JNDI, |
||||
* create and activate one. Otherwise take the existing activate |
||||
* SimpleNamingContextBuilder, clear it and return it. |
||||
* <p>This is mainly intended for test suites that want to |
||||
* reinitialize JNDI bindings from scratch repeatedly. |
||||
* @return an empty SimpleNamingContextBuilder that can be used |
||||
* to control JNDI bindings |
||||
*/ |
||||
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException { |
||||
if (activated != null) { |
||||
// Clear already activated context builder.
|
||||
activated.clear(); |
||||
} |
||||
else { |
||||
// Create and activate new context builder.
|
||||
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); |
||||
// The activate() call will cause an assigment to the activated variable.
|
||||
builder.activate(); |
||||
} |
||||
return activated; |
||||
} |
||||
|
||||
|
||||
private final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
private final Hashtable boundObjects = new Hashtable(); |
||||
|
||||
|
||||
/** |
||||
* Register the context builder by registering it with the JNDI NamingManager. |
||||
* Note that once this has been done, <code>new InitialContext()</code> will always |
||||
* return a context from this factory. Use the <code>emptyActivatedContextBuilder()</code> |
||||
* static method to get an empty context (for example, in test methods). |
||||
* @throws IllegalStateException if there's already a naming context builder |
||||
* registered with the JNDI NamingManager |
||||
*/ |
||||
public void activate() throws IllegalStateException, NamingException { |
||||
logger.info("Activating simple JNDI environment"); |
||||
synchronized (initializationLock) { |
||||
if (!initialized) { |
||||
if (NamingManager.hasInitialContextFactoryBuilder()) { |
||||
throw new IllegalStateException( |
||||
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " + |
||||
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " + |
||||
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM."); |
||||
} |
||||
NamingManager.setInitialContextFactoryBuilder(this); |
||||
initialized = true; |
||||
} |
||||
} |
||||
activated = this; |
||||
} |
||||
|
||||
/** |
||||
* Temporarily deactivate this context builder. It will remain registered with |
||||
* the JNDI NamingManager but will delegate to the standard JNDI InitialContextFactory |
||||
* (if configured) instead of exposing its own bound objects. |
||||
* <p>Call <code>activate()</code> again in order to expose this contexz builder's own |
||||
* bound objects again. Such activate/deactivate sequences can be applied any number |
||||
* of times (e.g. within a larger integration test suite running in the same VM). |
||||
* @see #activate() |
||||
*/ |
||||
public void deactivate() { |
||||
logger.info("Deactivating simple JNDI environment"); |
||||
activated = null; |
||||
} |
||||
|
||||
/** |
||||
* Clear all bindings in this context builder, while keeping it active. |
||||
*/ |
||||
public void clear() { |
||||
this.boundObjects.clear(); |
||||
} |
||||
|
||||
/** |
||||
* Bind the given object under the given name, for all naming contexts |
||||
* that this context builder will generate. |
||||
* @param name the JNDI name of the object (e.g. "java:comp/env/jdbc/myds") |
||||
* @param obj the object to bind (e.g. a DataSource implementation) |
||||
*/ |
||||
public void bind(String name, Object obj) { |
||||
if (logger.isInfoEnabled()) { |
||||
logger.info("Static JNDI binding: [" + name + "] = [" + obj + "]"); |
||||
} |
||||
this.boundObjects.put(name, obj); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Simple InitialContextFactoryBuilder implementation, |
||||
* creating a new SimpleNamingContext instance. |
||||
* @see SimpleNamingContext |
||||
*/ |
||||
public InitialContextFactory createInitialContextFactory(Hashtable environment) { |
||||
if (activated == null && environment != null) { |
||||
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY); |
||||
if (icf != null) { |
||||
Class icfClass = null; |
||||
if (icf instanceof Class) { |
||||
icfClass = (Class) icf; |
||||
} |
||||
else if (icf instanceof String) { |
||||
icfClass = ClassUtils.resolveClassName((String) icf, getClass().getClassLoader()); |
||||
} |
||||
else { |
||||
throw new IllegalArgumentException("Invalid value type for environment key [" + |
||||
Context.INITIAL_CONTEXT_FACTORY + "]: " + icf.getClass().getName()); |
||||
} |
||||
if (!InitialContextFactory.class.isAssignableFrom(icfClass)) { |
||||
throw new IllegalArgumentException( |
||||
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf); |
||||
} |
||||
try { |
||||
return (InitialContextFactory) icfClass.newInstance(); |
||||
} |
||||
catch (Throwable ex) { |
||||
IllegalStateException ise = |
||||
new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf); |
||||
ise.initCause(ex); |
||||
throw ise; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Default case...
|
||||
return new InitialContextFactory() { |
||||
public Context getInitialContext(Hashtable environment) { |
||||
return new SimpleNamingContext("", boundObjects, environment); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue