Open Source Repository

Home /open-symphony/oscore-2.2.6 | Repository Home


com/opensymphony/util/EJBUtils.java
/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package com.opensymphony.util;


/* ====================================================================
 * The OpenSymphony Software License, Version 1.1
 *
 * (this license is derived and fully compatible with the Apache Software
 * License - see http://www.apache.org/LICENSE.txt)
 *
 * Copyright (c) 2001 The OpenSymphony Group. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        OpenSymphony Group (http://www.opensymphony.com/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "OpenSymphony" and "The OpenSymphony Group"
 *    must not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact [email protected] .
 *
 * 5. Products derived from this software may not be called "OpenSymphony"
 *    or "OSCore", nor may "OpenSymphony" or "OSCore" appear in their
 *    name, without prior written permission of the OpenSymphony Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 */
import java.lang.reflect.*;

import java.rmi.*;

import java.util.*;

import javax.ejb.*;

import javax.naming.*;

import javax.rmi.*;


/**
 * Utilities for Enterprise JavaBeans (and JNDI).
 *
 * This is a class contains static methods only and is not meant to be instantiated.
 *
 @author <a href="mailto:[email protected]">Joe Walnes</a>
 @author <a href="mailto:[email protected]">Hani Suleiman</a>
 @author <a href="mailto:[email protected]">Dion Almaer</a>
 @version $Revision: 125 $
 */
public class EJBUtils {
    //~ Static fields/initializers /////////////////////////////////////////////

    /**
     * Method cache for finders.
     */
    private static HashMap finderMethods = new HashMap();

    /**
     * Set to cache which JNDI lookups shouldn't be checked for in java:comp/env
     */
    private static Set ignoreEnvLocations = new HashSet();

    //~ Methods ////////////////////////////////////////////////////////////////

    /**
     * Get root naming context (InitialContext).
     *
     @see javax.naming.InitialContext
     */
    public final static Context getRoot() throws NamingException, RemoteException {
        //if (rootContext == null) {
        //  rootContext = new InitialContext( System.getProperties() );
        //}
        //return rootContext;
        return new InitialContext();
    }

    /**
     * Method to lookup a stateless session EJB's home interface, and create
     * an instance using the create() method. Any exceptions thrown by the
     * create() method shall be rethrown (java.lang.Throwable).
     */
    public final static Object createStateless(String locationthrows Throwable {
        try {
            Object home = EJBUtils.lookup(location);
            Method createMethod = home.getClass().getDeclaredMethod("create"null);

            return createMethod.invoke(home, null);
        catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    /**
     * Utility method for attempting to find a specific entity bean given it's home
     * interface and primary key.
     *
     <p>Attempts to call the following methods in order:</p>
     <pre>
     *   home.findByPrimaryKey(int id);
     *   home.findByPrimaryKey(long id);
     *   home.findByPrimaryKey(Integer id);
     *   home.findByPrimaryKey(Long id);
     *   home.findByPrimaryKey(String id);
     </pre>
     *
     @param home Reference to entity home interface.
     @param id Value of primary key.
     @return Reference to <code>EJBObject</code> to be casted to desired type.
     @exception java.rmi.RemoteException Rethrown if thrown by finder method.
     @exception javax.ejb.FinderException Rethrown if thrown by finder method.
     */
    public final static EJBObject findEntity(EJBHome home, String idthrows RemoteException, FinderException {
        // Use reflection to try and find a suitable findByPrimaryKey method.
        try {
            // Class of implementation of EJBHome
            Class homeClass = home.getClass();

            // Possible param types (type->value)
            OrderedMap params = new OrderedMap();
            params.put(Integer.TYPE, new Integer(TextUtils.parseInt(id)));
            params.put(Long.TYPE, new Long(TextUtils.parseLong(id)));
            params.put("java.lang.Integer"new Integer(TextUtils.parseInt(id)));
            params.put("java.lang.Long"new Long(TextUtils.parseLong(id)));
            params.put("java.lang.String", id);

            // Loop through different types of params.
            Iterator it = params.iterator();

            while (it.hasNext()) {
                Object classType = it.next();

                // Attempt to invoke and return result from method.
                try {
                    Method m = null;

                    if (!finderMethods.containsKey(homeClass)) {
                        // first create array containing a single element, which is our class
                        Class[] theClass = new Class[] {
                            (classType instanceof String? Class.forName((StringclassType(ClassclassType
                        };

                        // find method with signature of above classes.
                        m = homeClass.getMethod("findByPrimaryKey", theClass);

                        //Cache the method, for performance.
                        finderMethods.put(homeClass, m);
                    else {
                        //It's in the cache, so use the method from there.
                        m = (MethodfinderMethods.get(homeClass);
                    }

                    Object[] args = new Object[] {params.get(classType)}// these are the params
                    EJBObject result = (EJBObjectm.invoke(home, args);

                    // If a result is returned, return it.
                    if (result != null) {
                        return result; // SUCCESS!!
                    else {
                    }
                catch (ClassCastException e) {
                    //if (
                    // The method was invoked but didn't return an instance of EJBObject
                    //logger.isDebugEnabled()) {
                    // The method was invoked but didn't return an instance of EJBObject
                    //logger.debug(e);
                    //}
                catch (ClassNotFoundException e) {
                    //if (
                    // This is never going to happen - it means java.lang.Integer is missing!!
                    // Carry on anyway and try the next one.
                    //logger.isDebugEnabled()) {
                    // This is never going to happen - it means java.lang.Integer is missing!!
                    // Carry on anyway and try the next one.
                    //logger.debug(e);
                    //}
                catch (NoSuchMethodException e) {
                    //if (
                    // Missing a findByPrimaryKey for this type - let's try another one.
                    //logger.isDebugEnabled()) {
                    // Missing a findByPrimaryKey for this type - let's try another one.
                    //logger.debug(e);
                    //}
                catch (IllegalAccessException e) {
                    //if (
                    // This findByPrimaryKey is protected/private - let's try another one.
                    //logger.isDebugEnabled()) {
                    // This findByPrimaryKey is protected/private - let's try another one.
                    //logger.debug(e);
                    //}
                catch (InvocationTargetException e) {
                    // Unwrap to find the actual exception
                    Throwable t = e.getTargetException();

                    //if (
                    // Rethrow actual exception if RemoteException or FinderException.
                    //logger.isDebugEnabled()) {
                    // Rethrow actual exception if RemoteException or FinderException.
                    //logger.debug(e);
                    //}
                    if (instanceof RemoteException) {
                        throw (RemoteExceptiont;
                    }

                    if (instanceof FinderException) {
                        throw (FinderExceptiont;
                    }
                }
            }
        catch (NullPointerException e) {
            //if (
            //    // home passed across was null. Can't really do anything with that.
            //    logger.isDebugEnabled()) {
            //    // home passed across was null. Can't really do anything with that.
            //    logger.debug(e);
            //}
        }

        //if (
        //    // Nothing was found. Oh well. Worth a try.
        //    logger.isDebugEnabled()) {
        //    // Nothing was found. Oh well. Worth a try.
        //    logger.debug("findEntity() found nothing");
        //}
        return null;
    }

    /**
     @see #findEntity(javax.ejb.EJBHome, String)
     */
    public final static EJBObject findEntity(EJBHome home, int idthrows RemoteException, FinderException {
        return findEntity(home, "" + id);
    }

    /**
     @see #findEntity(javax.ejb.EJBHome, String)
     */
    public final static EJBObject findEntity(EJBHome home, long idthrows RemoteException, FinderException {
        return findEntity(home, "" + id);
    }

    /**
     * Utility method for looking up and narrowing an Object via JNDI. Used when using RMI-IIOP.
     *
     @see #lookup(String)
     @see #narrow(Object, Class)
     */
    public final static Object lookup(String location, Class classTypethrows NamingException, RemoteException {
        return narrow(lookup(location), classType);
    }

    /**
     * Utility method for looking up an Object via JNDI. Prefixes <code>java:comp/env/</code>
     * to <code>location</code>. If that is not found, it retries without the prefix.
     *
     @param location JNDI location
     */
    public final static Object lookup(String locationthrows NamingException, RemoteException {
        // if already determined that env location should be ignored...
        NamingException notFoundE = null;

        if (ignoreEnvLocations.contains(location)) {
            try {
                return getRoot().lookup(location);
            catch (NamingException e) {
                // hmmm... maybe it's changed location in the JNDI tree
                ignoreEnvLocations.remove(location);
                notFoundE = e;
            }
        }

        try {
            return getRoot().lookup("java:comp/env/" + location);
        catch (NamingException e) {
            if (notFoundE != null) {
                throw notFoundE; // throw first exception if it exists
            }

            ignoreEnvLocations.add(location);

            return getRoot().lookup(location);
        }
    }

    /**
     * Utility method for narrowing portable object to a class
     */
    public final static Object narrow(Object o, Class classType) {
        return PortableRemoteObject.narrow(o, classType);
    }
}