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

com.sun.ejb.codegen.Remote30WrapperGenerator Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021, 2023 Contributors to the Eclipse Foundation.
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejb.codegen;

import com.sun.ejb.containers.InternalEJBContainerException;
import com.sun.ejb.containers.InternalRemoteException;
import com.sun.ejb.containers.RemoteBusinessWrapperBase;
import com.sun.enterprise.util.LocalStringManagerImpl;

import jakarta.ejb.EJBAccessException;
import jakarta.ejb.EJBException;
import jakarta.ejb.EJBObject;
import jakarta.ejb.EJBTransactionRequiredException;
import jakarta.ejb.EJBTransactionRolledbackException;
import jakarta.ejb.NoSuchEJBException;
import jakarta.transaction.TransactionRequiredException;
import jakarta.transaction.TransactionRolledbackException;

import java.lang.reflect.Method;
import java.rmi.AccessException;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.LinkedList;
import java.util.List;

import org.glassfish.pfl.dynamic.codegen.spi.Expression;
import org.glassfish.pfl.dynamic.codegen.spi.Type;
import org.omg.CORBA.SystemException;

import static java.lang.reflect.Modifier.PRIVATE;
import static java.lang.reflect.Modifier.PUBLIC;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._String;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._arg;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._assign;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._body;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._call;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._cast;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._catch;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._class;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._constructor;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._data;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._define;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._end;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._expr;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._method;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._new;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._return;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._s;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._super;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._t;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._throw;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._try;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._v;
import static org.glassfish.pfl.dynamic.codegen.spi.Wrapper._void;


/**
 * Generator of EJB 3.0+ Remote client stub implementations.
 */
public final class Remote30WrapperGenerator extends Generator {

    private static final LocalStringManagerImpl I18N = new LocalStringManagerImpl(Remote30WrapperGenerator.class);

    private final String remoteInterfaceName;
    private final Class businessInterface;
    private final String remoteClientClassName;
    private final String remoteClientPackageName;
    private final String remoteClientSimpleName;
    private final Method[] methodsToGenerate;

    /**
     * Adds _Wrapper to the original name.
     *
     * @param businessIntf full class name
     * @return [businessIntf]_Wrapper
     */
    public static String getGeneratedRemoteWrapperName(final String businessIntf) {
        final String packageName = getPackageName(businessIntf);
        final String simpleName = getBaseName(businessIntf);
        final String generatedSimpleName = "_" + simpleName + "_Wrapper";
        return getFullClassName(packageName, generatedSimpleName);
    }

    /**
     * Construct the Wrapper generator with the specified deployment
     * descriptor and class loader.
     *
     * @param loader class loader
     * @param businessIntfName must already exist and be loadable by the loader
     * @param remoteInterfaceName generated class will implement this
     *
     * @throws GeneratorException if an error occurred during class generation
     */
    public Remote30WrapperGenerator(final ClassLoader loader, final String businessIntfName, final String remoteInterfaceName)
        throws GeneratorException {

        super(loader);
        this.remoteInterfaceName = remoteInterfaceName;

        try {
            businessInterface = loader.loadClass(businessIntfName);
        } catch (final ClassNotFoundException ex) {
            throw new GeneratorException(I18N.getLocalString(
                "generator.remote_interface_not_found",
                "Business interface " + businessIntfName + " not found "));
        }

        if (EJBObject.class.isAssignableFrom(businessInterface)) {
            throw new GeneratorException("Invalid Remote Business Interface " + businessInterface
                + ". A Remote Business interface MUST NOT extend jakarta.ejb.EJBObject.");
        }

        remoteClientClassName = getGeneratedRemoteWrapperName(businessIntfName);
        remoteClientPackageName = getPackageName(remoteClientClassName);
        remoteClientSimpleName = getBaseName(remoteClientClassName);

        methodsToGenerate = removeRedundantMethods(businessInterface.getMethods());

        // NOTE: no need to remove ejb object methods because EJBObject
        // is only visible through the RemoteHome view.
    }

    @Override
    public String getPackageName() {
        return this.remoteClientPackageName;
    }

    @Override
    public String getGeneratedClassName() {
        return remoteClientClassName;
    }

    @Override
    public Class getAnchorClass() {
        return businessInterface;
    }

    @Override
    public void defineClassBody() {
        _class(PUBLIC, remoteClientSimpleName,
               _t(RemoteBusinessWrapperBase.class.getName()),
               _t(businessInterface.getName()));

        _data(PRIVATE, _t(remoteInterfaceName), "delegate_");

        _constructor( PUBLIC ) ;
        _arg(_t(remoteInterfaceName), "stub");
        _arg(_String(), "busIntf");

        _body();
        _expr(_super(_s(_void(), _t(Remote.class.getName()), _String()), _v("stub"), _v("busIntf")));
        _assign(_v("delegate_"), _v("stub"));
        _end();

        for (final Method method : methodsToGenerate) {
            printMethodImpl(method);
        }

        _end();
    }


    private void printMethodImpl(final Method m) {
        final List exceptionList = new LinkedList<>();
        for (final Class exception : m.getExceptionTypes()) {
            exceptionList.add(Type.type(exception));
        }

        final Type returnType = Type.type(m.getReturnType());
        _method(PUBLIC, returnType, m.getName(), exceptionList);

        int i = 0;
        final List expressionListTypes = new LinkedList<>();
        final List expressionList = new LinkedList<>();
        for (final Class param : m.getParameterTypes()) {
            final String paramName = "param" + i;
            _arg(Type.type(param), paramName);
            i++;
            expressionListTypes.add(Type.type(param));
            expressionList.add(_v(paramName));
        }

        _body();

        _try();

        if (m.getReturnType() == void.class) {
            _expr(
                _call(_v("delegate_"), m.getName(), _s(returnType, expressionListTypes), expressionList));
        } else {
            _return(
                _call(_v("delegate_"), m.getName(), _s(returnType, expressionListTypes), expressionList));
        }

        final boolean doExceptionTranslation = !Remote.class.isAssignableFrom(businessInterface);
        if (doExceptionTranslation) {
            _catch(_t(TransactionRolledbackException.class.getName()), "trex");

            _define(_t(RuntimeException.class.getName()), "r",
                _new(_t(EJBTransactionRolledbackException.class.getName()), _s(_void())));
            _expr(
                _call(
                    _v("r"), "initCause",
                    _s(_t(Throwable.class.getName()), _t(Throwable.class.getName())),
                    _v("trex")
                )
            );
            _throw(_v("r"));

            _catch(_t(TransactionRequiredException.class.getName()), "treqex");

            _define(_t(RuntimeException.class.getName()), "r",
                _new(_t(EJBTransactionRequiredException.class.getName()), _s(_void())));

            _expr(
                _call(
                    _v("r"), "initCause",
                    _s(_t(Throwable.class.getName()), _t(Throwable.class.getName())),
                    _v("treqex")
                )
            );
            _throw(_v("r"));

            _catch(_t(NoSuchObjectException.class.getName()), "nsoe");

            _define(_t(RuntimeException.class.getName()), "r",
                _new(_t(NoSuchEJBException.class.getName()), _s(_void())));
            _expr(
                _call(
                    _v("r"), "initCause",
                    _s(_t(Throwable.class.getName()), _t(Throwable.class.getName())),
                    _v("nsoe")
                )
            );
            _throw(_v("r"));

            _catch(_t(AccessException.class.getName()), "accex");

            _define(_t(RuntimeException.class.getName()), "r",
                _new(_t(EJBAccessException.class.getName()), _s(_void())));
            _expr(
                _call(
                    _v("r"), "initCause",
                    _s(_t(Throwable.class.getName()), _t(Throwable.class.getName())),
                    _v("accex")
                )
            );
            _throw(_v("r"));

            _catch(_t(InternalEJBContainerException.class.getName()), "iejbcEx");

            _throw(
                _cast(
                    _t(EJBException.class.getName()),
                    _call(_v("iejbcEx"), "getCause", _s(_t(Throwable.class.getName())))
                )
            );


            _catch(_t(RemoteException.class.getName()), "re");

            _throw( _new( _t(EJBException.class.getName()), _s(_void(), _t(Exception.class.getName())), _v("re")));

            _catch( _t(SystemException.class.getName()), "corbaSysEx");
            _define( _t(RuntimeException.class.getName()), "r", _new( _t(EJBException.class.getName()), _s(_void())));
            _expr(
                _call(
                    _v("r"), "initCause",
                    _s(_t(Throwable.class.getName()), _t(Throwable.class.getName())),
                    _v("corbaSysEx")
                )
            );
            _throw(_v("r"));

            _end();

        } else {
            _catch(_t(InternalEJBContainerException.class.getName()), "iejbcEx");
            _throw(
                _new( _t(InternalRemoteException.class.getName()),
                _s(_void(), _t(InternalEJBContainerException.class.getName())),
                _v("iejbcEx"))
            );
            _end();
        }

        _end();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy