All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.smartlab.web.EnterpriseDomainBuilder Maven / Gradle / Ivy

Go to download

SmartWeb is a web application development meta framework based on Jakarta Struts, Hibernate and other open source frameworks and libraries.

There is a newer version: 1.2.13
Show newest version
/*
 * 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