/*
 * Copyright (c) 1998, 2021 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;

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

import org.eclipse.persistence.sessions.remote.rmi.iiop.RMIRemoteSessionController;
import java.rmi.Remote;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.ORB;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.CORBA.portable.UnknownException;
import org.omg.CORBA_2_3.portable.ObjectImpl;


public class _RMIServerManagerController_Tie extends ObjectImpl implements Tie {

    private RMIServerManagerController target = null;

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

    @Override
    public String[] _ids() {
        return _type_ids;
    }
    @Override
    public OutputStream  _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
        try {
            org.omg.CORBA_2_3.portable.InputStream in =
                (org.omg.CORBA_2_3.portable.InputStream) _in;
            if (method.equals("createRemoteSessionController")) {
                RMIRemoteSessionController result = target.createRemoteSessionController();
                OutputStream out = reply.createReply();
                Util.writeRemoteObject(out,result);
                return out;
            }
            throw new BAD_OPERATION();
        } catch (SystemException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new UnknownException(ex);
        }
    }
    @Override
    public void deactivate() {
        _orb().disconnect(this);
        _set_delegate(null);
        target = null;
    }
    @Override
    public Remote getTarget() {
        return target;
    }
    @Override
    public ORB orb() {
        return _orb();
    }
    @Override
    public void orb(ORB orb) {
        orb.connect(this);
    }
    @Override
    public void setTarget(Remote target) {
        this.target = (RMIServerManagerController) target;
    }
    @Override
    public org.omg.CORBA.Object thisObject() {
        return this;
    }
}
