Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / gnu / CORBA / gnuRequest.java
blob5adf741292626647074f7504e51be02e555b6f06
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.BindException;
91 import java.net.Socket;
93 import java.util.ArrayList;
95 /**
96 * The implementation of the CORBA request.
98 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
100 public class gnuRequest extends Request implements Cloneable
103 * The maximal supported GIOP version.
105 public static Version MAX_SUPPORTED = new Version(1, 2);
108 * The initial pause that the Request makes when the required port is not
109 * available.
111 public static int PAUSE_INITIAL = 50;
114 * The number of repretetive attempts to get a required port, if it is not
115 * immediately available.
117 public static int PAUSE_STEPS = 12;
120 * The maximal pausing interval between two repetetive attempts. The interval
121 * doubles after each unsuccessful attempt, but will not exceed this value.
123 public static int PAUSE_MAX = 1000;
126 * The interceptor, listening the major request submission points.
128 ClientRequestInterceptorOperations m_interceptor;
131 * The request info, used by interceptor.
133 ClientRequestInfo m_info = new gnuClientRequestInfo(this);
136 * The empty byte array.
138 private static final RawReply EMPTY =
139 new RawReply(null, new MessageHeader(), new byte[ 0 ]);
142 * The context holder for methods ctx(Context) and ctx().
144 protected Context m_context;
147 * The context list for method contexts().
149 protected ContextList m_context_list;
152 * The request environment for holding the exception the has possibly been
153 * thrown by the method being invoked.
155 protected Environment m_environment = new gnuEnvironment();
158 * The list of all exceptions that can be thrown by the method being invoked.
160 protected ExceptionList m_exceptions = new gnuExceptionList();
163 * The result, returned by the invoked method (function).
165 protected NamedValue m_result = new gnuNamedValue();
168 * The exception id, received from the server, null if none.
170 protected String m_exception_id;
173 * The thrown system exception.
175 protected SystemException m_sys_ex;
178 * The invocation target.
180 protected org.omg.CORBA.Object m_target;
183 * The name of the method being invoked.
185 protected String m_operation;
188 * This field temporary remembers the value of the forwarded ior reference. If
189 * it is not null, the request was forwarded and the effective target is not
190 * the same as the default target.
192 public IOR m_forward_ior;
195 * Is set when object, and not IOR is directly available.
197 public org.omg.CORBA.Object m_forwarding_target;
200 * The flag, indicating that the request has been sent and the result is
201 * already received.
203 protected boolean complete;
206 * The flag, indicating that the response to this request must be ignored
207 * (used with {@link #send_oneway()}).
209 protected boolean oneWay;
212 * The flag, indicating that the request has been sent and no result is yet
213 * received.
215 protected boolean running;
218 * The request arguments.
220 protected gnuNVList m_args = new gnuNVList();
223 * The request arguments in the case when they are directly written into the
224 * parameter buffer.
226 protected StreamBasedRequest m_parameter_buffer;
229 * The array of slots.
231 protected Any[] m_slots;
234 * The request header currently in use.
236 protected RequestHeader m_rqh;
239 * The reply header currently in use.
241 protected ReplyHeader m_rph;
244 * The IOR of the target.
246 private IOR ior;
249 * The ORB of the target.
251 private ORB orb;
254 * The encoding, used to send the message.
256 * The default encoding is inherited from the set IOR (that string reference
257 * can be encoded in either Big or Little endian). If the IOR encoding is not
258 * known (for example, by obtaining the reference from the naming service),
259 * the Big Endian is used.
261 private boolean Big_endian = true;
264 * Set the IOR data, sufficient to find the invocation target. This also sets
265 * default endian encoding for invocations.
267 * @see IOR.parse(String)
269 public void setIor(IOR an_ior)
271 ior = an_ior;
272 setBigEndian(ior.Big_Endian);
276 * Used when redirecting request to another target.
278 gnuRequest redirected;
281 * Get the IOR data, sufficient to find the invocation target.
283 * @return the IOR data.
285 public IOR getIor()
287 return ior;
291 * Set the ORB, related to the invocation target.
293 public void setORB(ORB an_orb)
295 orb = an_orb;
297 // Take the interceptor from the ORB.
298 if (orb instanceof OrbRestricted)
299 m_interceptor = ((OrbRestricted) orb).iClient;
301 if (m_interceptor != null && orb instanceof ORB_1_4)
303 m_slots = ((ORB_1_4) orb).ic_current.clone_slots();
308 * Set the encoding that will be used to send the message. The default
309 * encoding is inherited from the set IOR (that string reference can be
310 * encoded in either Big or Little endian). If the IOR encoding is not known
311 * (for example, by obtaining the reference from the naming service), the Big
312 * Endian is used.
314 * @param use_big_endian true to use the Big Endian, false to use the Little
315 * Endian encoding.
317 public void setBigEndian(boolean use_big_endian)
319 Big_endian = use_big_endian;
323 * The the method name to invoke.
325 * @param operation the method name.
327 public void setOperation(String operation)
329 m_operation = operation;
333 * Get the parameter stream, where the invocation arguments should be written
334 * if they are written into the stream directly.
336 public StreamBasedRequest getParameterStream()
338 m_parameter_buffer = new StreamBasedRequest();
339 m_parameter_buffer.request = this;
340 m_parameter_buffer.setVersion(ior.Internet.version);
341 m_parameter_buffer.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
342 m_parameter_buffer.setOrb(orb);
343 m_parameter_buffer.setBigEndian(Big_endian);
345 // For the old iiop versions, it is important to set the size
346 // correctly.
347 if (ior.Internet.version.until_inclusive(1, 1))
349 BufferedCdrOutput measure = new BufferedCdrOutput();
350 measure.setOffset(12);
351 if (m_rqh == null)
352 m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader();
353 m_rqh.operation = m_operation;
354 m_rqh.object_key = ior.key;
355 m_rqh.write(measure);
356 m_parameter_buffer.setOffset(12 + measure.buffer.size());
359 return m_parameter_buffer;
363 * Creates a shallow copy of this request.
365 public gnuRequest Clone()
369 return (gnuRequest) clone();
371 catch (CloneNotSupportedException ex)
373 throw new Unexpected(ex);
377 /** {@inheritDoc} */
378 public Any add_in_arg()
380 gnuNamedValue v = new gnuNamedValue();
381 v.setFlags(ARG_IN.value);
382 m_args.add(v);
383 return v.value();
386 /** {@inheritDoc} */
387 public Any add_inout_arg()
389 gnuNamedValue v = new gnuNamedValue();
390 v.setFlags(ARG_INOUT.value);
391 m_args.add(v);
392 return v.value();
395 /** {@inheritDoc} */
396 public Any add_named_in_arg(String name)
398 gnuNamedValue v = new gnuNamedValue();
399 v.setFlags(ARG_IN.value);
400 v.setName(name);
401 m_args.add(v);
402 return v.value();
405 /** {@inheritDoc} */
406 public Any add_named_inout_arg(String name)
408 gnuNamedValue v = new gnuNamedValue();
409 v.setFlags(ARG_INOUT.value);
410 v.setName(name);
411 m_args.add(v);
412 return v.value();
415 /** {@inheritDoc} */
416 public Any add_named_out_arg(String name)
418 gnuNamedValue v = new gnuNamedValue();
419 v.setFlags(ARG_OUT.value);
420 v.setName(name);
421 m_args.add(v);
422 return v.value();
425 /** {@inheritDoc} */
426 public Any add_out_arg()
428 gnuNamedValue v = new gnuNamedValue();
429 v.setFlags(ARG_OUT.value);
430 m_args.add(v);
431 return v.value();
434 /** {@inheritDoc} */
435 public NVList arguments()
437 return m_args;
440 /** {@inheritDoc} */
441 public ContextList contexts()
443 return m_context_list;
446 /** {@inheritDoc} */
447 public Context ctx()
449 return m_context;
452 /** {@inheritDoc} */
453 public void ctx(Context a_context)
455 m_context = a_context;
458 /** {@inheritDoc} */
459 public Environment env()
461 return m_environment;
464 /** {@inheritDoc} */
465 public ExceptionList exceptions()
467 return m_exceptions;
470 /** {@inheritDoc} */
471 public void get_response() throws org.omg.CORBA.WrongTransaction
474 * The response is ready after it is received. FIXME implement context
475 * checks and any other functionality, if required.
480 * Submit the request, suspending the current thread until the answer is
481 * received.
483 * This implementation requires to set the IOR property ({@link #setIOR(IOR)}
484 * before calling this method.
486 * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously
487 * set.
489 * @throws SystemException if this exception has been thrown on remote side.
490 * The exact exception type and the minor code are the same as they have been
491 * for the exception, thrown on remoted side.
493 public synchronized void invoke() throws BAD_INV_ORDER
495 waitWhileBusy();
496 complete = false;
497 running = true;
499 if (ior == null)
500 throw new BAD_INV_ORDER("Set IOR property first");
504 Forwardings:
505 while (true)
509 p_invoke();
510 break Forwardings;
512 catch (ForwardRequest e)
516 ObjectImpl impl = (ObjectImpl) e.forward;
517 SimpleDelegate delegate =
518 (SimpleDelegate) impl._get_delegate();
519 ior = delegate.getIor();
521 catch (Exception ex)
523 BAD_PARAM bad =
524 new BAD_PARAM("Unsupported forwarding target");
525 bad.initCause(ex);
526 throw bad;
531 finally
533 running = false;
534 complete = true;
538 /** {@inheritDoc} */
539 public String operation()
541 return m_operation;
545 * Get the orb, related to the invocation target.
547 public ORB orb()
549 return orb;
552 /** {@inheritDoc} */
553 public boolean poll_response()
555 return complete && !running;
558 /** {@inheritDoc} */
559 public NamedValue result()
561 return m_result;
565 * {@inheritDoc}
568 public Any return_value()
570 return m_result.value();
573 /** {@inheritDoc} */
574 public synchronized void send_deferred()
576 waitWhileBusy();
577 new Thread()
579 public void run()
581 invoke();
583 }.start();
587 * Send a request and forget about it, not waiting for a response. This can be
588 * done also for methods that normally are expected to return some values.
590 * TODO It is generally recommended to reuse the threads. Reuse?
592 public void send_oneway()
594 final gnuRequest cloned = Clone();
595 cloned.oneWay = true;
597 new Thread()
599 public void run()
601 cloned.invoke();
603 }.start();
607 * Set the argument list. This field is initialised as empty non null instance
608 * by default, so the method is only used in cases when the direct replacement
609 * is desired.
611 * @param a_args the argument list.
613 public void set_args(NVList a_args)
615 if (a_args instanceof gnuNVList)
616 m_args = (gnuNVList) a_args;
617 else
621 // In case if this is another implementation of the NVList.
622 m_args.list.clear();
623 for (int i = 0; i < a_args.count(); i++)
625 m_args.add(a_args.item(i));
628 catch (Bounds ex)
630 Unexpected.error(ex);
636 * Set the context list that is later returned by the method
637 * {@link #contexts()}.
639 * @param a_context_list a new context list.
641 public void set_context_list(ContextList a_context_list)
643 m_context_list = a_context_list;
647 * Set the exception container. This field is initialised as empty non null
648 * instance by default, so the method is only used in cases when the direct
649 * replacement is desired.
651 * @param a_environment the new exception container.
653 public void set_environment(Environment a_environment)
655 m_environment = a_environment;
659 * Set the list of exceptions. This field is initialised as empty non null
660 * instance by default, so the method is only used in cases when the direct
661 * replacement is desired.
663 * @param a_exceptions a list of exceptions.
665 public void set_exceptions(ExceptionList a_exceptions)
667 m_exceptions = a_exceptions;
671 * Set the operation name.
673 * @param a_operation the operation name.
675 public void set_operation(String a_operation)
677 m_operation = a_operation;
681 * Set the named value, returned as result. This field is initialised as empty
682 * non null instance by default, so the method is only used in cases when the
683 * direct replacement is desired.
685 * @param a_result the result keeper.
687 public void set_result(NamedValue a_result)
689 m_result = a_result;
693 * Set the type of the named value, returned as a result. Instantiates a new
694 * instance of the result value.
696 public void set_return_type(TypeCode returns)
698 if (m_result == null || !returns.equal(m_result.value().type()))
700 m_result = new gnuNamedValue();
701 m_result.value().type(returns);
706 * Set the invocation target.
708 * @param a_target the CORBA object for that the method will be invoked.
710 public void set_target(org.omg.CORBA.Object a_target)
712 m_target = a_target;
716 * Do the actual invocation. This implementation requires to set the IOR
717 * property ({@link #setIOR(IOR)} before calling this method.
719 * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set
720 * or if the direct argument addition is mixed with the direct argument
721 * writing into the output stream.
723 * @return the server response in binary form.
725 public synchronized RawReply submit()
726 throws ForwardRequest
728 gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader();
730 header.setBigEndian(Big_endian);
732 // The byte order will be Big Endian by default.
733 header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST;
734 header.version = useVersion(ior.Internet.version);
736 RequestHeader rh = header.create_request_header();
737 rh.operation = m_operation;
738 rh.object_key = ior.key;
740 // Update interceptor.
741 m_rqh = rh;
743 if (m_interceptor != null)
744 m_interceptor.send_request(m_info);
746 // Prepare the submission.
747 BufferedCdrOutput request_part = new BufferedCdrOutput();
749 request_part.setOffset(header.getHeaderSize());
750 request_part.setVersion(header.version);
751 request_part.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
752 request_part.setOrb(orb);
753 request_part.setBigEndian(header.isBigEndian());
755 // This also sets the stream encoding to the encoding, specified
756 // in the header.
757 rh.write(request_part);
759 if (m_args != null && m_args.count() > 0)
761 write_parameters(header, request_part);
763 if (m_parameter_buffer != null)
764 throw new BAD_INV_ORDER("Please either add parameters or "
765 + "write them into stream, but not both " + "at once.");
768 if (m_parameter_buffer != null)
770 write_parameter_buffer(header, request_part);
773 // Now the message size is available.
774 header.message_size = request_part.buffer.size();
776 Socket socket = null;
778 java.lang.Object key = ior.Internet.host + ":" + ior.Internet.port;
780 synchronized (SocketRepository.class)
782 socket = SocketRepository.get_socket(key);
787 long pause = PAUSE_INITIAL;
789 if (socket == null)
791 // The BindException may be thrown under very heavy parallel
792 // load. For some time, just wait, exceptiong the socket to free.
793 Open: for (int i = 0; i < PAUSE_STEPS; i++)
797 if (orb instanceof OrbFunctional)
798 socket = ((OrbFunctional) orb).socketFactory.createClientSocket(
799 ior.Internet.host, ior.Internet.port);
800 else
801 socket = new Socket(ior.Internet.host, ior.Internet.port);
802 break Open;
804 catch (BindException ex)
808 // Expecting to free a socket via finaliser.
809 System.gc();
810 Thread.sleep(pause);
811 pause = pause * 2;
812 if (pause > PAUSE_MAX)
813 pause = PAUSE_MAX;
815 catch (InterruptedException iex)
822 if (socket == null)
823 throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port
824 + " in use");
825 socket.setKeepAlive(true);
827 OutputStream socketOutput = socket.getOutputStream();
829 // Write the message header.
830 header.write(socketOutput);
832 // Write the request header and parameters (if present).
833 request_part.buffer.writeTo(socketOutput);
835 socketOutput.flush();
836 if (!socket.isClosed())
838 MessageHeader response_header = new MessageHeader();
839 InputStream socketInput = socket.getInputStream();
840 response_header.read(socketInput);
842 byte[] r;
843 if (orb instanceof OrbFunctional)
845 OrbFunctional fo = (OrbFunctional) orb;
846 r = response_header.readMessage(socketInput, socket,
847 fo.TOUT_WHILE_READING, fo.TOUT_AFTER_RECEIVING);
849 else
850 r = response_header.readMessage(socketInput, null, 0, 0);
852 return new RawReply(orb, response_header, r);
854 else
855 return EMPTY;
857 catch (IOException io_ex)
859 COMM_FAILURE m = new COMM_FAILURE("Unable to open a socket at "
860 + ior.Internet.host + ":" + ior.Internet.port, 0xC9,
861 CompletionStatus.COMPLETED_NO);
862 m.initCause(io_ex);
863 throw m;
865 finally
869 if (socket != null && !socket.isClosed())
871 socket.setSoTimeout(OrbFunctional.TANDEM_REQUESTS);
872 SocketRepository.put_socket(key, socket);
875 catch (IOException scx)
877 InternalError ierr = new InternalError();
878 ierr.initCause(scx);
879 throw ierr;
884 /** {@inheritDoc} */
885 public org.omg.CORBA.Object target()
887 return m_target;
891 * Get the used version. Normally, it is better to respond using the same
892 * version as it is specified in IOR, but not above the maximal supported
893 * version.
895 public Version useVersion(Version desired)
897 if (desired.until_inclusive(MAX_SUPPORTED.major, MAX_SUPPORTED.minor))
898 return desired;
899 else
900 return MAX_SUPPORTED;
904 * Wait while the response to request, submitted using
905 * {@link #send_deferred()} or {@link #invoke()} (from other thread) is
906 * returned.
908 * FIXME It is possible to rewrite this using Object.wait() and
909 * Object.notify(), but be sure to prepare the test as well.
911 public synchronized void waitWhileBusy()
913 // Waiting constants.
914 long wait = 10;
915 long increment = 2;
916 long max = 5000;
918 while (running)
922 Thread.sleep(wait);
923 if (wait < max)
924 wait = wait * increment;
926 catch (InterruptedException ex)
933 * Do actual invocation. This method recursively calls itself if the
934 * redirection is detected.
936 private void p_invoke()
937 throws SystemException, ForwardRequest
939 RawReply response = submit();
941 if (m_rph == null)
942 m_rph = response.header.create_reply_header();
944 BufferredCdrInput input = response.getStream();
945 input.setOrb(orb);
947 m_rph.read(input);
949 // The stream must be aligned sinve v1.2, but only once.
950 boolean align = response.header.version.since_inclusive(1, 2);
952 switch (m_rph.reply_status)
954 case ReplyHeader.NO_EXCEPTION:
956 NamedValue arg;
958 // Read return value, if set.
959 if (m_result != null)
961 if (align)
963 input.align(8);
964 align = false;
966 m_result.value().read_value(input, m_result.value().type());
969 // Read returned parameters, if set.
970 if (m_args != null)
971 for (int i = 0; i < m_args.count(); i++)
975 arg = m_args.item(i);
977 // Both ARG_INOUT and ARG_OUT have this binary flag set.
978 if ((arg.flags() & ARG_OUT.value) != 0)
980 if (align)
982 input.align(8);
983 align = false;
986 arg.value().read_value(input, arg.value().type());
989 catch (Bounds ex)
991 Unexpected.error(ex);
995 if (m_interceptor != null)
996 m_interceptor.receive_reply(m_info);
998 break;
1000 case ReplyHeader.SYSTEM_EXCEPTION:
1001 if (align)
1003 input.align(8);
1004 align = false;
1006 readExceptionId(input);
1008 m_sys_ex = ObjectCreator.readSystemException(input,
1009 m_rph.service_context);
1010 m_environment.exception(m_sys_ex);
1012 if (m_interceptor != null)
1013 m_interceptor.receive_exception(m_info);
1015 throw m_sys_ex;
1017 case ReplyHeader.USER_EXCEPTION:
1018 if (align)
1020 input.align(8);
1021 align = false;
1023 readExceptionId(input);
1025 // Prepare an Any that will hold the exception.
1026 gnuAny exc = new gnuAny();
1027 exc.setOrb(orb);
1029 exc.insert_Streamable(new StreamHolder(input));
1031 UnknownUserException unuex = new UnknownUserException(exc);
1032 m_environment.exception(unuex);
1034 if (m_interceptor != null)
1035 m_interceptor.receive_exception(m_info);
1037 break;
1039 case ReplyHeader.LOCATION_FORWARD_PERM:
1040 case ReplyHeader.LOCATION_FORWARD:
1041 if (response.header.version.since_inclusive(1, 2))
1042 input.align(8);
1044 IOR forwarded = new IOR();
1047 forwarded._read_no_endian(input);
1049 catch (IOException ex)
1051 new MARSHAL("Cant read forwarding info", 5103,
1052 CompletionStatus.COMPLETED_NO);
1055 setIor(forwarded);
1057 m_forward_ior = forwarded;
1059 if (m_interceptor != null)
1060 m_interceptor.receive_other(m_info);
1062 // Repeat with the forwarded information.
1063 p_invoke();
1064 return;
1066 default:
1067 throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status,
1068 CompletionStatus.COMPLETED_NO);
1073 * Read exception id without changing the stream pointer position.
1075 void readExceptionId(BufferredCdrInput input)
1077 input.mark(2048);
1078 m_exception_id = input.read_string();
1079 input.reset();
1083 * Write the operation parameters.
1085 * @param header the message header
1086 * @param request_part the stream to write parameters into
1088 * @throws MARSHAL if the attempt to write the parameters has failde.
1090 protected void write_parameter_buffer(MessageHeader header,
1091 BufferedCdrOutput request_part
1092 ) throws MARSHAL
1096 if (header.version.since_inclusive(1, 2))
1098 request_part.align(8);
1100 m_parameter_buffer.buffer.writeTo(request_part);
1102 catch (IOException ex)
1104 MARSHAL m = new MARSHAL("Unable to write method arguments to CDR output.");
1105 m.minor = Minor.CDR;
1106 throw m;
1111 * Write the operation parameters.
1113 * @param header the message header
1114 * @param request_part the stream to write parameters into
1116 * @throws MARSHAL if the attempt to write the parameters has failde.
1118 protected void write_parameters(MessageHeader header,
1119 BufferedCdrOutput request_part
1120 ) throws MARSHAL
1122 // Align after 1.2, but only once.
1123 boolean align = header.version.since_inclusive(1, 2);
1124 NamedValue para;
1128 // Write parameters now.
1129 for (int i = 0; i < m_args.count(); i++)
1131 para = m_args.item(i);
1133 // This bit is set both for ARG_IN and ARG_INOUT
1134 if ((para.flags() & ARG_IN.value) != 0)
1136 if (align)
1138 request_part.align(8);
1139 align = false;
1141 para.value().write_value(request_part);
1145 catch (Bounds ex)
1147 InternalError ierr = new InternalError();
1148 ierr.initCause(ex);
1149 throw ierr;
1153 /* **************Implementation of the request info operations. ***** */
1156 * Add context to request.
1158 public void add_request_service_context(ServiceContext service_context,
1159 boolean replace
1162 m_rqh.addContext(service_context, replace);
1166 * Get the Internet profile as an effective profile.
1168 public TaggedProfile effective_profile()
1170 BufferedCdrOutput buf = new BufferedCdrOutput(512);
1171 buf.setOrb(orb);
1172 ior.Internet.write(buf);
1174 TaggedProfile p = new TaggedProfile();
1175 p.tag = TAG_INTERNET_IOP.value;
1176 p.profile_data = buf.buffer.toByteArray();
1177 return p;
1181 * Return either target or forwarded targed.
1183 public org.omg.CORBA.Object effective_target()
1185 return new IorObject(orb, ior);
1189 * Get effective component with the give id from the Internet profile.
1191 public TaggedComponent get_effective_component(int id)
1192 throws BAD_PARAM
1194 if (id == TAG_CODE_SETS.value)
1196 // Codesets are encoded separately.
1197 BufferedCdrOutput buf = new BufferedCdrOutput(512);
1198 buf.setOrb(orb);
1199 ior.Internet.CodeSets.write(buf);
1201 TaggedComponent t = new TaggedComponent();
1202 t.tag = TAG_CODE_SETS.value;
1203 t.component_data = buf.buffer.toByteArray();
1204 return t;
1206 else
1208 for (int i = 0; i < ior.Internet.components.size(); i++)
1210 TaggedComponent c =
1211 (TaggedComponent) ior.Internet.components.get(i);
1212 if (c.tag == id)
1213 return c;
1216 throw new BAD_PARAM("No component " + id + " in the Internet profile", 28,
1217 CompletionStatus.COMPLETED_MAYBE
1222 * Get all components with the given id from the internet profile.
1224 public TaggedComponent[] get_effective_components(int id)
1225 throws BAD_PARAM
1227 if (id == TAG_CODE_SETS.value)
1228 return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) };
1229 else
1231 ArrayList components = new ArrayList(ior.Internet.components.size());
1232 for (int i = 0; i < ior.Internet.components.size(); i++)
1234 TaggedComponent c =
1235 (TaggedComponent) ior.Internet.components.get(i);
1236 if (c.tag == id)
1237 components.add(c);
1239 if (components.size() == 0)
1240 throw new BAD_PARAM("No component " + id +
1241 " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE
1243 else
1245 TaggedComponent[] t = new TaggedComponent[ components.size() ];
1246 for (int i = 0; i < t.length; i++)
1247 t [ i ] = (TaggedComponent) components.get(i);
1248 return t;
1254 * This should be not implemented up till jdk 1.5 inclusive.
1256 public Policy get_request_policy(int type) throws INV_POLICY
1258 throw new NO_IMPLEMENT();
1261 /** @inheritDoc */
1262 public String received_exception_id()
1264 return m_exception_id;
1267 /** @inheritDoc */
1268 public Any received_exception()
1270 if (m_exception_id == null)
1271 return null;
1273 if (m_sys_ex != null)
1275 Any a = orb.create_any();
1276 ObjectCreator.insertSysException(a, m_sys_ex);
1277 return a;
1280 Exception mex = m_environment.exception();
1282 UnknownUserException ex = (UnknownUserException) mex;
1283 if (ex == null)
1284 return null;
1285 else
1286 return ex.except;
1290 * Return the forwarded reference, null if none.
1292 public org.omg.CORBA.Object forward_reference()
1294 if (m_forwarding_target != null)
1295 return m_forwarding_target;
1297 if (m_forward_ior != null)
1298 return new IorObject(orb, m_forward_ior);
1299 else
1300 return null;
1304 * Get the slot from the slot array inside this request.
1306 public Any get_slot(int id) throws InvalidSlot
1310 return m_slots [ id ];
1312 catch (Exception e)
1314 throw new InvalidSlot("slot id " + id + ":" + e);
1319 * Get the reply status.
1321 public short reply_status()
1323 if (m_rph == null)
1324 throw new BAD_INV_ORDER("Request not yet sent", 14,
1325 CompletionStatus.COMPLETED_NO
1327 return (short) m_rph.reply_status;
1331 * Get the request id.
1333 public int request_id()
1335 return m_rqh.request_id;
1339 * Return true if the response is expected.
1341 public boolean response_expected()
1343 return !oneWay;
1347 * Determines how far the request shall progress before control is returned to
1348 * the client. However up till JDK 1.5 inclusive this method always returns
1349 * SYNC_WITH_TRANSPORT.
1351 * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
1353 * @specnote as defined in the Suns 1.5 JDK API.
1355 public short sync_scope()
1357 return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
1360 /** @inheritDoc */
1361 public ServiceContext get_request_service_context(int ctx_name)
1362 throws BAD_PARAM
1364 return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1365 m_rqh.service_context
1369 /** @inheritDoc */
1370 public ServiceContext get_reply_service_context(int ctx_name)
1371 throws BAD_PARAM
1373 if (m_rph == null)
1374 throw new BAD_INV_ORDER("Reply context not yet available");
1375 return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1376 m_rph.service_context
1380 /** @inheritDoc */
1381 public String[] operation_context()
1383 return ice_contexts();
1387 * Get contexts as required by interceptor.
1389 public String[] ice_contexts()
1391 if (m_context_list == null)
1392 return new String[ 0 ];
1393 else
1397 String[] cn = new String[ m_context_list.count() ];
1398 for (int i = 0; i < cn.length; i++)
1399 cn [ i ] = m_context_list.item(i);
1400 return cn;
1402 catch (Bounds e)
1404 throw new Unexpected(e);
1410 * Check if the call is done via DII.
1412 public void checkDii()
1414 if (m_parameter_buffer != null)
1415 throw new NO_RESOURCES("The invocation method provides " +
1416 "no access to this resource. DII call required.", 1,
1417 CompletionStatus.COMPLETED_MAYBE