/* gnuDelegate.java --
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.CORBA;

import gnu.CORBA.CDR.BufferredCdrInput;
import gnu.CORBA.GIOP.ReplyHeader;

import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NVList;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Request;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.PortableInterceptor.ForwardRequest;

import java.io.IOException;

/**
 * The Classpath implementation of the {@link Delegate} functionality in the
 * case, when the object was constructed from an IOR object. The IOR can be
 * constructed from the stringified object reference.
 *
 * There is an different instance of this delegate for each CORBA object.
 *
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 */
public class IorDelegate extends SimpleDelegate
{
  /**
   * Contructs an instance of object using the given IOR.
   */
  public IorDelegate(ORB an_orb, IOR an_ior)
  {
    super(an_orb, an_ior);
  }

  /**
   * Creates the request to invoke the method on this object.
   *
   * @param target the object, for that the operation must be invoked.
   * @param context context (null allowed)
   * @param operation the method name
   * @param parameters the method parameters
   * @param returns the return value holder
   *
   * @return the created request.
   */
  public Request create_request(org.omg.CORBA.Object target, Context context,
    String operation, NVList parameters, NamedValue returns
  )
  {
    gnuRequest request = getRequestInstance(target);

    request.setIor(getIor());
    request.set_target(target);

    request.setOperation(operation);
    request.set_args(parameters);
    request.m_context = context;
    request.set_result(returns);
    request.setORB(orb);

    return request;
  }

  /**
   * Creates the request to invoke the method on this object.
   *
   * @param target the object, for that the operation must be invoked.
   * @param context context (null allowed)
   * @param operation the method name
   * @param parameters the method parameters
   * @param returns the return value holder
   *
   * @return the created request.
   */
  public Request create_request(org.omg.CORBA.Object target, Context context,
    String operation, NVList parameters, NamedValue returns,
    ExceptionList exceptions, ContextList ctx_list
  )
  {
    gnuRequest request = getRequestInstance(target);

    request.setIor(ior);
    request.set_target(target);

    request.setOperation(operation);
    request.set_args(parameters);
    request.m_context = context;
    request.set_result(returns);
    request.set_exceptions(exceptions);
    request.set_context_list(ctx_list);
    request.setORB(orb);

    return request;
  }

  /**
   * Get the instance of request.
   */
  protected gnuRequest getRequestInstance(org.omg.CORBA.Object target)
  {
    return new gnuRequest();
  }

  /**
   * Invoke operation on the given object, als handling temproray and permanent
   * redirections. The ReplyHeader.LOCATION_FORWARD will cause to resend the
   * request to the new direction. The ReplyHeader.LOCATION_FORWARD_PERM will
   * cause additionally to remember the new location by this delegate, so
   * subsequent calls will be immediately delivered to the new target.
   *
   * @param target the target object.
   * @param output the output stream, previously returned by
   * {@link #request(org.omg.CORBA.Object, String, boolean)}.
   *
   * @return the input stream, to read the response from or null for a one-way
   * request.
   *
   * @throws SystemException if the SystemException has been thrown on the
   * remote side (the exact type and the minor code matches the data of the
   * remote exception that has been thrown).
   *
   * @throws org.omg.CORBA.portable.ApplicationException as specified.
   * @throws org.omg.CORBA.portable.RemarshalException as specified.
   */
  public InputStream invoke(org.omg.CORBA.Object target, OutputStream output)
    throws ApplicationException, RemarshalException
  {
    StreamBasedRequest request = (StreamBasedRequest) output;
    while (true)
      {
        try
          {
            if (request.response_expected)
              {
                RawReply response = request.request.submit();

                // Read reply header.
                ReplyHeader rh = response.header.create_reply_header();
                BufferredCdrInput input = response.getStream();
                input.setOrb(orb);
                rh.read(input);
                request.request.m_rph = rh;

                boolean moved_permanently = false;

                switch (rh.reply_status)
                  {
                    case ReplyHeader.NO_EXCEPTION:
                      if (request.request.m_interceptor != null)
                        request.request.m_interceptor.receive_reply(request.request.m_info);
                      if (response.header.version.since_inclusive(1, 2))
                        input.align(8);
                      return input;

                    case ReplyHeader.SYSTEM_EXCEPTION:
                      if (response.header.version.since_inclusive(1, 2))
                        input.align(8);
                      showException(request, input);

                      throw ObjectCreator.readSystemException(input,
                        rh.service_context);

                    case ReplyHeader.USER_EXCEPTION:
                      if (response.header.version.since_inclusive(1, 2))
                        input.align(8);
                      showException(request, input);

                      throw new ApplicationException(
                        request.request.m_exception_id, input);

                    case ReplyHeader.LOCATION_FORWARD_PERM:
                      moved_permanently = true;

                    case ReplyHeader.LOCATION_FORWARD:
                      if (response.header.version.since_inclusive(1, 2))
                        input.align(8);

                      IOR forwarded = new IOR();
                      try
                        {
                          forwarded._read_no_endian(input);
                        }
                      catch (IOException ex)
                        {
                          MARSHAL t = new MARSHAL("Cant read forwarding info",
                            5102, CompletionStatus.COMPLETED_NO);
                          t.initCause(ex);
                          throw t;
                        }

                      gnuRequest prev = request.request;
                      gnuRequest r = getRequestInstance(target);

                      r.m_interceptor = prev.m_interceptor;
                      r.m_slots = prev.m_slots;

                      r.m_args = prev.m_args;
                      r.m_context = prev.m_context;
                      r.m_context_list = prev.m_context_list;
                      r.m_environment = prev.m_environment;
                      r.m_exceptions = prev.m_exceptions;
                      r.m_operation = prev.m_operation;
                      r.m_parameter_buffer = prev.m_parameter_buffer;
                      r.m_parameter_buffer.request = r;
                      r.m_result = prev.m_result;
                      r.m_target = prev.m_target;
                      r.oneWay = prev.oneWay;
                      r.m_forward_ior = forwarded;

                      if (r.m_interceptor != null)
                        r.m_interceptor.receive_other(r.m_info);

                      r.setIor(forwarded);

                      IorObject it = new IorObject(orb,
                        forwarded);

                      r.m_target = it;

                      request.request = r;

                      IOR prev_ior = getIor();

                      setIor(forwarded);

                      try
                        {
                          return invoke(it, request);
                        }
                      finally
                        {
                          if (!moved_permanently)
                            setIor(prev_ior);
                        }

                    default:
                      throw new MARSHAL("Unknow reply status: "
                        + rh.reply_status, 8000 + rh.reply_status,
                        CompletionStatus.COMPLETED_NO);
                  }
              }
            else
              {
                request.request.send_oneway();
                return null;
              }
          }
        catch (ForwardRequest forwarded)
          {
            ForwardRequest fw = forwarded;
            Forwarding2: while (true)
              {
                try
                  {
                    gnuRequest prev = request.request;
                    gnuRequest r = getRequestInstance(target);

                    r.m_interceptor = prev.m_interceptor;
                    r.m_args = prev.m_args;
                    r.m_context = prev.m_context;
                    r.m_context_list = prev.m_context_list;
                    r.m_environment = prev.m_environment;
                    r.m_exceptions = prev.m_exceptions;
                    r.m_operation = prev.m_operation;
                    r.m_parameter_buffer = prev.m_parameter_buffer;
                    r.m_parameter_buffer.request = r;
                    r.m_result = prev.m_result;
                    r.m_target = prev.m_target;
                    r.oneWay = prev.oneWay;

                    r.m_forwarding_target = fw.forward;

                    if (r.m_interceptor != null)
                      r.m_interceptor.receive_other(r.m_info);

                    r.m_target = fw.forward;
                    request.request = r;
                    break Forwarding2;
                  }
                catch (ForwardRequest e)
                  {
                    forwarded = e;
                  }
              }
          }
      }
  }

  /**
   * Show exception to interceptor.
   */
  void showException(StreamBasedRequest request, BufferredCdrInput input)
    throws ForwardRequest
  {
    input.mark(2048);
    request.request.m_exception_id = input.read_string();
    input.reset();

    if (request.request.m_interceptor != null)
      request.request.m_interceptor.receive_exception(request.request.m_info);
  }

  /**
   * Create a request to invoke the method of this CORBA object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param operation the name of the method to invoke.
   *
   * @return the request.
   */
  public Request request(org.omg.CORBA.Object target, String operation)
  {
    gnuRequest request = getRequestInstance(target);

    request.setIor(ior);
    request.set_target(target);

    request.setOperation(operation);
    request.setORB(orb);

    return request;
  }

  /**
   * Create a request to invoke the method of this CORBA object.
   *
   * @param target the CORBA object, to that this operation must be applied.
   * @param operation the name of the method to invoke.
   * @param response_expected specifies if this is one way message or the
   * response to the message is expected.
   *
   * @return the stream where the method arguments should be written.
   */
  public OutputStream request(org.omg.CORBA.Object target, String operation,
    boolean response_expected
  )
  {
    gnuRequest request = getRequestInstance(target);

    request.setIor(ior);
    request.set_target(target);
    request.setOperation(operation);

    StreamBasedRequest out = request.getParameterStream();
    out.response_expected = response_expected;
    request.setORB(orb);
    out.setOrb(orb);

    return out;
  }

  /**
   * If there is an opened cache socket to access this object, close that
   * socket.
   *
   * @param target The target is not used, this delegate requires a single
   * instance per object.
   */
  public void release(org.omg.CORBA.Object target)
  {
    // Do nothing here.
  }

  /**
   * Reset the remote_ior flag, forcing to check if the object is local on the
   * next getRequestInstance call.
   */
  public void setIor(IOR an_ior)
  {
    super.setIor(an_ior);
  }

  /**
   * Checks if the ior is local so far it is easy.
   */
  public boolean is_local(org.omg.CORBA.Object self)
  {
    return false;
  }
}
