/*
 * Copyright (c) 1998, 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,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.remote.rmi.IIOP;

// Stub class generated by rmic, do not edit.
// Contents subject to change without notice.

import org.eclipse.persistence.sessions.remote.rmi.iiop.RMIRemoteSessionController;
import org.eclipse.persistence.sessions.remote.rmi.iiop._RMIRemoteSessionController_Stub;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.CORBA.portable.ServantObject;


public class _RMIServerManager_Stub extends Stub implements RMIServerManager {

    private static final String[] _type_ids = {
        "RMI:org.eclipse.persistence.testing.tests.remote.rmi.IIOP.RMIServerManager:0000000000000000"
    };

    public String[] _ids() {
        return _type_ids;
    }
    public RMIRemoteSessionController createRemoteSessionController() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA.portable.InputStream in = null;
                try {
                    OutputStream out = _request("createRemoteSessionController", true);
                    in = _invoke(out);
                    return (RMIRemoteSessionController) in.read_Object(_RMIRemoteSessionController_Stub.class);
                } catch (ApplicationException ex) {
                    in = ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return createRemoteSessionController();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("createRemoteSessionController",RMIServerManager.class);
            if (so == null) {
                return createRemoteSessionController();
            }
            try {
                RMIRemoteSessionController result = ((RMIServerManager)so.servant).createRemoteSessionController();
                return (RMIRemoteSessionController)Util.copyObject(result,_orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }
}
