/*
 * 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.suncorba;

/**
* org/eclipse/persistence/testing/Remote/SunCORBA/_CORBAServerManagerStub.java
* Generated by the IDL-to-Java compiler (portable), version "3.0"
* from CORBAServerManager.idl
* Wednesday, August 23, 2000 1:20:43 PM EDT
*/

public class _CORBAServerManagerStub extends org.omg.CORBA.portable.ObjectImpl implements org.eclipse.persistence.testing.tests.remote.suncorba.CORBAServerManager
{
  // Type-specific CORBA::Object operations
  private static String[] __ids = {
    "IDL:org/eclipse/persistence/testing/Remote/SunCORBA/CORBAServerManager:1.0"};

  // Constructors
  // NOTE:  If the default constructor is used, the
  //        object is useless until _set_delegate (...)
  //        is called.
  public _CORBAServerManagerStub ()
  {
    super ();
  }
  public _CORBAServerManagerStub (org.omg.CORBA.portable.Delegate delegate)
  {
    super ();
    _set_delegate (delegate);
  }
  @Override
  public String[] _ids ()
  {
    return __ids.clone ();
  }
  @Override
  public org.eclipse.persistence.sessions.remote.corba.sun.CORBARemoteSessionController createRemoteSessionController ()
  {
    org.omg.CORBA.portable.InputStream _in = null;
    try {
       org.omg.CORBA.portable.OutputStream _out = _request ("createRemoteSessionController", true);
       _in = _invoke (_out);
       org.eclipse.persistence.sessions.remote.corba.sun.CORBARemoteSessionController __result = org.eclipse.persistence.sessions.remote.corba.sun.CORBARemoteSessionControllerHelper.read (_in);
       return __result;
    } catch (org.omg.CORBA.portable.ApplicationException _ex) {
       _in = _ex.getInputStream ();
       String _id = _ex.getId ();
       throw new org.omg.CORBA.MARSHAL (_id);
    } catch (org.omg.CORBA.portable.RemarshalException _rm) {
       return createRemoteSessionController ();
    } finally {
        _releaseReply (_in);
    }
  } // createRemoteSessionController
  private void readObject (java.io.ObjectInputStream s)
  {
     try
     {
       String str = s.readUTF ();
       org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init ().string_to_object (str);
       org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
       _set_delegate (delegate);
     } catch (java.io.IOException e) {}
  }
  private void writeObject (java.io.ObjectOutputStream s)
  {
     try
     {
       String str = org.omg.CORBA.ORB.init ().object_to_string (this);
       s.writeUTF (str);
     } catch (java.io.IOException e) {}
  }
} // class _CORBAServerManagerStub
