net.smartlab.web.EnterpriseDomainBuilder Maven / Gradle / Ivy
/*
* The SmartWeb Framework
* Copyright (C) 2004-2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* For further informations on the SmartWeb Framework please visit
*
* http://smartweb.sourceforge.net
*/
package net.smartlab.web;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.RemoteException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.ejb.EJBHome;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This class works as a Business Delegate for Session Enterprise Java Beans.
* @author rlogiacco
* @uml.dependency supplier="net.smartlab.web.EnterpriseDomain"
*/
public class EnterpriseDomainBuilder extends Domain {
/**
* Provides logging capabilities to the builder.
*/
private final static Log logger = LogFactory.getLog(EnterpriseDomainBuilder.class);
protected final static Map primitives = new TreeMap();
static {
primitives.put("boolean", boolean.class);
primitives.put("byte", byte.class);
primitives.put("short", short.class);
primitives.put("int", int.class);
primitives.put("long", long.class);
primitives.put("float", float.class);
primitives.put("double", double.class);
primitives.put("char", char.class);
}
/**
* Associating map for EJB homes. Home objects are cached here for single
* JNDI lookup, but should be checked for bindings update.
*/
private final static Map homes = Collections.synchronizedMap(new HashMap());
/**
* @TODO documentation
* @param name
* @param type
* @return
*/
public static Object getInstance(String name, Class type) {
return EnterpriseDomainBuilder.getInstance(name, type, null, null);
}
/**
* @TODO documentation
* @param name
* @param type
* @param params
* @return
*/
public static Object getInstance(String name, Class type, Object[] params) {
return EnterpriseDomainBuilder.getInstance(name, type, null, params);
}
/**
* TODO documentation
*
* @param name
* @param type
* @param context
* @return
*/
public static Object getInstance(String name, Class type, Context context) {
return EnterpriseDomainBuilder.getInstance(name, type, context, null);
}
/**
* TODO documentation
*
* @param name
* @param type
* @param context
* @param params
* @return
*/
public static Object getInstance(String name, Class type, Context context, Object[] params) {
HomeWrapper wrapper = (HomeWrapper)homes.get(name);
if (wrapper == null) {
// home not found
try {
if (context == null) {
context = new InitialContext();
logger.debug("no context specified");
}
Object home = context.lookup(name);
if (home instanceof EJBHome) {
home = PortableRemoteObject.narrow(home, EJBHome.class);
}
wrapper = new HomeWrapper(home);
homes.put(name, wrapper);
} catch (NamingException ne) {
logger.error("lookup(" + name + ") - error", ne);
return null;
}
} else {
if (System.currentTimeMillis() - wrapper.getLastCheck() > 60000) {
homes.remove(name);
}
}
try {
Class[] paramTypes = null;
if (params != null) {
paramTypes = new Class[params.length];
for (int i = 0; i < paramTypes.length; i++) {
paramTypes[i] = params[i].getClass();
}
}
Object ejb = wrapper.getHome().getClass().getDeclaredMethod("create", paramTypes).invoke(wrapper.getHome(),
params);
return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[] {type},
new EnterpriseDomainWrapper(ejb));
} catch (Exception e) {
homes.remove(name);
logger.error("ejb home class instantiation failed", e);
return null;
}
}
private static class EnterpriseDomainWrapper implements InvocationHandler {
/**
* Logger for this class
*/
private static final Log logger = LogFactory.getLog(EnterpriseDomain.class);
/**
* TODO documentation Comment for ejb
*/
private Object ejb;
/**
* TODO documentation
*
* @param ejb
*/
private EnterpriseDomainWrapper(Object ejb) {
this.ejb = ejb;
}
/**
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
* java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] params) throws Throwable {
if (logger.isDebugEnabled()) {
logger.debug("invoke(" + ejb + ", " + method + ", " + params + ")");
}
Object result = null;
try {
if (ejb instanceof EnterpriseDomain.Remote) {
String[] types = EnterpriseDomainWrapper.getNames(method.getParameterTypes());
result = ((EnterpriseDomain.Remote)ejb).execute(method.getName(), params, types, EnterpriseDomain
.getContext());
} else {
result = method.invoke(ejb, params);
}
} catch (RemoteException re) {
if (re.detail instanceof InvocationTargetException) {
// Exception thrown by the business tier
throw ((InvocationTargetException)re.detail).getTargetException();
} else {
// Exception thrown by the communication layer
throw re;
}
}
if (logger.isDebugEnabled()) {
logger.debug("invoke(" + ejb + ", " + method + ", " + params + ") - finish with result=" + result);
}
return result;
}
/**
* Get the class names than can be used in remote reflection invocation.
*
* @param paramTypes The method argument classes
* @return class names
*/
private static String[] getNames(Class[] paramTypes) {
String[] paramNames = new String[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
paramNames[i] = paramTypes[i].getName();
}
return paramNames;
}
}
protected static class HomeWrapper {
private Object home;
private long lastCheck;
private HomeWrapper(Object home) {
this.home = home;
this.lastCheck = System.currentTimeMillis();
}
public long getLastCheck() {
return lastCheck;
}
public Object getHome() {
return home;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy