12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424 |
- /* gnuRequest.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.CDR.BufferedCdrOutput;
- import gnu.CORBA.GIOP.MessageHeader;
- import gnu.CORBA.GIOP.ReplyHeader;
- import gnu.CORBA.GIOP.RequestHeader;
- import gnu.CORBA.GIOP.CodeSetServiceContext;
- import gnu.CORBA.Interceptor.gnuClientRequestInfo;
- import gnu.CORBA.Poa.ORB_1_4;
- import org.omg.CORBA.ARG_IN;
- import org.omg.CORBA.ARG_INOUT;
- import org.omg.CORBA.ARG_OUT;
- import org.omg.CORBA.Any;
- import org.omg.CORBA.BAD_INV_ORDER;
- import org.omg.CORBA.BAD_PARAM;
- import org.omg.CORBA.Bounds;
- import org.omg.CORBA.COMM_FAILURE;
- import org.omg.CORBA.CompletionStatus;
- import org.omg.CORBA.Context;
- import org.omg.CORBA.ContextList;
- import org.omg.CORBA.Environment;
- import org.omg.CORBA.ExceptionList;
- import org.omg.CORBA.INV_POLICY;
- import org.omg.CORBA.MARSHAL;
- import org.omg.CORBA.NO_IMPLEMENT;
- import org.omg.CORBA.NO_RESOURCES;
- import org.omg.CORBA.NVList;
- import org.omg.CORBA.NamedValue;
- import org.omg.CORBA.ORB;
- import org.omg.CORBA.Policy;
- import org.omg.CORBA.Request;
- import org.omg.CORBA.SystemException;
- import org.omg.CORBA.TypeCode;
- import org.omg.CORBA.UnknownUserException;
- import org.omg.CORBA.portable.ObjectImpl;
- import org.omg.IOP.ServiceContext;
- import org.omg.IOP.TAG_CODE_SETS;
- import org.omg.IOP.TAG_INTERNET_IOP;
- import org.omg.IOP.TaggedComponent;
- import org.omg.IOP.TaggedProfile;
- import org.omg.PortableInterceptor.ClientRequestInfo;
- import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
- import org.omg.PortableInterceptor.ForwardRequest;
- import org.omg.PortableInterceptor.InvalidSlot;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.Socket;
- import java.util.ArrayList;
- /**
- * The implementation of the CORBA request.
- *
- * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
- */
- public class gnuRequest extends Request implements Cloneable
- {
- /**
- * The maximal supported GIOP version.
- */
- public static Version MAX_SUPPORTED = new Version(1, 2);
- /**
- * The initial pause that the Request makes when the required port is not
- * available.
- */
- public static int PAUSE_INITIAL = 50;
- /**
- * The number of repretetive attempts to get a required port, if it is not
- * immediately available.
- */
- public static int PAUSE_STEPS = 12;
- /**
- * The maximal pausing interval between two repetetive attempts. The interval
- * doubles after each unsuccessful attempt, but will not exceed this value.
- */
- public static int PAUSE_MAX = 1000;
- /**
- * The interceptor, listening the major request submission points.
- */
- ClientRequestInterceptorOperations m_interceptor;
- /**
- * The request info, used by interceptor.
- */
- ClientRequestInfo m_info = new gnuClientRequestInfo(this);
- /**
- * The empty byte array.
- */
- private static final RawReply EMPTY =
- new RawReply(null, new MessageHeader(), new byte[ 0 ]);
- /**
- * The context holder for methods ctx(Context) and ctx().
- */
- protected Context m_context;
- /**
- * The context list for method contexts().
- */
- protected ContextList m_context_list;
- /**
- * The request environment for holding the exception the has possibly been
- * thrown by the method being invoked.
- */
- protected Environment m_environment = new gnuEnvironment();
- /**
- * The list of all exceptions that can be thrown by the method being invoked.
- */
- protected ExceptionList m_exceptions = new gnuExceptionList();
- /**
- * The result, returned by the invoked method (function).
- */
- protected NamedValue m_result = new gnuNamedValue();
- /**
- * The exception id, received from the server, null if none.
- */
- protected String m_exception_id;
- /**
- * The thrown system exception.
- */
- protected SystemException m_sys_ex;
- /**
- * The invocation target.
- */
- protected org.omg.CORBA.Object m_target;
- /**
- * The name of the method being invoked.
- */
- protected String m_operation;
- /**
- * This field temporary remembers the value of the forwarded ior reference. If
- * it is not null, the request was forwarded and the effective target is not
- * the same as the default target.
- */
- public IOR m_forward_ior;
- /**
- * Is set when object, and not IOR is directly available.
- */
- public org.omg.CORBA.Object m_forwarding_target;
- /**
- * The flag, indicating that the request has been sent and the result is
- * already received.
- */
- protected boolean complete;
- /**
- * The flag, indicating that the response to this request must be ignored
- * (used with {@link #send_oneway()}).
- */
- protected boolean oneWay;
- /**
- * The flag, indicating that the request has been sent and no result is yet
- * received.
- */
- protected boolean running;
- /**
- * The request arguments.
- */
- protected gnuNVList m_args = new gnuNVList();
- /**
- * The request arguments in the case when they are directly written into the
- * parameter buffer.
- */
- protected StreamBasedRequest m_parameter_buffer;
- /**
- * The array of slots.
- */
- protected Any[] m_slots;
- /**
- * The request header currently in use.
- */
- protected RequestHeader m_rqh;
- /**
- * The reply header currently in use.
- */
- protected ReplyHeader m_rph;
- /**
- * The IOR of the target.
- */
- private IOR ior;
- /**
- * The ORB of the target.
- */
- private ORB orb;
- /**
- * The encoding, used to send the message.
- *
- * The default encoding is inherited from the set IOR (that string reference
- * can be encoded in either Big or Little endian). If the IOR encoding is not
- * known (for example, by obtaining the reference from the naming service),
- * the Big Endian is used.
- */
- private boolean Big_endian = true;
- /**
- * Set the IOR data, sufficient to find the invocation target. This also sets
- * default endian encoding for invocations.
- *
- * @see IOR.parse(String)
- */
- public void setIor(IOR an_ior)
- {
- ior = an_ior;
- setBigEndian(ior.Big_Endian);
- }
- /**
- * Used when redirecting request to another target.
- */
- gnuRequest redirected;
- /**
- * Get the IOR data, sufficient to find the invocation target.
- *
- * @return the IOR data.
- */
- public IOR getIor()
- {
- return ior;
- }
- /**
- * Set the ORB, related to the invocation target.
- */
- public void setORB(ORB an_orb)
- {
- orb = an_orb;
- // Take the interceptor from the ORB.
- if (orb instanceof OrbRestricted)
- m_interceptor = ((OrbRestricted) orb).iClient;
- if (m_interceptor != null && orb instanceof ORB_1_4)
- {
- m_slots = ((ORB_1_4) orb).ic_current.clone_slots();
- }
- }
- /**
- * Set the encoding that will be used to send the message. The default
- * encoding is inherited from the set IOR (that string reference can be
- * encoded in either Big or Little endian). If the IOR encoding is not known
- * (for example, by obtaining the reference from the naming service), the Big
- * Endian is used.
- *
- * @param use_big_endian true to use the Big Endian, false to use the Little
- * Endian encoding.
- */
- public void setBigEndian(boolean use_big_endian)
- {
- Big_endian = use_big_endian;
- }
- /**
- * The the method name to invoke.
- *
- * @param operation the method name.
- */
- public void setOperation(String operation)
- {
- m_operation = operation;
- }
- /**
- * Get the parameter stream, where the invocation arguments should be written
- * if they are written into the stream directly.
- */
- public StreamBasedRequest getParameterStream()
- {
- m_parameter_buffer = new StreamBasedRequest();
- m_parameter_buffer.request = this;
- m_parameter_buffer.setVersion(ior.Internet.version);
- m_parameter_buffer.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
- m_parameter_buffer.setOrb(orb);
- m_parameter_buffer.setBigEndian(Big_endian);
- // For the old iiop versions, it is important to set the size
- // correctly.
- if (ior.Internet.version.until_inclusive(1, 1))
- {
- BufferedCdrOutput measure = new BufferedCdrOutput();
- measure.setOffset(12);
- if (m_rqh == null)
- m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader();
- m_rqh.operation = m_operation;
- m_rqh.object_key = ior.key;
- m_rqh.write(measure);
- m_parameter_buffer.setOffset(12 + measure.buffer.size());
- }
- return m_parameter_buffer;
- }
- /**
- * Creates a shallow copy of this request.
- */
- public gnuRequest Clone()
- {
- try
- {
- return (gnuRequest) clone();
- }
- catch (CloneNotSupportedException ex)
- {
- throw new Unexpected(ex);
- }
- }
- /** {@inheritDoc} */
- public Any add_in_arg()
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_IN.value);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public Any add_inout_arg()
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_INOUT.value);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public Any add_named_in_arg(String name)
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_IN.value);
- v.setName(name);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public Any add_named_inout_arg(String name)
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_INOUT.value);
- v.setName(name);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public Any add_named_out_arg(String name)
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_OUT.value);
- v.setName(name);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public Any add_out_arg()
- {
- gnuNamedValue v = new gnuNamedValue();
- v.setFlags(ARG_OUT.value);
- m_args.add(v);
- return v.value();
- }
- /** {@inheritDoc} */
- public NVList arguments()
- {
- return m_args;
- }
- /** {@inheritDoc} */
- public ContextList contexts()
- {
- return m_context_list;
- }
- /** {@inheritDoc} */
- public Context ctx()
- {
- return m_context;
- }
- /** {@inheritDoc} */
- public void ctx(Context a_context)
- {
- m_context = a_context;
- }
- /** {@inheritDoc} */
- public Environment env()
- {
- return m_environment;
- }
- /** {@inheritDoc} */
- public ExceptionList exceptions()
- {
- return m_exceptions;
- }
- /** {@inheritDoc} */
- public void get_response() throws org.omg.CORBA.WrongTransaction
- {
- /**
- * The response is ready after it is received. FIXME implement context
- * checks and any other functionality, if required.
- */
- }
- /**
- * Submit the request, suspending the current thread until the answer is
- * received.
- *
- * This implementation requires to set the IOR property ({@link #setIOR(IOR)}
- * before calling this method.
- *
- * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously
- * set.
- *
- * @throws SystemException if this exception has been thrown on remote side.
- * The exact exception type and the minor code are the same as they have been
- * for the exception, thrown on remoted side.
- */
- public synchronized void invoke() throws BAD_INV_ORDER
- {
- waitWhileBusy();
- complete = false;
- running = true;
- if (ior == null)
- throw new BAD_INV_ORDER("Set IOR property first");
- try
- {
- Forwardings:
- while (true)
- {
- try
- {
- p_invoke();
- break Forwardings;
- }
- catch (ForwardRequest e)
- {
- try
- {
- ObjectImpl impl = (ObjectImpl) e.forward;
- SimpleDelegate delegate =
- (SimpleDelegate) impl._get_delegate();
- ior = delegate.getIor();
- }
- catch (Exception ex)
- {
- BAD_PARAM bad =
- new BAD_PARAM("Unsupported forwarding target");
- bad.initCause(ex);
- throw bad;
- }
- }
- }
- }
- finally
- {
- running = false;
- complete = true;
- }
- }
- /** {@inheritDoc} */
- public String operation()
- {
- return m_operation;
- }
- /**
- * Get the orb, related to the invocation target.
- */
- public ORB orb()
- {
- return orb;
- }
- /** {@inheritDoc} */
- public boolean poll_response()
- {
- return complete && !running;
- }
- /** {@inheritDoc} */
- public NamedValue result()
- {
- return m_result;
- }
- /**
- * {@inheritDoc}
- *
- */
- public Any return_value()
- {
- return m_result.value();
- }
- /** {@inheritDoc} */
- public synchronized void send_deferred()
- {
- waitWhileBusy();
- new Thread()
- {
- public void run()
- {
- invoke();
- }
- }.start();
- }
- /**
- * Send a request and forget about it, not waiting for a response. This can be
- * done also for methods that normally are expected to return some values.
- *
- * TODO It is generally recommended to reuse the threads. Reuse?
- */
- public void send_oneway()
- {
- final gnuRequest cloned = Clone();
- cloned.oneWay = true;
- new Thread()
- {
- public void run()
- {
- cloned.invoke();
- }
- }.start();
- }
- /**
- * Set the argument list. This field is initialised as empty non null instance
- * by default, so the method is only used in cases when the direct replacement
- * is desired.
- *
- * @param a_args the argument list.
- */
- public void set_args(NVList a_args)
- {
- if (a_args instanceof gnuNVList)
- m_args = (gnuNVList) a_args;
- else
- {
- try
- {
- // In case if this is another implementation of the NVList.
- m_args.list.clear();
- for (int i = 0; i < a_args.count(); i++)
- {
- m_args.add(a_args.item(i));
- }
- }
- catch (Bounds ex)
- {
- Unexpected.error(ex);
- }
- }
- }
- /**
- * Set the context list that is later returned by the method
- * {@link #contexts()}.
- *
- * @param a_context_list a new context list.
- */
- public void set_context_list(ContextList a_context_list)
- {
- m_context_list = a_context_list;
- }
- /**
- * Set the exception container. This field is initialised as empty non null
- * instance by default, so the method is only used in cases when the direct
- * replacement is desired.
- *
- * @param a_environment the new exception container.
- */
- public void set_environment(Environment a_environment)
- {
- m_environment = a_environment;
- }
- /**
- * Set the list of exceptions. This field is initialised as empty non null
- * instance by default, so the method is only used in cases when the direct
- * replacement is desired.
- *
- * @param a_exceptions a list of exceptions.
- */
- public void set_exceptions(ExceptionList a_exceptions)
- {
- m_exceptions = a_exceptions;
- }
- /**
- * Set the operation name.
- *
- * @param a_operation the operation name.
- */
- public void set_operation(String a_operation)
- {
- m_operation = a_operation;
- }
- /**
- * Set the named value, returned as result. This field is initialised as empty
- * non null instance by default, so the method is only used in cases when the
- * direct replacement is desired.
- *
- * @param a_result the result keeper.
- */
- public void set_result(NamedValue a_result)
- {
- m_result = a_result;
- }
- /**
- * Set the type of the named value, returned as a result. Instantiates a new
- * instance of the result value.
- */
- public void set_return_type(TypeCode returns)
- {
- if (m_result == null || !returns.equal(m_result.value().type()))
- {
- m_result = new gnuNamedValue();
- m_result.value().type(returns);
- }
- }
- /**
- * Set the invocation target.
- *
- * @param a_target the CORBA object for that the method will be invoked.
- */
- public void set_target(org.omg.CORBA.Object a_target)
- {
- m_target = a_target;
- }
- /**
- * Do the actual invocation. This implementation requires to set the IOR
- * property ({@link #setIOR(IOR)} before calling this method.
- *
- * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set
- * or if the direct argument addition is mixed with the direct
- * argument writing into the output stream.
- * @return the server response in binary form.
- */
- public synchronized RawReply submit()
- throws ForwardRequest
- {
- gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader();
- header.setBigEndian(Big_endian);
- // The byte order will be Big Endian by default.
- header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST;
- header.version = useVersion(ior.Internet.version);
- RequestHeader rh = header.create_request_header();
- rh.operation = m_operation;
- rh.object_key = ior.key;
- // Update interceptor.
- m_rqh = rh;
- if (m_interceptor != null)
- m_interceptor.send_request(m_info);
- // Prepare the submission.
- BufferedCdrOutput request_part = new BufferedCdrOutput();
- request_part.setOffset(header.getHeaderSize());
- request_part.setVersion(header.version);
- request_part.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
- request_part.setOrb(orb);
- request_part.setBigEndian(header.isBigEndian());
- // This also sets the stream encoding to the encoding, specified
- // in the header.
- rh.write(request_part);
- if (m_args != null && m_args.count() > 0)
- {
- write_parameters(header, request_part);
- if (m_parameter_buffer != null)
- throw new BAD_INV_ORDER("Please either add parameters or "
- + "write them into stream, but not both " + "at once.");
- }
- if (m_parameter_buffer != null)
- {
- write_parameter_buffer(header, request_part);
- }
- // Now the message size is available.
- header.message_size = request_part.buffer.size();
- Socket socket = null;
- java.lang.Object key = ior.Internet.host + ":" + ior.Internet.port;
- synchronized (SocketRepository.class)
- {
- socket = SocketRepository.get_socket(key);
- }
- try
- {
- long pause = PAUSE_INITIAL;
- if (socket == null)
- {
- // The IOException may be thrown under very heavy parallel
- // load. For some time, just wait, exceptiong the socket to free.
- Open: for (int i = 0; i < PAUSE_STEPS; i++)
- {
- try
- {
- if (orb instanceof OrbFunctional)
- socket = ((OrbFunctional) orb).socketFactory.
- createClientSocket(
- ior.Internet.host, ior.Internet.port);
- else
- socket = new Socket(ior.Internet.host, ior.Internet.port);
- break Open;
- }
- catch (IOException ex)
- {
- try
- {
- // Expecting to free a socket via finaliser.
- System.gc();
- Thread.sleep(pause);
- pause = pause * 2;
- if (pause > PAUSE_MAX)
- pause = PAUSE_MAX;
- }
- catch (InterruptedException iex)
- {
- }
- }
- }
- }
- if (socket == null)
- throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port
- + " in use");
- socket.setKeepAlive(true);
- OutputStream socketOutput = socket.getOutputStream();
- // Write the message header.
- header.write(socketOutput);
- // Write the request header and parameters (if present).
- request_part.buffer.writeTo(socketOutput);
- socketOutput.flush();
- if (!socket.isClosed() && !oneWay)
- {
- MessageHeader response_header = new MessageHeader();
- InputStream socketInput = socket.getInputStream();
- response_header.read(socketInput);
- byte[] r;
- if (orb instanceof OrbFunctional)
- {
- OrbFunctional fo = (OrbFunctional) orb;
- r = response_header.readMessage(socketInput, socket,
- fo.TOUT_WHILE_READING, fo.TOUT_AFTER_RECEIVING);
- }
- else
- r = response_header.readMessage(socketInput, null, 0, 0);
- return new RawReply(orb, response_header, r);
- }
- else
- return EMPTY;
- }
- catch (IOException io_ex)
- {
- COMM_FAILURE m = new COMM_FAILURE("Unable to open a socket at "
- + ior.Internet.host + ":" + ior.Internet.port, 0xC9,
- CompletionStatus.COMPLETED_NO);
- m.initCause(io_ex);
- throw m;
- }
- finally
- {
- try
- {
- if (socket != null && !socket.isClosed())
- {
- socket.setSoTimeout(OrbFunctional.TANDEM_REQUESTS);
- SocketRepository.put_socket(key, socket);
- }
- }
- catch (IOException scx)
- {
- InternalError ierr = new InternalError();
- ierr.initCause(scx);
- throw ierr;
- }
- }
- }
- /** {@inheritDoc} */
- public org.omg.CORBA.Object target()
- {
- return m_target;
- }
- /**
- * Get the used version. Normally, it is better to respond using the same
- * version as it is specified in IOR, but not above the maximal supported
- * version.
- */
- public Version useVersion(Version desired)
- {
- if (desired.until_inclusive(MAX_SUPPORTED.major, MAX_SUPPORTED.minor))
- return desired;
- else
- return MAX_SUPPORTED;
- }
- /**
- * Wait while the response to request, submitted using
- * {@link #send_deferred()} or {@link #invoke()} (from other thread) is
- * returned.
- *
- * FIXME It is possible to rewrite this using Object.wait() and
- * Object.notify(), but be sure to prepare the test as well.
- */
- public synchronized void waitWhileBusy()
- {
- // Waiting constants.
- long wait = 10;
- long increment = 2;
- long max = 5000;
- while (running)
- {
- try
- {
- Thread.sleep(wait);
- if (wait < max)
- wait = wait * increment;
- }
- catch (InterruptedException ex)
- {
- }
- }
- }
- /**
- * Do actual invocation. This method recursively calls itself if the
- * redirection is detected.
- */
- private void p_invoke()
- throws SystemException, ForwardRequest
- {
- RawReply response = submit();
- // If this is a one way message, do not care about the response.
- if (oneWay && response == EMPTY)
- return;
- if (m_rph == null)
- m_rph = response.header.create_reply_header();
- BufferredCdrInput input = response.getStream();
- input.setOrb(orb);
- m_rph.read(input);
- // The stream must be aligned sinve v1.2, but only once.
- boolean align = response.header.version.since_inclusive(1, 2);
- switch (m_rph.reply_status)
- {
- case ReplyHeader.NO_EXCEPTION:
- NamedValue arg;
- // Read return value, if set.
- if (m_result != null)
- {
- if (align)
- {
- input.align(8);
- align = false;
- }
- m_result.value().read_value(input, m_result.value().type());
- }
- // Read returned parameters, if set.
- if (m_args != null)
- for (int i = 0; i < m_args.count(); i++)
- {
- try
- {
- arg = m_args.item(i);
- // Both ARG_INOUT and ARG_OUT have this binary flag set.
- if ((arg.flags() & ARG_OUT.value) != 0)
- {
- if (align)
- {
- input.align(8);
- align = false;
- }
- arg.value().read_value(input, arg.value().type());
- }
- }
- catch (Bounds ex)
- {
- Unexpected.error(ex);
- }
- }
- if (m_interceptor != null)
- m_interceptor.receive_reply(m_info);
- break;
- case ReplyHeader.SYSTEM_EXCEPTION:
- if (align)
- {
- input.align(8);
- align = false;
- }
- readExceptionId(input);
- m_sys_ex = ObjectCreator.readSystemException(input,
- m_rph.service_context);
- m_environment.exception(m_sys_ex);
- if (m_interceptor != null)
- m_interceptor.receive_exception(m_info);
- throw m_sys_ex;
- case ReplyHeader.USER_EXCEPTION:
- if (align)
- {
- input.align(8);
- align = false;
- }
- readExceptionId(input);
- // Prepare an Any that will hold the exception.
- gnuAny exc = new gnuAny();
- exc.setOrb(orb);
- exc.insert_Streamable(new StreamHolder(input));
- UnknownUserException unuex = new UnknownUserException(exc);
- m_environment.exception(unuex);
- if (m_interceptor != null)
- m_interceptor.receive_exception(m_info);
- break;
- case ReplyHeader.LOCATION_FORWARD_PERM:
- 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)
- {
- new MARSHAL("Cant read forwarding info", 5103,
- CompletionStatus.COMPLETED_NO);
- }
- setIor(forwarded);
- m_forward_ior = forwarded;
- if (m_interceptor != null)
- m_interceptor.receive_other(m_info);
- // Repeat with the forwarded information.
- p_invoke();
- return;
- default:
- throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status,
- CompletionStatus.COMPLETED_NO);
- }
- }
- /**
- * Read exception id without changing the stream pointer position.
- */
- void readExceptionId(BufferredCdrInput input)
- {
- input.mark(2048);
- m_exception_id = input.read_string();
- input.reset();
- }
- /**
- * Write the operation parameters.
- *
- * @param header the message header
- * @param request_part the stream to write parameters into
- *
- * @throws MARSHAL if the attempt to write the parameters has failde.
- */
- protected void write_parameter_buffer(MessageHeader header,
- BufferedCdrOutput request_part
- ) throws MARSHAL
- {
- try
- {
- if (header.version.since_inclusive(1, 2))
- {
- request_part.align(8);
- }
- m_parameter_buffer.buffer.writeTo(request_part);
- }
- catch (IOException ex)
- {
- MARSHAL m = new MARSHAL("Unable to write method arguments to CDR output.");
- m.minor = Minor.CDR;
- throw m;
- }
- }
- /**
- * Write the operation parameters.
- *
- * @param header the message header
- * @param request_part the stream to write parameters into
- *
- * @throws MARSHAL if the attempt to write the parameters has failde.
- */
- protected void write_parameters(MessageHeader header,
- BufferedCdrOutput request_part
- ) throws MARSHAL
- {
- // Align after 1.2, but only once.
- boolean align = header.version.since_inclusive(1, 2);
- NamedValue para;
- try
- {
- // Write parameters now.
- for (int i = 0; i < m_args.count(); i++)
- {
- para = m_args.item(i);
- // This bit is set both for ARG_IN and ARG_INOUT
- if ((para.flags() & ARG_IN.value) != 0)
- {
- if (align)
- {
- request_part.align(8);
- align = false;
- }
- para.value().write_value(request_part);
- }
- }
- }
- catch (Bounds ex)
- {
- InternalError ierr = new InternalError();
- ierr.initCause(ex);
- throw ierr;
- }
- }
- /* **************Implementation of the request info operations. ***** */
- /**
- * Add context to request.
- */
- public void add_request_service_context(ServiceContext service_context,
- boolean replace
- )
- {
- m_rqh.addContext(service_context, replace);
- }
- /**
- * Get the Internet profile as an effective profile.
- */
- public TaggedProfile effective_profile()
- {
- BufferedCdrOutput buf = new BufferedCdrOutput(512);
- buf.setOrb(orb);
- ior.Internet.write(buf);
- TaggedProfile p = new TaggedProfile();
- p.tag = TAG_INTERNET_IOP.value;
- p.profile_data = buf.buffer.toByteArray();
- return p;
- }
- /**
- * Return either target or forwarded targed.
- */
- public org.omg.CORBA.Object effective_target()
- {
- return new IorObject(orb, ior);
- }
- /**
- * Get effective component with the give id from the Internet profile.
- */
- public TaggedComponent get_effective_component(int id)
- throws BAD_PARAM
- {
- if (id == TAG_CODE_SETS.value)
- {
- // Codesets are encoded separately.
- BufferedCdrOutput buf = new BufferedCdrOutput(512);
- buf.setOrb(orb);
- ior.Internet.CodeSets.write(buf);
- TaggedComponent t = new TaggedComponent();
- t.tag = TAG_CODE_SETS.value;
- t.component_data = buf.buffer.toByteArray();
- return t;
- }
- else
- {
- for (int i = 0; i < ior.Internet.components.size(); i++)
- {
- TaggedComponent c =
- (TaggedComponent) ior.Internet.components.get(i);
- if (c.tag == id)
- return c;
- }
- }
- throw new BAD_PARAM("No component " + id + " in the Internet profile", 28,
- CompletionStatus.COMPLETED_MAYBE
- );
- }
- /**
- * Get all components with the given id from the internet profile.
- */
- public TaggedComponent[] get_effective_components(int id)
- throws BAD_PARAM
- {
- if (id == TAG_CODE_SETS.value)
- return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) };
- else
- {
- ArrayList components = new ArrayList(ior.Internet.components.size());
- for (int i = 0; i < ior.Internet.components.size(); i++)
- {
- TaggedComponent c =
- (TaggedComponent) ior.Internet.components.get(i);
- if (c.tag == id)
- components.add(c);
- }
- if (components.size() == 0)
- throw new BAD_PARAM("No component " + id +
- " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE
- );
- else
- {
- TaggedComponent[] t = new TaggedComponent[ components.size() ];
- for (int i = 0; i < t.length; i++)
- t [ i ] = (TaggedComponent) components.get(i);
- return t;
- }
- }
- }
- /**
- * This should be not implemented up till jdk 1.5 inclusive.
- */
- public Policy get_request_policy(int type) throws INV_POLICY
- {
- throw new NO_IMPLEMENT();
- }
- /** @inheritDoc */
- public String received_exception_id()
- {
- return m_exception_id;
- }
- /** @inheritDoc */
- public Any received_exception()
- {
- if (m_exception_id == null)
- return null;
- if (m_sys_ex != null)
- {
- Any a = orb.create_any();
- ObjectCreator.insertSysException(a, m_sys_ex);
- return a;
- }
- Exception mex = m_environment.exception();
- UnknownUserException ex = (UnknownUserException) mex;
- if (ex == null)
- return null;
- else
- return ex.except;
- }
- /**
- * Return the forwarded reference, null if none.
- */
- public org.omg.CORBA.Object forward_reference()
- {
- if (m_forwarding_target != null)
- return m_forwarding_target;
- if (m_forward_ior != null)
- return new IorObject(orb, m_forward_ior);
- else
- return null;
- }
- /**
- * Get the slot from the slot array inside this request.
- */
- public Any get_slot(int id) throws InvalidSlot
- {
- try
- {
- return m_slots [ id ];
- }
- catch (Exception e)
- {
- throw new InvalidSlot("slot id " + id + ":" + e);
- }
- }
- /**
- * Get the reply status.
- */
- public short reply_status()
- {
- if (m_rph == null)
- throw new BAD_INV_ORDER("Request not yet sent", 14,
- CompletionStatus.COMPLETED_NO
- );
- return (short) m_rph.reply_status;
- }
- /**
- * Get the request id.
- */
- public int request_id()
- {
- return m_rqh.request_id;
- }
- /**
- * Return true if the response is expected.
- */
- public boolean response_expected()
- {
- return !oneWay;
- }
- /**
- * Determines how far the request shall progress before control is returned to
- * the client. However up till JDK 1.5 inclusive this method always returns
- * SYNC_WITH_TRANSPORT.
- *
- * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
- *
- * @specnote as defined in the Suns 1.5 JDK API.
- */
- public short sync_scope()
- {
- return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
- }
- /** @inheritDoc */
- public ServiceContext get_request_service_context(int ctx_name)
- throws BAD_PARAM
- {
- return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
- m_rqh.service_context
- );
- }
- /** @inheritDoc */
- public ServiceContext get_reply_service_context(int ctx_name)
- throws BAD_PARAM
- {
- if (m_rph == null)
- throw new BAD_INV_ORDER("Reply context not yet available");
- return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
- m_rph.service_context
- );
- }
- /** @inheritDoc */
- public String[] operation_context()
- {
- return ice_contexts();
- }
- /**
- * Get contexts as required by interceptor.
- */
- public String[] ice_contexts()
- {
- if (m_context_list == null)
- return new String[ 0 ];
- else
- {
- try
- {
- String[] cn = new String[ m_context_list.count() ];
- for (int i = 0; i < cn.length; i++)
- cn [ i ] = m_context_list.item(i);
- return cn;
- }
- catch (Bounds e)
- {
- throw new Unexpected(e);
- }
- }
- }
- /**
- * Check if the call is done via DII.
- */
- public void checkDii()
- {
- if (m_parameter_buffer != null)
- throw new NO_RESOURCES("The invocation method provides " +
- "no access to this resource. DII call required.", 1,
- CompletionStatus.COMPLETED_MAYBE
- );
- }
- }
|