From: Erik Brakkee Date: Mon, 5 Jul 2010 15:34:21 +0000 (+0000) Subject: (no commit message) X-Git-Tag: wamblee-utils-0.7~364 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;h=993a2f8b4cfe42af68cfb9b9d0a801179090815c;p=utils --- diff --git a/test/enterprise/src/main/java/org/wamblee/support/jndi/JndiProxyFactory.java b/test/enterprise/src/main/java/org/wamblee/support/jndi/JndiProxyFactory.java new file mode 100644 index 00000000..99088576 --- /dev/null +++ b/test/enterprise/src/main/java/org/wamblee/support/jndi/JndiProxyFactory.java @@ -0,0 +1,135 @@ +/* + * Copyright 2005-2010 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.wamblee.support.jndi; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +/** + * Proxy factory that can provide contextual references to objects retrieved + * from JNDI. + * + * @param T + * Interface to proxy. + * @author Erik Brakkee + * + */ +public class JndiProxyFactory { + /** + * Exception thrown in case an object cannot be retrieved from JNDI. + * + * @author Erik Brakkee + */ + public static class JndiWiringException extends RuntimeException { + public JndiWiringException(String aMsg, Throwable aCause) { + super(aMsg, aCause); + } + + public JndiWiringException(String aMsg) { + super(aMsg); + } + } + + /** + * Invocation handler that does a lookup in JNDI and invokes the method on the + * object it found. + * + * @author Erik Brakkee + */ + private class JndiInvocationHandler implements InvocationHandler { + + @Override + /** + * @throws JndiWiringException in case the object could not be retrieved from JNDI. + */ + public Object invoke(Object aProxy, Method aMethod, Object[] aArgs) + throws Throwable { + Object svcObj = null; + try { + InitialContext ctx = new InitialContext(); + svcObj = ctx.lookup(jndi); + } catch (NamingException e) { + throw new JndiWiringException( + "Error looking up object in JNDI at '" + jndi + "'", e); + } + if (svcObj == null) { + throw new JndiWiringException("Object at '" + jndi + + "' is null"); + } + if (!clazz.isInstance(svcObj)) { + throw new JndiWiringException("Object in JNDI tree at '" + + jndi + "' not of type " + clazz.getName() + + " but of type " + svcObj.getClass().getName()); + } + T svc = (T) svcObj; + try { + return aMethod.invoke(svc, aArgs); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + } + } + + private String jndi; + private Class clazz; + + /** + * Constructs the factory. + * + * @param aClass + * Interface class of the service to proxy. + * @param aJndi JNDI name of the object to lookup. + * + */ + public JndiProxyFactory(Class aClass, String aJndi) { + if (!aClass.isInterface()) { + throw new IllegalArgumentException("Class " + aClass.getName() + + " is not an interface"); + } + clazz = aClass; + jndi = aJndi; + } + + /** + * Gets the proxy that delegates to the thread-specific instance set by + * {@link #set(Object)} + * + * When at runtime the proxy cannot find lookup the object in JNDI, it + * throws {@link JndiWiringException}. + * + * @return Proxy. + */ + public T getProxy() { + InvocationHandler handler = new JndiInvocationHandler(); + Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), + new Class[] { clazz }); + T proxy; + try { + proxy = (T) proxyClass.getConstructor( + new Class[] { InvocationHandler.class }).newInstance( + new Object[] { handler }); + return proxy; + } catch (Exception e) { + throw new RuntimeException("Could not create proxy for " + + clazz.getName(), e); + } + } +}