OSDN Git Service

Imported Classpath 0.18.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / CORBA / IOR_Delegate.java
index b06f630..3b64eb5 100644 (file)
@@ -40,7 +40,9 @@ package gnu.CORBA;
 
 import gnu.CORBA.CDR.cdrBufInput;
 import gnu.CORBA.GIOP.ReplyHeader;
+import gnu.CORBA.Poa.activeObjectMap;
 
+import org.omg.CORBA.CompletionStatus;
 import org.omg.CORBA.Context;
 import org.omg.CORBA.ContextList;
 import org.omg.CORBA.ExceptionList;
@@ -53,6 +55,7 @@ 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;
 
@@ -67,10 +70,20 @@ import java.net.Socket;
  *
  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
  */
-public class IOR_Delegate
-  extends Simple_delegate
+public class IOR_Delegate extends Simple_delegate
 {
   /**
+   * True if the current IOR does not map into the local servant. If false, the
+   * IOR is either local or should be checked.
+   */
+  boolean remote_ior;
+
+  /**
+   * If not null, this field contains data about the local servant.
+   */
+  activeObjectMap.Obj local_ior;
+
+  /**
    * Contructs an instance of object using the given IOR.
    */
   public IOR_Delegate(ORB an_orb, IOR an_ior)
@@ -92,11 +105,10 @@ public class IOR_Delegate
    * @return the created request.
    */
   public Request create_request(org.omg.CORBA.Object target, Context context,
-                                String operation, NVList parameters,
-                                NamedValue returns
-                               )
+    String operation, NVList parameters, NamedValue returns
+  )
   {
-    gnuRequest request = new gnuRequest();
+    gnuRequest request = getRequestInstance(target);
 
     request.setIor(getIor());
     request.set_target(target);
@@ -122,12 +134,11 @@ public class IOR_Delegate
    * @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
-                               )
+    String operation, NVList parameters, NamedValue returns,
+    ExceptionList exceptions, ContextList ctx_list
+  )
   {
-    gnuRequest request = new gnuRequest();
+    gnuRequest request = getRequestInstance(target);
 
     request.setIor(ior);
     request.set_target(target);
@@ -144,100 +155,219 @@ public class IOR_Delegate
   }
 
   /**
-   * Invoke operation on the given object, writing parameters to the given
-   * output stream.
+   * 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.
+   * @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).
+   * 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
+    throws ApplicationException, RemarshalException
   {
     streamRequest request = (streamRequest) output;
-    if (request.response_expected)
+    Forwardings:
+    while (true)
       {
-        binaryReply response = request.request.submit();
-
-        // Read reply header.
-        ReplyHeader rh = response.header.create_reply_header();
-        cdrBufInput input = response.getStream();
-        input.setOrb(orb);
-        rh.read(input);
-
-        boolean moved_permanently = false;
-
-        switch (rh.reply_status)
+        try
           {
-            case ReplyHeader.NO_EXCEPTION :
-              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);
-              throw ObjectCreator.readSystemException(input);
-
-            case ReplyHeader.USER_EXCEPTION :
-              if (response.header.version.since_inclusive(1, 2))
-                input.align(8);
-              input.mark(2000);
-
-              String uxId = input.read_string();
-              input.reset();
-
-              throw new ApplicationException(uxId, 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");
-                  t.initCause(ex);
-                  throw t;
-                }
-
-              request.request.setIor(forwarded);
-
-              // If the object has moved permanently, its IOR is replaced.
-              if (moved_permanently)
-                setIor(forwarded);
-
-              return invoke(target, request);
-
-            default :
-              throw new MARSHAL("Unknow reply status: " + rh.reply_status);
+            if (request.response_expected)
+              {
+                binaryReply response = request.request.submit();
+
+                // Read reply header.
+                ReplyHeader rh = response.header.create_reply_header();
+                cdrBufInput 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);
+
+                    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);
+
+                      IOR_contructed_object it =
+                        new IOR_contructed_object(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;
+                  }
+              }
           }
-      }
-    else
-      {
-        request.request.send_oneway();
-        return null;
       }
   }
 
   /**
+   * Show exception to interceptor.
+   */
+  void showException(streamRequest request, cdrBufInput 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.
@@ -247,7 +377,7 @@ public class IOR_Delegate
    */
   public Request request(org.omg.CORBA.Object target, String operation)
   {
-    gnuRequest request = new gnuRequest();
+    gnuRequest request = getRequestInstance(target);
 
     request.setIor(ior);
     request.set_target(target);
@@ -269,27 +399,28 @@ public class IOR_Delegate
    * @return the stream where the method arguments should be written.
    */
   public OutputStream request(org.omg.CORBA.Object target, String operation,
-                              boolean response_expected
-                             )
+    boolean response_expected
+  )
   {
-    gnuRequest request = new gnuRequest();
+    gnuRequest request = getRequestInstance(target);
 
     request.setIor(ior);
     request.set_target(target);
     request.setOperation(operation);
 
-    request.getParameterStream().response_expected = response_expected;
+    streamRequest out = request.getParameterStream();
+    out.response_expected = response_expected;
     request.setORB(orb);
 
-    return request.getParameterStream();
+    return out;
   }
 
   /**
-   * If there is an opened cache socket to access this object, close
-   * that socket.
+   * 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.
+   * @param target The target is not used, this delegate requires a single
+   * instance per object.
    */
   public void release(org.omg.CORBA.Object target)
   {
@@ -308,4 +439,28 @@ public class IOR_Delegate
         // do nothing, then.
       }
   }
+
+  /**
+   * 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);
+    remote_ior = false;
+    local_ior = null;
+  }
+
+  /**
+   * Checks if the ior is local so far it is easy.
+   */
+  public boolean is_local(org.omg.CORBA.Object self)
+  {
+    if (remote_ior)
+      return false;
+    else if (local_ior != null)
+      return true;
+    else
+      return super.is_local(self);
+  }
 }
\ No newline at end of file