Package org.apache.tuscany.sca.binding.ejb.util

Source Code of org.apache.tuscany.sca.binding.ejb.util.EJBObjectFactory

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.tuscany.sca.binding.ejb.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;

import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;
import javax.naming.NamingException;
import javax.rmi.CORBA.Util;

import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.ObjectImpl;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.stub.java.rmi._Remote_Stub;
import org.oasisopen.sca.ServiceRuntimeException;

/**
* Factor class that is used to create EJB Proxies.
*
* @version $Rev: 738490 $ $Date: 2009-01-28 14:07:54 +0000 (Wed, 28 Jan 2009) $
*/
final class EJBObjectFactory {

    private EJBObjectFactory() {
    }

    /**
     * Get either a generated of dynamic EJB stub using the specified JNDI
     * properties.
     * <p>
     * The returned stub will implement the specified stubInterface Interface.
     * If the underlying EJB stub is not assignable from the specified
     * stubInterface then a proxy is used to convert between the two.
     * <p>
     * The returned EJB stub may be either the pregenerated EJB stub or a
     * dynamic stub. This allows a client to invoke an EJB without requiring any
     * of the pregenerated EJB stub classes be available in the classpath.
     * <p>
     */
    static Object createStub(NamingEndpoint namingEndpoint, InterfaceInfo ejbInterface) throws NamingException,
        RemoteException, CreateException {

        EJBLocator locator = namingEndpoint.getLocator();
        Object homeObject = locator.locate(namingEndpoint.getJndiName());
        /*
         * The type of the object returned from the lookup is as follows: If the
         * generated stub exists on the classpath, it's an instance of that
         * type, otherwise, "org.omg.stub.java.rmi._Remote_Stub" or
         * "org.omg.stub.javax.ejb._EJBHome_Stub"
         */
        Object stub = getEJBStub(homeObject, ejbInterface);
        // Cache dynamic stub only
        return stub;
    }

    /**
     * @param homeObject
     * @param ejbHomeClass
     * @return
     * @throws RemoteException
     */
    private static Object getEJBStub(Object homeObject, InterfaceInfo ejbInterface) throws RemoteException,
        CreateException {

        Object stub = null;

        // Get the business interface of the EJB
        Class ejbInterfaceClass = null;
        try {
            ejbInterfaceClass = Thread.currentThread().getContextClassLoader().loadClass(ejbInterface.getName());
        } catch (ClassNotFoundException e) {
            // ignore
        }

        if (ejbInterfaceClass != null && ejbInterfaceClass.isInstance(homeObject)) {
            // EJB 3
            stub = homeObject;
        } else if (homeObject instanceof EJBLocalHome) {
            // Local EJB
            stub = createEJBLocalObject(homeObject);
        } else {
            // Handle dynamic stub
            if (homeObject instanceof ObjectImpl) {
                ObjectImpl objectImpl = (ObjectImpl)homeObject;
                stub = createEJBObject(objectImpl);
            }/**
                         * Above checks will be satisfied if Bean is running on servers like WebSphere. With this
                         * logic, client (SCA composite with EJB ref binding) doesn't need to include home class or
                         * client stubs.
                         *
                         * Below check is needed SCA composite with EJB ref binding is accessing openEJB implementation.
                         * For e.g if the bean is running on Geronimo.
                         */
            else if ((javax.rmi.PortableRemoteObject.narrow(homeObject, javax.ejb.EJBHome.class)) instanceof javax.ejb.EJBHome) {
                stub = createEJBObjectFromHome(homeObject);
            } else
                throw new ServiceRuntimeException("Invalid stub type: " + homeObject.getClass());
        }
        return stub;
    }

    /**
     * Create a pre-generated EJB stub
     *
     * @param homeObject
     * @return
     * @throws RemoteException
     */
    static private Object createEJBLocalObject(Object homeObject) throws RemoteException {

        Object stub = null;
        try {
            // Find the "create()" method
            Method createMethod = homeObject.getClass().getMethod("create", null);
            // Create an EJB object
            stub = createMethod.invoke(homeObject, null);
        } catch (NoSuchMethodException e) {
            // "create()" method not found, it's still a dynamic stub
            stub = null;
        } catch (InvocationTargetException e) {
            throw new RemoteException(e.getTargetException().toString());
        } catch (Exception e) {
            throw new RemoteException(e.toString());
        }
        return stub;
    }

    /**
     * Here homeObject is instance of EJBHome
     *
     * @param homeObject
     * @return
     * @throws RemoteException
     */
    private static Object createEJBObjectFromHome(Object homeObject) throws RemoteException {

        Object stub = null;
        try {
            // Find the "create()" method
            Method createMethod = homeObject.getClass().getMethod("create", null);
            // Create an EJB object
            stub = createMethod.invoke(homeObject, null);
        } catch (NoSuchMethodException e) {
            // "create()" method not found, it's still a dynamic stub
            stub = null;
        } catch (InvocationTargetException e) {
            throw new RemoteException(e.getTargetException().toString());
        } catch (Exception e) {
            throw new RemoteException(e.toString());
        }
        return stub;
    }

    /**
     * Create an EJBObject using RMI/IIOP APIs
     *
     * @param ejbHomeObject
     * @return The EJBObject remote stub
     * @throws CreateException
     * @throws RemoteException
     */
    private static Object createEJBObject(ObjectImpl ejbHomeObject) throws CreateException, RemoteException {

        try {
            org.omg.CORBA_2_3.portable.InputStream in = null;
            try {
                org.omg.CORBA.portable.OutputStream out = ejbHomeObject._request("create", true);
                in = (org.omg.CORBA_2_3.portable.InputStream)ejbHomeObject._invoke(out);
                // The Remote stub should be available in JDK
                // TODO: [rfeng] Work around an issue in Apache Yoko which doesn't understand the org.omg.stub.*
                return in.read_Object(_Remote_Stub.class);
            } catch (ApplicationException ex) {
                in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                String id = in.read_string();
                if (id.equals("IDL:javax/ejb/CreateEx:1.0")) {
                    throw (CreateException)in.read_value(CreateException.class);
                }
                throw new UnexpectedException(id);
            } catch (RemarshalException ex) {
                return createEJBObject(ejbHomeObject);
            } finally {
                ejbHomeObject._releaseReply(in);
            }
        } catch (SystemException ex) {
            throw Util.mapSystemException(ex);
        }
    }
}
TOP

Related Classes of org.apache.tuscany.sca.binding.ejb.util.EJBObjectFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.