package com.highqsoft.corbafileserver.generated;


/**
* com/highqsoft/corbafileserver/generated/_CORBAFileServerIFStub.java .
* Generated by the IDL-to-Java compiler (portable), version "3.2"
* from src/main/idl/corbafileserver.idl
* Donnerstag, 16. Juni 2016 10:30 Uhr MESZ
*/

public class _CORBAFileServerIFStub extends org.omg.CORBA.portable.ObjectImpl implements com.highqsoft.corbafileserver.generated.CORBAFileServerIF
{


  /**
        * Save the data associated with the given intput stream.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  subDir an alternative sub directory, that can be specified,
        *                if the filename should not used to determine the destination folder.
        * @param  stream the input stream, ready to read by the server.
        * @return the url string of the created file.
        */
  public String save (org.asam.ods.AoSession aoSess, String name, String subDir, com.highqsoft.corbafileserver.generated.InputStreamIF stream) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("save", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                com.highqsoft.corbafileserver.generated.InputStreamIFHelper.write ($out, stream);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return save (aoSess, name, subDir, stream        );
            } finally {
                _releaseReply ($in);
            }
  } // save


  /**
        * Save the data associated with the given intput stream.
        * Specify the ApplicationElement id and the InstanceElement id
        * of the component that holds the external reference.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  subDir an alternative sub directory, that can be specified,
        *                if the filename should not used to determine the destination folder.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        * @param  stream the input stream, ready to read by the server.
        * @return the url string of the created file.
        */
  public String saveForInstance (org.asam.ods.AoSession aoSess, String name, String subDir, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid, com.highqsoft.corbafileserver.generated.InputStreamIF stream) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("saveForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                com.highqsoft.corbafileserver.generated.InputStreamIFHelper.write ($out, stream);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return saveForInstance (aoSess, name, subDir, aid, iid, stream        );
            } finally {
                _releaseReply ($in);
            }
  } // saveForInstance


  /**
        * Save the data associated with the given intput stream.
        * Specify the name of an applciation element and the name of the instance element
        * that holds the external reference
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  subDir an alternative sub directory, that can be specified,
        *                if the filename should not used to determine the destination folder.
        * @param  aeName the application element name.
        * @param  ieName the instance element name.
        * @param  stream the input stream, ready to read by the server.
        * @return the url string of the created file.
        */
  public String saveForInstanceName (org.asam.ods.AoSession aoSess, String name, String subDir, String aeName, String ieName, com.highqsoft.corbafileserver.generated.InputStreamIF stream) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("saveForInstanceName", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                $out.write_string (aeName);
                $out.write_string (ieName);
                com.highqsoft.corbafileserver.generated.InputStreamIFHelper.write ($out, stream);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return saveForInstanceName (aoSess, name, subDir, aeName, ieName, stream        );
            } finally {
                _releaseReply ($in);
            }
  } // saveForInstanceName


  /**
        * Delete the data associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        */
  public void delete (org.asam.ods.AoSession aoSess, String name) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("delete", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                delete (aoSess, name        );
            } finally {
                _releaseReply ($in);
            }
  } // delete


  /**
        * Move the data associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  urlo the url of the file.
        */
  public void move (org.asam.ods.AoSession aoSess, String url) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("move", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (url);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                move (aoSess, url        );
            } finally {
                _releaseReply ($in);
            }
  } // move


  /**
        * Delete the data associated with the given name.
        * Specify the ApplicationElement id and the InstanceElement id
        * of the component that holds the external reference.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  url the url of the file.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        */
  public void deleteForInstance (org.asam.ods.AoSession aoSess, String url, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("deleteForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (url);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                deleteForInstance (aoSess, url, aid, iid        );
            } finally {
                _releaseReply ($in);
            }
  } // deleteForInstance


  /**
        * Move the data associated with the given name.
        * Specify the ApplicationElement id and the InstanceElement id
        * of the component that holds the external reference.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        */
  public void moveForInstance (org.asam.ods.AoSession aoSess, String name, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("moveForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                moveForInstance (aoSess, name, aid, iid        );
            } finally {
                _releaseReply ($in);
            }
  } // moveForInstance


  /**
         * Get the data using a socket.
         *
         * @throws CORBAFileServerException
         * with the following possible error codes:
         *    FILESERVER_CONNECT_FAILED
         *    FILESERVER_BAD_PARAMETER
         *    FILESERVER_CONNECTION_LOST
         *    FILESERVER_IMPLEMENTATION_PROBLEM
         *    FILESERVER_NOT_IMPLEMENTED
         *    FILESERVER_NO_MEMORY
         *
         * @param  aoSess the ASAM ODS session.
         * @param  name the name of the file.
         * @param  host the hostname for the socket connection.
         * @param  port the port for the socket connection.
         */
  public void getBySocket (org.asam.ods.AoSession aoSess, String name, String host, int aPort) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getBySocket", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (host);
                $out.write_long (aPort);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                getBySocket (aoSess, name, host, aPort        );
            } finally {
                _releaseReply ($in);
            }
  } // getBySocket


  /**
         * Get the data using a socket.
         *
         * @throws CORBAFileServerException
         * with the following possible error codes:
         *    FILESERVER_CONNECT_FAILED
         *    FILESERVER_BAD_PARAMETER
         *    FILESERVER_CONNECTION_LOST
         *    FILESERVER_IMPLEMENTATION_PROBLEM
         *    FILESERVER_NOT_IMPLEMENTED
         *    FILESERVER_NO_MEMORY
         *
         * @param  aoSess the ASAM ODS session.
         * @param  name the url specification of the file.
         * @param  aid the application element id.
         * @param  iid the instance element id.
         * @param  host the hostname for the socket connection.
         * @param  port the port for the socket connection.
         */
  public void getForInstanceBySocket (org.asam.ods.AoSession aoSess, String name, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid, String host, int aPort) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getForInstanceBySocket", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $out.write_string (host);
                $out.write_long (aPort);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                getForInstanceBySocket (aoSess, name, aid, iid, host, aPort        );
            } finally {
                _releaseReply ($in);
            }
  } // getForInstanceBySocket


  /**
         * Save the data using a socket.
         *
         * @throws CORBAFileServerException
         * with the following possible error codes:
         *    FILESERVER_CONNECT_FAILED
         *    FILESERVER_BAD_PARAMETER
         *    FILESERVER_CONNECTION_LOST
         *    FILESERVER_IMPLEMENTATION_PROBLEM
         *    FILESERVER_NOT_IMPLEMENTED
         *    FILESERVER_NO_MEMORY
         *
         * @param  aoSess the ASAM ODS session.
         * @param  name the name of the file.
         * @param  subDir an alternative sub directory, that can be specified,
         *                if the filename should not used to determine the destination folder.
         * @param  host the hostname for the socket connection.
         * @param  port the port for the socket connection.
         * @return the url string of the created file.
         */
  public String saveBySocket (org.asam.ods.AoSession aoSess, String name, String subDir, String host, int aPort) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("saveBySocket", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                $out.write_string (host);
                $out.write_long (aPort);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return saveBySocket (aoSess, name, subDir, host, aPort        );
            } finally {
                _releaseReply ($in);
            }
  } // saveBySocket


  /**
         * Save the data using a socket.
         *
         * @throws CORBAFileServerException
         * with the following possible error codes:
         *    FILESERVER_CONNECT_FAILED
         *    FILESERVER_BAD_PARAMETER
         *    FILESERVER_CONNECTION_LOST
         *    FILESERVER_IMPLEMENTATION_PROBLEM
         *    FILESERVER_NOT_IMPLEMENTED
         *    FILESERVER_NO_MEMORY
         *
         * @param  aoSess the ASAM ODS session.
         * @param  name the name of the file.
         * @param  subDir an alternative sub directory, that can be specified,
         *                if the filename should not used to determine the destination folder.
         * @param  aid the application element id.
         * @param  iid the instance element id.
         * @param  host the hostname for the socket connection.
         * @param  port the port for the socket connection.
         * @return the url string of the created file.
         */
  public String saveForInstanceBySocket (org.asam.ods.AoSession aoSess, String name, String subDir, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid, String host, int aPort) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("saveForInstanceBySocket", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $out.write_string (host);
                $out.write_long (aPort);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return saveForInstanceBySocket (aoSess, name, subDir, aid, iid, host, aPort        );
            } finally {
                _releaseReply ($in);
            }
  } // saveForInstanceBySocket


  /**
         * Save the data using a socket.
         *
         * @throws CORBAFileServerException
         * with the following possible error codes:
         *    FILESERVER_CONNECT_FAILED
         *    FILESERVER_BAD_PARAMETER
         *    FILESERVER_CONNECTION_LOST
         *    FILESERVER_IMPLEMENTATION_PROBLEM
         *    FILESERVER_NOT_IMPLEMENTED
         *    FILESERVER_NO_MEMORY
         *
         * @param  aoSess the ASAM ODS session.
         * @param  name the name of the file.
         * @param  subDir an alternative sub directory, that can be specified,
         *                if the filename should not used to determine the destination folder.
         * @param  aeName the application element name.
         * @param  ieName the instance element name.
         * @param  host the hostname for the socket connection.
         * @param  port the port for the socket connection.
         * @return the url string of the created file.
         */
  public String saveForInstanceNameBySocket (org.asam.ods.AoSession aoSess, String name, String subDir, String aeName, String ieName, String host, int aPort) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("saveForInstanceNameBySocket", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (subDir);
                $out.write_string (aeName);
                $out.write_string (ieName);
                $out.write_string (host);
                $out.write_long (aPort);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return saveForInstanceNameBySocket (aoSess, name, subDir, aeName, ieName, host, aPort        );
            } finally {
                _releaseReply ($in);
            }
  } // saveForInstanceNameBySocket


  /**
        * Read the data associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  stream the input stream, ready to read by the server.
        */
  public com.highqsoft.corbafileserver.generated.InputStreamIF read (org.asam.ods.AoSession aoSess, String name) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("read", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $in = _invoke ($out);
                com.highqsoft.corbafileserver.generated.InputStreamIF $result = com.highqsoft.corbafileserver.generated.InputStreamIFHelper.read ($in);
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return read (aoSess, name        );
            } finally {
                _releaseReply ($in);
            }
  } // read


  /**
        * Read the data associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        * @param  stream the input stream, ready to read by the server.
        */
  public com.highqsoft.corbafileserver.generated.InputStreamIF readForInstance (org.asam.ods.AoSession aoSess, String name, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("readForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $in = _invoke ($out);
                com.highqsoft.corbafileserver.generated.InputStreamIF $result = com.highqsoft.corbafileserver.generated.InputStreamIFHelper.read ($in);
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return readForInstance (aoSess, name, aid, iid        );
            } finally {
                _releaseReply ($in);
            }
  } // readForInstance


  /**
        *  Get size of the file associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  size the size of the input stream.
        */
  public long getSize (org.asam.ods.AoSession aoSess, String name) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getSize", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $in = _invoke ($out);
                long $result = $in.read_longlong ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getSize (aoSess, name        );
            } finally {
                _releaseReply ($in);
            }
  } // getSize


  /**
        *  Get size of the file associated with the given name.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        * @param  size the size of the input stream.
        */
  public long getSizeForInstance (org.asam.ods.AoSession aoSess, String name, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getSizeForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $in = _invoke ($out);
                long $result = $in.read_longlong ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getSizeForInstance (aoSess, name, aid, iid        );
            } finally {
                _releaseReply ($in);
            }
  } // getSizeForInstance


  /**
        * This method can be called by the client when the server should be start a termination process.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  parameter the parameter string. The content depends on the
        *         server side terminate implementation.
        */
  public void terminate (org.asam.ods.AoSession aoSess, String name, String parameter) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("terminate", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                $out.write_string (parameter);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                terminate (aoSess, name, parameter        );
            } finally {
                _releaseReply ($in);
            }
  } // terminate


  /**
        * This method can be called by the client when the server should be start a termination process.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECT_FAILED
        *    FILESERVER_BAD_PARAMETER
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @param  aoSess the ASAM ODS session.
        * @param  name the name of the file.
        * @param  aid the application element id.
        * @param  iid the instance element id.
        * @param  parameter the parameter string. The content depends on the
        *         server side terminate implementation.
        */
  public void terminateForInstance (org.asam.ods.AoSession aoSess, String name, org.asam.ods.T_LONGLONG aid, org.asam.ods.T_LONGLONG iid, String parameter) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("terminateForInstance", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (name);
                org.asam.ods.T_LONGLONGHelper.write ($out, aid);
                org.asam.ods.T_LONGLONGHelper.write ($out, iid);
                $out.write_string (parameter);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                terminateForInstance (aoSess, name, aid, iid, parameter        );
            } finally {
                _releaseReply ($in);
            }
  } // terminateForInstance


  /**
        * Get the name of the host where the server is running
        *
        * @param  aoSess the ASAM ODS session.
        * @return the hostname
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        */
  public String getHostname (org.asam.ods.AoSession aoSess) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getHostname", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getHostname (aoSess        );
            } finally {
                _releaseReply ($in);
            }
  } // getHostname


  /**
        * Get a context variable.
        *
        * @param  aoSess the ASAM ODS session.
        * @param key the keyword of the context value.
        * @return the context value
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY,
        *    FILESERVER_NOT_FOUND
        */
  public String getContext (org.asam.ods.AoSession aoSess, String key) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getContext", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (key);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getContext (aoSess, key        );
            } finally {
                _releaseReply ($in);
            }
  } // getContext


  /**
        * Set a context variable.
        *
        * @param  aoSess the ASAM ODS session.
        * @param key the keyword of the context value.
        * @param value the context value.
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        */
  public void setContext (org.asam.ods.AoSession aoSess, String key, String value) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("setContext", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (key);
                $out.write_string (value);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                setContext (aoSess, key, value        );
            } finally {
                _releaseReply ($in);
            }
  } // setContext


  /**
        * Remove a context variable.
        *
        * @param  aoSess the ASAM ODS session.
        * @param key the keyword of the context value.
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        */
  public void removeContext (org.asam.ods.AoSession aoSess, String key) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("removeContext", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $out.write_string (key);
                $in = _invoke ($out);
                return;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                removeContext (aoSess, key        );
            } finally {
                _releaseReply ($in);
            }
  } // removeContext


  /**
        * List all context keywords.
        *
        * @param  aoSess the ASAM ODS session.
        * @return a sequence of strings.
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        */
  public String[] listContext (org.asam.ods.AoSession aoSess) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("listContext", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                $in = _invoke ($out);
                String $result[] = com.highqsoft.corbafileserver.generated.DS_STRINGHelper.read ($in);
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return listContext (aoSess        );
            } finally {
                _releaseReply ($in);
            }
  } // listContext


  /**
        * Get the version of the CorbaFileServerIF.
        * Returns getVersion of CorbaFileServer.
        *
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        * @return  The interface version of the CorbaFileServerIF.
        *
        */
  public String getInterfaceVersion () throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getInterfaceVersion", true);
                $in = _invoke ($out);
                String $result = $in.read_string ();
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getInterfaceVersion (        );
            } finally {
                _releaseReply ($in);
            }
  } // getInterfaceVersion


  /**
        * Returns an array of long values representing the length
        * of the files that were provided in the String array.
        * The order of the long values must match with the order
        * of the filenames.
        *
        * @param aoSess the aoSession of the caller
        * @param names the String array of filenames for 
        *              which to get the sizes
        * @return an Array of long values containing the file sizes
        * @throws CORBAFileServerException
        * with the following possible error codes:
        *    FILESERVER_CONNECTION_LOST
        *    FILESERVER_IMPLEMENTATION_PROBLEM
        *    FILESERVER_NOT_IMPLEMENTED
        *    FILESERVER_NO_MEMORY
        *
        *
        */
  public long[] getSizes (org.asam.ods.AoSession aoSess, String[] names) throws com.highqsoft.corbafileserver.generated.CORBAFileServerException
  {
            org.omg.CORBA.portable.InputStream $in = null;
            try {
                org.omg.CORBA.portable.OutputStream $out = _request ("getSizes", true);
                org.asam.ods.AoSessionHelper.write ($out, aoSess);
                com.highqsoft.corbafileserver.generated.DS_STRINGHelper.write ($out, names);
                $in = _invoke ($out);
                long $result[] = com.highqsoft.corbafileserver.generated.LONG_ARRAYHelper.read ($in);
                return $result;
            } catch (org.omg.CORBA.portable.ApplicationException $ex) {
                $in = $ex.getInputStream ();
                String _id = $ex.getId ();
                if (_id.equals ("IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerException:1.0"))
                    throw com.highqsoft.corbafileserver.generated.CORBAFileServerExceptionHelper.read ($in);
                else
                    throw new org.omg.CORBA.MARSHAL (_id);
            } catch (org.omg.CORBA.portable.RemarshalException $rm) {
                return getSizes (aoSess, names        );
            } finally {
                _releaseReply ($in);
            }
  } // getSizes

  // Type-specific CORBA::Object operations
  private static String[] __ids = {
    "IDL:com/highqsoft/corbafileserver/generated/CORBAFileServerIF:1.0"};

  public String[] _ids ()
  {
    return (String[])__ids.clone ();
  }

  private void readObject (java.io.ObjectInputStream s) throws java.io.IOException
  {
     String str = s.readUTF ();
     String[] args = null;
     java.util.Properties props = null;
     org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props);
   try {
     org.omg.CORBA.Object obj = orb.string_to_object (str);
     org.omg.CORBA.portable.Delegate delegate = ((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
     _set_delegate (delegate);
   } finally {
     orb.destroy() ;
   }
  }

  private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException
  {
     String[] args = null;
     java.util.Properties props = null;
     org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init (args, props);
   try {
     String str = orb.object_to_string (this);
     s.writeUTF (str);
   } finally {
     orb.destroy() ;
   }
  }
} // class _CORBAFileServerIFStub
