libjava/
[official-gcc.git] / libjava / classpath / gnu / CORBA / gnuRequest.java
blob3ec2a797f0f1610120114156124182445e91551c
1 /* gnuRequest.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu.CORBA;
41 import gnu.CORBA.CDR.BufferredCdrInput;
42 import gnu.CORBA.CDR.BufferedCdrOutput;
43 import gnu.CORBA.GIOP.MessageHeader;
44 import gnu.CORBA.GIOP.ReplyHeader;
45 import gnu.CORBA.GIOP.RequestHeader;
46 import gnu.CORBA.GIOP.CodeSetServiceContext;
47 import gnu.CORBA.Interceptor.gnuClientRequestInfo;
48 import gnu.CORBA.Poa.ORB_1_4;
50 import org.omg.CORBA.ARG_IN;
51 import org.omg.CORBA.ARG_INOUT;
52 import org.omg.CORBA.ARG_OUT;
53 import org.omg.CORBA.Any;
54 import org.omg.CORBA.BAD_INV_ORDER;
55 import org.omg.CORBA.BAD_PARAM;
56 import org.omg.CORBA.Bounds;
57 import org.omg.CORBA.COMM_FAILURE;
58 import org.omg.CORBA.CompletionStatus;
59 import org.omg.CORBA.Context;
60 import org.omg.CORBA.ContextList;
61 import org.omg.CORBA.Environment;
62 import org.omg.CORBA.ExceptionList;
63 import org.omg.CORBA.INV_POLICY;
64 import org.omg.CORBA.MARSHAL;
65 import org.omg.CORBA.NO_IMPLEMENT;
66 import org.omg.CORBA.NO_RESOURCES;
67 import org.omg.CORBA.NVList;
68 import org.omg.CORBA.NamedValue;
69 import org.omg.CORBA.ORB;
70 import org.omg.CORBA.Policy;
71 import org.omg.CORBA.Request;
72 import org.omg.CORBA.SystemException;
73 import org.omg.CORBA.TypeCode;
74 import org.omg.CORBA.UnknownUserException;
75 import org.omg.CORBA.portable.ObjectImpl;
76 import org.omg.IOP.ServiceContext;
77 import org.omg.IOP.TAG_CODE_SETS;
78 import org.omg.IOP.TAG_INTERNET_IOP;
79 import org.omg.IOP.TaggedComponent;
80 import org.omg.IOP.TaggedProfile;
81 import org.omg.PortableInterceptor.ClientRequestInfo;
82 import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
83 import org.omg.PortableInterceptor.ForwardRequest;
84 import org.omg.PortableInterceptor.InvalidSlot;
86 import java.io.IOException;
87 import java.io.InputStream;
88 import java.io.OutputStream;
90 import java.net.Socket;
92 import java.util.ArrayList;
94 /**
95 * The implementation of the CORBA request.
97 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
99 public class gnuRequest extends Request implements Cloneable
102 * The maximal supported GIOP version.
104 public static Version MAX_SUPPORTED = new Version(1, 2);
107 * The initial pause that the Request makes when the required port is not
108 * available.
110 public static int PAUSE_INITIAL = 50;
113 * The number of repretetive attempts to get a required port, if it is not
114 * immediately available.
116 public static int PAUSE_STEPS = 12;
119 * The maximal pausing interval between two repetetive attempts. The interval
120 * doubles after each unsuccessful attempt, but will not exceed this value.
122 public static int PAUSE_MAX = 1000;
125 * The interceptor, listening the major request submission points.
127 ClientRequestInterceptorOperations m_interceptor;
130 * The request info, used by interceptor.
132 ClientRequestInfo m_info = new gnuClientRequestInfo(this);
135 * The empty byte array.
137 private static final RawReply EMPTY =
138 new RawReply(null, new MessageHeader(), new byte[ 0 ]);
141 * The context holder for methods ctx(Context) and ctx().
143 protected Context m_context;
146 * The context list for method contexts().
148 protected ContextList m_context_list;
151 * The request environment for holding the exception the has possibly been
152 * thrown by the method being invoked.
154 protected Environment m_environment = new gnuEnvironment();
157 * The list of all exceptions that can be thrown by the method being invoked.
159 protected ExceptionList m_exceptions = new gnuExceptionList();
162 * The result, returned by the invoked method (function).
164 protected NamedValue m_result = new gnuNamedValue();
167 * The exception id, received from the server, null if none.
169 protected String m_exception_id;
172 * The thrown system exception.
174 protected SystemException m_sys_ex;
177 * The invocation target.
179 protected org.omg.CORBA.Object m_target;
182 * The name of the method being invoked.
184 protected String m_operation;
187 * This field temporary remembers the value of the forwarded ior reference. If
188 * it is not null, the request was forwarded and the effective target is not
189 * the same as the default target.
191 public IOR m_forward_ior;
194 * Is set when object, and not IOR is directly available.
196 public org.omg.CORBA.Object m_forwarding_target;
199 * The flag, indicating that the request has been sent and the result is
200 * already received.
202 protected boolean complete;
205 * The flag, indicating that the response to this request must be ignored
206 * (used with {@link #send_oneway()}).
208 protected boolean oneWay;
211 * The flag, indicating that the request has been sent and no result is yet
212 * received.
214 protected boolean running;
217 * The request arguments.
219 protected gnuNVList m_args = new gnuNVList();
222 * The request arguments in the case when they are directly written into the
223 * parameter buffer.
225 protected StreamBasedRequest m_parameter_buffer;
228 * The array of slots.
230 protected Any[] m_slots;
233 * The request header currently in use.
235 protected RequestHeader m_rqh;
238 * The reply header currently in use.
240 protected ReplyHeader m_rph;
243 * The IOR of the target.
245 private IOR ior;
248 * The ORB of the target.
250 private ORB orb;
253 * The encoding, used to send the message.
255 * The default encoding is inherited from the set IOR (that string reference
256 * can be encoded in either Big or Little endian). If the IOR encoding is not
257 * known (for example, by obtaining the reference from the naming service),
258 * the Big Endian is used.
260 private boolean Big_endian = true;
263 * Set the IOR data, sufficient to find the invocation target. This also sets
264 * default endian encoding for invocations.
266 * @see IOR.parse(String)
268 public void setIor(IOR an_ior)
270 ior = an_ior;
271 setBigEndian(ior.Big_Endian);
275 * Used when redirecting request to another target.
277 gnuRequest redirected;
280 * Get the IOR data, sufficient to find the invocation target.
282 * @return the IOR data.
284 public IOR getIor()
286 return ior;
290 * Set the ORB, related to the invocation target.
292 public void setORB(ORB an_orb)
294 orb = an_orb;
296 // Take the interceptor from the ORB.
297 if (orb instanceof OrbRestricted)
298 m_interceptor = ((OrbRestricted) orb).iClient;
300 if (m_interceptor != null && orb instanceof ORB_1_4)
302 m_slots = ((ORB_1_4) orb).ic_current.clone_slots();
307 * Set the encoding that will be used to send the message. The default
308 * encoding is inherited from the set IOR (that string reference can be
309 * encoded in either Big or Little endian). If the IOR encoding is not known
310 * (for example, by obtaining the reference from the naming service), the Big
311 * Endian is used.
313 * @param use_big_endian true to use the Big Endian, false to use the Little
314 * Endian encoding.
316 public void setBigEndian(boolean use_big_endian)
318 Big_endian = use_big_endian;
322 * The the method name to invoke.
324 * @param operation the method name.
326 public void setOperation(String operation)
328 m_operation = operation;
332 * Get the parameter stream, where the invocation arguments should be written
333 * if they are written into the stream directly.
335 public StreamBasedRequest getParameterStream()
337 m_parameter_buffer = new StreamBasedRequest();
338 m_parameter_buffer.request = this;
339 m_parameter_buffer.setVersion(ior.Internet.version);
340 m_parameter_buffer.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
341 m_parameter_buffer.setOrb(orb);
342 m_parameter_buffer.setBigEndian(Big_endian);
344 // For the old iiop versions, it is important to set the size
345 // correctly.
346 if (ior.Internet.version.until_inclusive(1, 1))
348 BufferedCdrOutput measure = new BufferedCdrOutput();
349 measure.setOffset(12);
350 if (m_rqh == null)
351 m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader();
352 m_rqh.operation = m_operation;
353 m_rqh.object_key = ior.key;
354 m_rqh.write(measure);
355 m_parameter_buffer.setOffset(12 + measure.buffer.size());
358 return m_parameter_buffer;
362 * Creates a shallow copy of this request.
364 public gnuRequest Clone()
368 return (gnuRequest) clone();
370 catch (CloneNotSupportedException ex)
372 throw new Unexpected(ex);
376 /** {@inheritDoc} */
377 public Any add_in_arg()
379 gnuNamedValue v = new gnuNamedValue();
380 v.setFlags(ARG_IN.value);
381 m_args.add(v);
382 return v.value();
385 /** {@inheritDoc} */
386 public Any add_inout_arg()
388 gnuNamedValue v = new gnuNamedValue();
389 v.setFlags(ARG_INOUT.value);
390 m_args.add(v);
391 return v.value();
394 /** {@inheritDoc} */
395 public Any add_named_in_arg(String name)
397 gnuNamedValue v = new gnuNamedValue();
398 v.setFlags(ARG_IN.value);
399 v.setName(name);
400 m_args.add(v);
401 return v.value();
404 /** {@inheritDoc} */
405 public Any add_named_inout_arg(String name)
407 gnuNamedValue v = new gnuNamedValue();
408 v.setFlags(ARG_INOUT.value);
409 v.setName(name);
410 m_args.add(v);
411 return v.value();
414 /** {@inheritDoc} */
415 public Any add_named_out_arg(String name)
417 gnuNamedValue v = new gnuNamedValue();
418 v.setFlags(ARG_OUT.value);
419 v.setName(name);
420 m_args.add(v);
421 return v.value();
424 /** {@inheritDoc} */
425 public Any add_out_arg()
427 gnuNamedValue v = new gnuNamedValue();
428 v.setFlags(ARG_OUT.value);
429 m_args.add(v);
430 return v.value();
433 /** {@inheritDoc} */
434 public NVList arguments()
436 return m_args;
439 /** {@inheritDoc} */
440 public ContextList contexts()
442 return m_context_list;
445 /** {@inheritDoc} */
446 public Context ctx()
448 return m_context;
451 /** {@inheritDoc} */
452 public void ctx(Context a_context)
454 m_context = a_context;
457 /** {@inheritDoc} */
458 public Environment env()
460 return m_environment;
463 /** {@inheritDoc} */
464 public ExceptionList exceptions()
466 return m_exceptions;
469 /** {@inheritDoc} */
470 public void get_response() throws org.omg.CORBA.WrongTransaction
473 * The response is ready after it is received. FIXME implement context
474 * checks and any other functionality, if required.
479 * Submit the request, suspending the current thread until the answer is
480 * received.
482 * This implementation requires to set the IOR property ({@link #setIOR(IOR)}
483 * before calling this method.
485 * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously
486 * set.
488 * @throws SystemException if this exception has been thrown on remote side.
489 * The exact exception type and the minor code are the same as they have been
490 * for the exception, thrown on remoted side.
492 public synchronized void invoke() throws BAD_INV_ORDER
494 waitWhileBusy();
495 complete = false;
496 running = true;
498 if (ior == null)
499 throw new BAD_INV_ORDER("Set IOR property first");
503 Forwardings:
504 while (true)
508 p_invoke();
509 break Forwardings;
511 catch (ForwardRequest e)
515 ObjectImpl impl = (ObjectImpl) e.forward;
516 SimpleDelegate delegate =
517 (SimpleDelegate) impl._get_delegate();
518 ior = delegate.getIor();
520 catch (Exception ex)
522 BAD_PARAM bad =
523 new BAD_PARAM("Unsupported forwarding target");
524 bad.initCause(ex);
525 throw bad;
530 finally
532 running = false;
533 complete = true;
537 /** {@inheritDoc} */
538 public String operation()
540 return m_operation;
544 * Get the orb, related to the invocation target.
546 public ORB orb()
548 return orb;
551 /** {@inheritDoc} */
552 public boolean poll_response()
554 return complete && !running;
557 /** {@inheritDoc} */
558 public NamedValue result()
560 return m_result;
564 * {@inheritDoc}
567 public Any return_value()
569 return m_result.value();
572 /** {@inheritDoc} */
573 public synchronized void send_deferred()
575 waitWhileBusy();
576 new Thread()
578 public void run()
580 invoke();
582 }.start();
586 * Send a request and forget about it, not waiting for a response. This can be
587 * done also for methods that normally are expected to return some values.
589 * TODO It is generally recommended to reuse the threads. Reuse?
591 public void send_oneway()
593 final gnuRequest cloned = Clone();
594 cloned.oneWay = true;
596 new Thread()
598 public void run()
600 cloned.invoke();
602 }.start();
606 * Set the argument list. This field is initialised as empty non null instance
607 * by default, so the method is only used in cases when the direct replacement
608 * is desired.
610 * @param a_args the argument list.
612 public void set_args(NVList a_args)
614 if (a_args instanceof gnuNVList)
615 m_args = (gnuNVList) a_args;
616 else
620 // In case if this is another implementation of the NVList.
621 m_args.list.clear();
622 for (int i = 0; i < a_args.count(); i++)
624 m_args.add(a_args.item(i));
627 catch (Bounds ex)
629 Unexpected.error(ex);
635 * Set the context list that is later returned by the method
636 * {@link #contexts()}.
638 * @param a_context_list a new context list.
640 public void set_context_list(ContextList a_context_list)
642 m_context_list = a_context_list;
646 * Set the exception container. This field is initialised as empty non null
647 * instance by default, so the method is only used in cases when the direct
648 * replacement is desired.
650 * @param a_environment the new exception container.
652 public void set_environment(Environment a_environment)
654 m_environment = a_environment;
658 * Set the list of exceptions. This field is initialised as empty non null
659 * instance by default, so the method is only used in cases when the direct
660 * replacement is desired.
662 * @param a_exceptions a list of exceptions.
664 public void set_exceptions(ExceptionList a_exceptions)
666 m_exceptions = a_exceptions;
670 * Set the operation name.
672 * @param a_operation the operation name.
674 public void set_operation(String a_operation)
676 m_operation = a_operation;
680 * Set the named value, returned as result. This field is initialised as empty
681 * non null instance by default, so the method is only used in cases when the
682 * direct replacement is desired.
684 * @param a_result the result keeper.
686 public void set_result(NamedValue a_result)
688 m_result = a_result;
692 * Set the type of the named value, returned as a result. Instantiates a new
693 * instance of the result value.
695 public void set_return_type(TypeCode returns)
697 if (m_result == null || !returns.equal(m_result.value().type()))
699 m_result = new gnuNamedValue();
700 m_result.value().type(returns);
705 * Set the invocation target.
707 * @param a_target the CORBA object for that the method will be invoked.
709 public void set_target(org.omg.CORBA.Object a_target)
711 m_target = a_target;
715 * Do the actual invocation. This implementation requires to set the IOR
716 * property ({@link #setIOR(IOR)} before calling this method.
718 * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set
719 * or if the direct argument addition is mixed with the direct
720 * argument writing into the output stream.
721 * @return the server response in binary form.
723 public synchronized RawReply submit()
724 throws ForwardRequest
726 gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader();
728 header.setBigEndian(Big_endian);
730 // The byte order will be Big Endian by default.
731 header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST;
732 header.version = useVersion(ior.Internet.version);
734 RequestHeader rh = header.create_request_header();
735 rh.operation = m_operation;
736 rh.object_key = ior.key;
738 // Update interceptor.
739 m_rqh = rh;
741 if (m_interceptor != null)
742 m_interceptor.send_request(m_info);
744 // Prepare the submission.
745 BufferedCdrOutput request_part = new BufferedCdrOutput();
747 request_part.setOffset(header.getHeaderSize());
748 request_part.setVersion(header.version);
749 request_part.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
750 request_part.setOrb(orb);
751 request_part.setBigEndian(header.isBigEndian());
753 // This also sets the stream encoding to the encoding, specified
754 // in the header.
755 rh.write(request_part);
757 if (m_args != null && m_args.count() > 0)
759 write_parameters(header, request_part);
761 if (m_parameter_buffer != null)
762 throw new BAD_INV_ORDER("Please either add parameters or "
763 + "write them into stream, but not both " + "at once.");
766 if (m_parameter_buffer != null)
768 write_parameter_buffer(header, request_part);
771 // Now the message size is available.
772 header.message_size = request_part.buffer.size();
774 Socket socket = null;
776 java.lang.Object key = ior.Internet.host + ":" + ior.Internet.port;
778 synchronized (SocketRepository.class)
780 socket = SocketRepository.get_socket(key);
785 long pause = PAUSE_INITIAL;
787 if (socket == null)
789 // The IOException may be thrown under very heavy parallel
790 // load. For some time, just wait, exceptiong the socket to free.
791 Open: for (int i = 0; i < PAUSE_STEPS; i++)
795 if (orb instanceof OrbFunctional)
796 socket = ((OrbFunctional) orb).socketFactory.
797 createClientSocket(
798 ior.Internet.host, ior.Internet.port);
799 else
800 socket = new Socket(ior.Internet.host, ior.Internet.port);
801 break Open;
803 catch (IOException ex)
807 // Expecting to free a socket via finaliser.
808 System.gc();
809 Thread.sleep(pause);
810 pause = pause * 2;
811 if (pause > PAUSE_MAX)
812 pause = PAUSE_MAX;
814 catch (InterruptedException iex)
821 if (socket == null)
822 throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port
823 + " in use");
824 socket.setKeepAlive(true);
826 OutputStream socketOutput = socket.getOutputStream();
828 // Write the message header.
829 header.write(socketOutput);
831 // Write the request header and parameters (if present).
832 request_part.buffer.writeTo(socketOutput);
834 socketOutput.flush();
835 if (!socket.isClosed() && !oneWay)
837 MessageHeader response_header = new MessageHeader();
838 InputStream socketInput = socket.getInputStream();
839 response_header.read(socketInput);
841 byte[] r;
842 if (orb instanceof OrbFunctional)
844 OrbFunctional fo = (OrbFunctional) orb;
845 r = response_header.readMessage(socketInput, socket,
846 fo.TOUT_WHILE_READING, fo.TOUT_AFTER_RECEIVING);
848 else
849 r = response_header.readMessage(socketInput, null, 0, 0);
851 return new RawReply(orb, response_header, r);
853 else
854 return EMPTY;
856 catch (IOException io_ex)
858 COMM_FAILURE m = new COMM_FAILURE("Unable to open a socket at "
859 + ior.Internet.host + ":" + ior.Internet.port, 0xC9,
860 CompletionStatus.COMPLETED_NO);
861 m.initCause(io_ex);
862 throw m;
864 finally
868 if (socket != null && !socket.isClosed())
870 socket.setSoTimeout(OrbFunctional.TANDEM_REQUESTS);
871 SocketRepository.put_socket(key, socket);
874 catch (IOException scx)
876 InternalError ierr = new InternalError();
877 ierr.initCause(scx);
878 throw ierr;
883 /** {@inheritDoc} */
884 public org.omg.CORBA.Object target()
886 return m_target;
890 * Get the used version. Normally, it is better to respond using the same
891 * version as it is specified in IOR, but not above the maximal supported
892 * version.
894 public Version useVersion(Version desired)
896 if (desired.until_inclusive(MAX_SUPPORTED.major, MAX_SUPPORTED.minor))
897 return desired;
898 else
899 return MAX_SUPPORTED;
903 * Wait while the response to request, submitted using
904 * {@link #send_deferred()} or {@link #invoke()} (from other thread) is
905 * returned.
907 * FIXME It is possible to rewrite this using Object.wait() and
908 * Object.notify(), but be sure to prepare the test as well.
910 public synchronized void waitWhileBusy()
912 // Waiting constants.
913 long wait = 10;
914 long increment = 2;
915 long max = 5000;
917 while (running)
921 Thread.sleep(wait);
922 if (wait < max)
923 wait = wait * increment;
925 catch (InterruptedException ex)
932 * Do actual invocation. This method recursively calls itself if the
933 * redirection is detected.
935 private void p_invoke()
936 throws SystemException, ForwardRequest
938 RawReply response = submit();
940 // If this is a one way message, do not care about the response.
941 if (oneWay && response == EMPTY)
942 return;
944 if (m_rph == null)
945 m_rph = response.header.create_reply_header();
947 BufferredCdrInput input = response.getStream();
948 input.setOrb(orb);
950 m_rph.read(input);
952 // The stream must be aligned sinve v1.2, but only once.
953 boolean align = response.header.version.since_inclusive(1, 2);
955 switch (m_rph.reply_status)
957 case ReplyHeader.NO_EXCEPTION:
959 NamedValue arg;
961 // Read return value, if set.
962 if (m_result != null)
964 if (align)
966 input.align(8);
967 align = false;
969 m_result.value().read_value(input, m_result.value().type());
972 // Read returned parameters, if set.
973 if (m_args != null)
974 for (int i = 0; i < m_args.count(); i++)
978 arg = m_args.item(i);
980 // Both ARG_INOUT and ARG_OUT have this binary flag set.
981 if ((arg.flags() & ARG_OUT.value) != 0)
983 if (align)
985 input.align(8);
986 align = false;
989 arg.value().read_value(input, arg.value().type());
992 catch (Bounds ex)
994 Unexpected.error(ex);
998 if (m_interceptor != null)
999 m_interceptor.receive_reply(m_info);
1001 break;
1003 case ReplyHeader.SYSTEM_EXCEPTION:
1004 if (align)
1006 input.align(8);
1007 align = false;
1009 readExceptionId(input);
1011 m_sys_ex = ObjectCreator.readSystemException(input,
1012 m_rph.service_context);
1013 m_environment.exception(m_sys_ex);
1015 if (m_interceptor != null)
1016 m_interceptor.receive_exception(m_info);
1018 throw m_sys_ex;
1020 case ReplyHeader.USER_EXCEPTION:
1021 if (align)
1023 input.align(8);
1024 align = false;
1026 readExceptionId(input);
1028 // Prepare an Any that will hold the exception.
1029 gnuAny exc = new gnuAny();
1030 exc.setOrb(orb);
1032 exc.insert_Streamable(new StreamHolder(input));
1034 UnknownUserException unuex = new UnknownUserException(exc);
1035 m_environment.exception(unuex);
1037 if (m_interceptor != null)
1038 m_interceptor.receive_exception(m_info);
1040 break;
1042 case ReplyHeader.LOCATION_FORWARD_PERM:
1043 case ReplyHeader.LOCATION_FORWARD:
1044 if (response.header.version.since_inclusive(1, 2))
1045 input.align(8);
1047 IOR forwarded = new IOR();
1050 forwarded._read_no_endian(input);
1052 catch (IOException ex)
1054 new MARSHAL("Cant read forwarding info", 5103,
1055 CompletionStatus.COMPLETED_NO);
1058 setIor(forwarded);
1060 m_forward_ior = forwarded;
1062 if (m_interceptor != null)
1063 m_interceptor.receive_other(m_info);
1065 // Repeat with the forwarded information.
1066 p_invoke();
1067 return;
1069 default:
1070 throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status,
1071 CompletionStatus.COMPLETED_NO);
1076 * Read exception id without changing the stream pointer position.
1078 void readExceptionId(BufferredCdrInput input)
1080 input.mark(2048);
1081 m_exception_id = input.read_string();
1082 input.reset();
1086 * Write the operation parameters.
1088 * @param header the message header
1089 * @param request_part the stream to write parameters into
1091 * @throws MARSHAL if the attempt to write the parameters has failde.
1093 protected void write_parameter_buffer(MessageHeader header,
1094 BufferedCdrOutput request_part
1095 ) throws MARSHAL
1099 if (header.version.since_inclusive(1, 2))
1101 request_part.align(8);
1103 m_parameter_buffer.buffer.writeTo(request_part);
1105 catch (IOException ex)
1107 MARSHAL m = new MARSHAL("Unable to write method arguments to CDR output.");
1108 m.minor = Minor.CDR;
1109 throw m;
1114 * Write the operation parameters.
1116 * @param header the message header
1117 * @param request_part the stream to write parameters into
1119 * @throws MARSHAL if the attempt to write the parameters has failde.
1121 protected void write_parameters(MessageHeader header,
1122 BufferedCdrOutput request_part
1123 ) throws MARSHAL
1125 // Align after 1.2, but only once.
1126 boolean align = header.version.since_inclusive(1, 2);
1127 NamedValue para;
1131 // Write parameters now.
1132 for (int i = 0; i < m_args.count(); i++)
1134 para = m_args.item(i);
1136 // This bit is set both for ARG_IN and ARG_INOUT
1137 if ((para.flags() & ARG_IN.value) != 0)
1139 if (align)
1141 request_part.align(8);
1142 align = false;
1144 para.value().write_value(request_part);
1148 catch (Bounds ex)
1150 InternalError ierr = new InternalError();
1151 ierr.initCause(ex);
1152 throw ierr;
1156 /* **************Implementation of the request info operations. ***** */
1159 * Add context to request.
1161 public void add_request_service_context(ServiceContext service_context,
1162 boolean replace
1165 m_rqh.addContext(service_context, replace);
1169 * Get the Internet profile as an effective profile.
1171 public TaggedProfile effective_profile()
1173 BufferedCdrOutput buf = new BufferedCdrOutput(512);
1174 buf.setOrb(orb);
1175 ior.Internet.write(buf);
1177 TaggedProfile p = new TaggedProfile();
1178 p.tag = TAG_INTERNET_IOP.value;
1179 p.profile_data = buf.buffer.toByteArray();
1180 return p;
1184 * Return either target or forwarded targed.
1186 public org.omg.CORBA.Object effective_target()
1188 return new IorObject(orb, ior);
1192 * Get effective component with the give id from the Internet profile.
1194 public TaggedComponent get_effective_component(int id)
1195 throws BAD_PARAM
1197 if (id == TAG_CODE_SETS.value)
1199 // Codesets are encoded separately.
1200 BufferedCdrOutput buf = new BufferedCdrOutput(512);
1201 buf.setOrb(orb);
1202 ior.Internet.CodeSets.write(buf);
1204 TaggedComponent t = new TaggedComponent();
1205 t.tag = TAG_CODE_SETS.value;
1206 t.component_data = buf.buffer.toByteArray();
1207 return t;
1209 else
1211 for (int i = 0; i < ior.Internet.components.size(); i++)
1213 TaggedComponent c =
1214 (TaggedComponent) ior.Internet.components.get(i);
1215 if (c.tag == id)
1216 return c;
1219 throw new BAD_PARAM("No component " + id + " in the Internet profile", 28,
1220 CompletionStatus.COMPLETED_MAYBE
1225 * Get all components with the given id from the internet profile.
1227 public TaggedComponent[] get_effective_components(int id)
1228 throws BAD_PARAM
1230 if (id == TAG_CODE_SETS.value)
1231 return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) };
1232 else
1234 ArrayList components = new ArrayList(ior.Internet.components.size());
1235 for (int i = 0; i < ior.Internet.components.size(); i++)
1237 TaggedComponent c =
1238 (TaggedComponent) ior.Internet.components.get(i);
1239 if (c.tag == id)
1240 components.add(c);
1242 if (components.size() == 0)
1243 throw new BAD_PARAM("No component " + id +
1244 " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE
1246 else
1248 TaggedComponent[] t = new TaggedComponent[ components.size() ];
1249 for (int i = 0; i < t.length; i++)
1250 t [ i ] = (TaggedComponent) components.get(i);
1251 return t;
1257 * This should be not implemented up till jdk 1.5 inclusive.
1259 public Policy get_request_policy(int type) throws INV_POLICY
1261 throw new NO_IMPLEMENT();
1264 /** @inheritDoc */
1265 public String received_exception_id()
1267 return m_exception_id;
1270 /** @inheritDoc */
1271 public Any received_exception()
1273 if (m_exception_id == null)
1274 return null;
1276 if (m_sys_ex != null)
1278 Any a = orb.create_any();
1279 ObjectCreator.insertSysException(a, m_sys_ex);
1280 return a;
1283 Exception mex = m_environment.exception();
1285 UnknownUserException ex = (UnknownUserException) mex;
1286 if (ex == null)
1287 return null;
1288 else
1289 return ex.except;
1293 * Return the forwarded reference, null if none.
1295 public org.omg.CORBA.Object forward_reference()
1297 if (m_forwarding_target != null)
1298 return m_forwarding_target;
1300 if (m_forward_ior != null)
1301 return new IorObject(orb, m_forward_ior);
1302 else
1303 return null;
1307 * Get the slot from the slot array inside this request.
1309 public Any get_slot(int id) throws InvalidSlot
1313 return m_slots [ id ];
1315 catch (Exception e)
1317 throw new InvalidSlot("slot id " + id + ":" + e);
1322 * Get the reply status.
1324 public short reply_status()
1326 if (m_rph == null)
1327 throw new BAD_INV_ORDER("Request not yet sent", 14,
1328 CompletionStatus.COMPLETED_NO
1330 return (short) m_rph.reply_status;
1334 * Get the request id.
1336 public int request_id()
1338 return m_rqh.request_id;
1342 * Return true if the response is expected.
1344 public boolean response_expected()
1346 return !oneWay;
1350 * Determines how far the request shall progress before control is returned to
1351 * the client. However up till JDK 1.5 inclusive this method always returns
1352 * SYNC_WITH_TRANSPORT.
1354 * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
1356 * @specnote as defined in the Suns 1.5 JDK API.
1358 public short sync_scope()
1360 return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
1363 /** @inheritDoc */
1364 public ServiceContext get_request_service_context(int ctx_name)
1365 throws BAD_PARAM
1367 return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1368 m_rqh.service_context
1372 /** @inheritDoc */
1373 public ServiceContext get_reply_service_context(int ctx_name)
1374 throws BAD_PARAM
1376 if (m_rph == null)
1377 throw new BAD_INV_ORDER("Reply context not yet available");
1378 return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1379 m_rph.service_context
1383 /** @inheritDoc */
1384 public String[] operation_context()
1386 return ice_contexts();
1390 * Get contexts as required by interceptor.
1392 public String[] ice_contexts()
1394 if (m_context_list == null)
1395 return new String[ 0 ];
1396 else
1400 String[] cn = new String[ m_context_list.count() ];
1401 for (int i = 0; i < cn.length; i++)
1402 cn [ i ] = m_context_list.item(i);
1403 return cn;
1405 catch (Bounds e)
1407 throw new Unexpected(e);
1413 * Check if the call is done via DII.
1415 public void checkDii()
1417 if (m_parameter_buffer != null)
1418 throw new NO_RESOURCES("The invocation method provides " +
1419 "no access to this resource. DII call required.", 1,
1420 CompletionStatus.COMPLETED_MAYBE