package org.yajul.jndi; import org.yajul.juli.LogHelper; import javax.naming.*; import java.util.logging.Logger; /** * Helper functions for JNDI. * <br>User: Joshua Davis * Date: Sep 9, 2007 * Time: 10:17:15 AM */ public class JndiHelper { private static final Logger log = Logger.getLogger(JndiHelper.class.getName()); /** * Encapsulates the standard JNDI lookup calls for EJBs, etc. in a method that * throws an uncheckeced exception. The typical use case would be inside an EAR where * a failed lookup means some kind of unrecoverable deployment problem. That eliminates * some of the redundant code sprinkled throughout an application. * <br> * This should not be used to replace EJB3 injection, but it does come in handy when: * <ul> * <li>There are EJBs that have circular dependencies, which makes lookup (Service Locator pattern) * necessary.</li> * <li>There are cluster singletons, or other cases where you want to use a different InitialContext * to look up an EJB or other JNDI object. For example: EJB3 Timers are usually deployed as cluster * singletons in JBoss AS, so these should be looked up in HAJNDI.</li> * </ul> * * @param context The initial context. Null to use the default <tt>new InitialContext()</tt> * @param clazz the expected type of the object in JNDI. For an EJB, this will be the local * interface class. * @param name The JNDI name for the object, e.g. XxxDao/local or, XxxDao/Remote * @return the JNDI object * @throws LookupException if the lookup fails for any reason */ @SuppressWarnings("unchecked") public static <T> T lookup(InitialContext context, Class<T> clazz, String name) { final Object object = doLookup(context, name); if (clazz.isAssignableFrom(object.getClass())) { return (T) object; } else { throw new LookupException(String.format( "Found JNDI name '%s' of type %s, but it cannot be assigned to type: %s", name, object.getClass(), clazz)); } } public static String listBindings(Context context, String name) { StringBuilder sb = new StringBuilder(); sb.append("Listing for ").append(name).append("\n"); listContext(" ", context, name, sb); return sb.toString(); } private static void listContext(String prefix, Context context, String name, StringBuilder sb) { try { NamingEnumeration<Binding> bindings = context.listBindings(name); while (bindings.hasMore()) { Binding binding = bindings.next(); sb.append(prefix).append(name).append(binding.getName()).append(" -> ") .append(binding.getClassName()).append("\n"); Object obj = binding.getObject(); if (obj instanceof Context) { Context nestedContext = (Context) obj; listContext(prefix + binding.getName() + "/",nestedContext,"",sb); } } } catch (NamingException e) { LogHelper.unexpected(log,e); throw new LookupException("Unable to list context due to: " + e.getMessage(),e); } } public static <T> T lookup(InitialContext ic, String name) { Object object = doLookup(ic, name); try { //noinspection unchecked return (T) object; } catch (ClassCastException cce) { throw new LookupException(String.format( "Found JNDI name '%s' of type %s, but that isn't the right type.", name, object.getClass())); } } private static Object doLookup(InitialContext ic, String name) { InitialContext context = ic; if (context == null) { try { context = new InitialContext(); } catch (NamingException e1) { throw new LookupException("Unable to create default InitialContext", e1); } } try { return context.lookup(name); } catch (NamingException e) { throw new LookupException(String.format( "Unable to find JNDI name '%s'", name), e); } } public static InitialContext getDefaultInitialContext() { try { return new InitialContext(); } catch (NamingException e) { throw new RuntimeException("Unable to create default InitialContext due to " + e, e); } } }