KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > protocol > CorbaMessageMediatorImpl


1 /*
2  * @(#)CorbaMessageMediatorImpl.java 1.98 04/06/21
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.protocol;
9
10 import java.io.ByteArrayOutputStream JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.PrintWriter JavaDoc;
13 import java.nio.ByteBuffer JavaDoc;
14 import java.nio.channels.SelectionKey JavaDoc;
15 import java.util.EmptyStackException JavaDoc;
16 import java.util.Iterator JavaDoc;
17
18 import org.omg.CORBA.Any JavaDoc;
19 import org.omg.CORBA.CompletionStatus JavaDoc;
20 import org.omg.CORBA.ExceptionList JavaDoc;
21 import org.omg.CORBA.INTERNAL JavaDoc;
22 import org.omg.CORBA.Principal JavaDoc;
23 import org.omg.CORBA.SystemException JavaDoc;
24 import org.omg.CORBA.TypeCode JavaDoc;
25 import org.omg.CORBA.UnknownUserException JavaDoc;
26 import org.omg.CORBA.UNKNOWN JavaDoc;
27 import org.omg.CORBA.portable.ResponseHandler JavaDoc;
28 import org.omg.CORBA.portable.UnknownException JavaDoc;
29 import org.omg.CORBA_2_3.portable.InputStream JavaDoc;
30 import org.omg.CORBA_2_3.portable.OutputStream JavaDoc;
31 import org.omg.IOP.ExceptionDetailMessage JavaDoc;
32 import org.omg.IOP.TAG_RMI_CUSTOM_MAX_STREAM_FORMAT JavaDoc;
33
34 import com.sun.corba.se.pept.broker.Broker;
35 import com.sun.corba.se.pept.encoding.InputObject;
36 import com.sun.corba.se.pept.encoding.OutputObject;
37 import com.sun.corba.se.pept.protocol.MessageMediator;
38 import com.sun.corba.se.pept.protocol.ProtocolHandler;
39 import com.sun.corba.se.pept.transport.ByteBufferPool;
40 import com.sun.corba.se.pept.transport.Connection;
41 import com.sun.corba.se.pept.transport.ContactInfo;
42 import com.sun.corba.se.pept.transport.EventHandler;
43
44 import com.sun.corba.se.spi.ior.IOR;
45 import com.sun.corba.se.spi.ior.ObjectKey;
46 import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
47 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
48 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
49 import com.sun.corba.se.spi.ior.iiop.IIOPProfile;
50 import com.sun.corba.se.spi.ior.iiop.MaxStreamFormatVersionComponent;
51 import com.sun.corba.se.spi.oa.OAInvocationInfo;
52 import com.sun.corba.se.spi.oa.ObjectAdapter;
53 import com.sun.corba.se.spi.orb.ORB;
54 import com.sun.corba.se.spi.orb.ORBVersionFactory;
55 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
56 import com.sun.corba.se.spi.protocol.CorbaProtocolHandler;
57 import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
58 import com.sun.corba.se.spi.protocol.ForwardException;
59 import com.sun.corba.se.spi.transport.CorbaConnection;
60 import com.sun.corba.se.spi.transport.CorbaContactInfo;
61 import com.sun.corba.se.spi.transport.CorbaResponseWaitingRoom;
62 import com.sun.corba.se.spi.logging.CORBALogDomains;
63
64 import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
65 import com.sun.corba.se.spi.servicecontext.ServiceContexts;
66 import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
67 import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
68 import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
69 import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
70
71 import com.sun.corba.se.impl.corba.RequestImpl;
72 import com.sun.corba.se.impl.encoding.BufferManagerFactory;
73 import com.sun.corba.se.impl.encoding.BufferManagerReadStream;
74 import com.sun.corba.se.impl.encoding.CDRInputObject;
75 import com.sun.corba.se.impl.encoding.CDROutputObject;
76 import com.sun.corba.se.impl.encoding.EncapsOutputStream;
77 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
78 import com.sun.corba.se.impl.logging.InterceptorsSystemException;
79 import com.sun.corba.se.impl.orbutil.ORBConstants;
80 import com.sun.corba.se.impl.orbutil.ORBUtility;
81 import com.sun.corba.se.impl.ior.iiop.JavaSerializationComponent;
82 import com.sun.corba.se.impl.protocol.AddressingDispositionException;
83 import com.sun.corba.se.impl.protocol.RequestCanceledException;
84 import com.sun.corba.se.impl.protocol.giopmsgheaders.AddressingDispositionHelper;
85 import com.sun.corba.se.impl.protocol.giopmsgheaders.CancelRequestMessage;
86 import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_1;
87 import com.sun.corba.se.impl.protocol.giopmsgheaders.FragmentMessage_1_2;
88 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage;
89 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_0;
90 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_1;
91 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateRequestMessage_1_2;
92 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyOrReplyMessage;
93 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage;
94 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_0;
95 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_1;
96 import com.sun.corba.se.impl.protocol.giopmsgheaders.LocateReplyMessage_1_2;
97 import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
98 import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
99 import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageHandler;
100 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
101 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_0;
102 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_1;
103 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage_1_2;
104 import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage;
105 import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_0 ;
106 import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_1 ;
107 import com.sun.corba.se.impl.protocol.giopmsgheaders.RequestMessage_1_2 ;
108
109 // REVISIT: make sure no memory leaks in client/server request/reply maps.
110
// REVISIT: normalize requestHeader, replyHeader, messageHeader.
111

112 /**
113  * @author Harold Carr
114  */

115 public class CorbaMessageMediatorImpl
116     implements
117     CorbaMessageMediator,
118     CorbaProtocolHandler,
119     MessageHandler
120 {
121     protected ORB orb;
122     protected ORBUtilSystemException wrapper ;
123     protected InterceptorsSystemException interceptorWrapper ;
124     protected CorbaContactInfo contactInfo;
125     protected CorbaConnection connection;
126     protected short addrDisposition;
127     protected CDROutputObject outputObject;
128     protected CDRInputObject inputObject;
129     protected Message JavaDoc messageHeader;
130     protected RequestMessage requestHeader;
131     protected LocateReplyOrReplyMessage replyHeader;
132     protected String JavaDoc replyExceptionDetailMessage;
133     protected IOR replyIOR;
134     protected Integer JavaDoc requestIdInteger;
135     protected Message JavaDoc dispatchHeader;
136     protected ByteBuffer JavaDoc dispatchByteBuffer;
137     protected byte streamFormatVersion;
138     protected boolean streamFormatVersionSet = false;
139
140     protected org.omg.CORBA.Request JavaDoc diiRequest;
141
142     protected boolean cancelRequestAlreadySent = false;
143
144     protected ProtocolHandler protocolHandler;
145     protected boolean _executeReturnServantInResponseConstructor = false;
146     protected boolean _executeRemoveThreadInfoInResponseConstructor = false;
147     protected boolean _executePIInResponseConstructor = false;
148
149     //
150
// Client-side constructor.
151
//
152

153     public CorbaMessageMediatorImpl(ORB orb,
154                     ContactInfo contactInfo,
155                     Connection connection,
156                     GIOPVersion giopVersion,
157                     IOR ior,
158                     int requestId,
159                     short addrDisposition,
160                     String JavaDoc operationName,
161                     boolean isOneWay)
162     {
163     this( orb, connection ) ;
164         
165     this.contactInfo = (CorbaContactInfo) contactInfo;
166     this.addrDisposition = addrDisposition;
167
168     streamFormatVersion =
169         getStreamFormatVersionForThisRequest(
170             ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
171         giopVersion);
172     streamFormatVersionSet = true;
173
174     requestHeader = (RequestMessage) MessageBase.createRequest(
175             this.orb,
176         giopVersion,
177         ORBUtility.getEncodingVersion(orb, ior),
178         requestId,
179         !isOneWay,
180         ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR(),
181         this.addrDisposition,
182         operationName,
183         new ServiceContexts(orb),
184         null);
185     }
186
187     //
188
// Acceptor constructor.
189
//
190

191     public CorbaMessageMediatorImpl(ORB orb,
192                     Connection connection)
193     {
194     this.orb = orb;
195     this.connection = (CorbaConnection)connection;
196     this.wrapper = ORBUtilSystemException.get( orb,
197         CORBALogDomains.RPC_PROTOCOL ) ;
198     this.interceptorWrapper = InterceptorsSystemException.get( orb,
199         CORBALogDomains.RPC_PROTOCOL ) ;
200     }
201
202     //
203
// Dispatcher constructor.
204
//
205

206     // Note: in some cases (e.g., a reply message) this message
207
// mediator will only be used for dispatch. Then the original
208
// request side mediator will take over.
209
public CorbaMessageMediatorImpl(ORB orb,
210                     CorbaConnection connection,
211                     Message JavaDoc dispatchHeader,
212                     ByteBuffer JavaDoc byteBuffer)
213     {
214     this( orb, connection ) ;
215     this.dispatchHeader = dispatchHeader;
216         this.dispatchByteBuffer = byteBuffer;
217     }
218
219     ////////////////////////////////////////////////////
220
//
221
// MessageMediator
222
//
223

224     public Broker getBroker()
225     {
226     return orb;
227     }
228
229     public ContactInfo getContactInfo()
230     {
231     return contactInfo;
232     }
233
234     public Connection getConnection()
235     {
236     return connection;
237     }
238
239     public void initializeMessage()
240     {
241     getRequestHeader().write(outputObject);
242     }
243
244     public void finishSendingRequest()
245     {
246     // REVISIT: probably move logic in outputObject to here.
247
outputObject.finishSendingMessage();
248     }
249
250     public InputObject waitForResponse()
251     {
252     if (getRequestHeader().isResponseExpected()) {
253         return connection.waitForResponse(this);
254     }
255     return null;
256     }
257
258     public void setOutputObject(OutputObject outputObject)
259     {
260     this.outputObject = (CDROutputObject) outputObject;
261     }
262
263     public OutputObject getOutputObject()
264     {
265     return outputObject;
266     }
267
268     public void setInputObject(InputObject inputObject)
269     {
270     this.inputObject = (CDRInputObject) inputObject;
271     }
272
273     public InputObject getInputObject()
274     {
275     return inputObject;
276     }
277
278     ////////////////////////////////////////////////////
279
//
280
// CorbaMessageMediator
281
//
282

283     public void setReplyHeader(LocateReplyOrReplyMessage header)
284     {
285     this.replyHeader = header;
286     this.replyIOR = header.getIOR(); // REVISIT - need separate field?
287
}
288
289     public LocateReplyMessage getLocateReplyHeader()
290     {
291     return (LocateReplyMessage) replyHeader;
292     }
293     
294     public ReplyMessage getReplyHeader()
295     {
296     return (ReplyMessage) replyHeader;
297     }
298
299     public void setReplyExceptionDetailMessage(String JavaDoc message)
300     {
301     replyExceptionDetailMessage = message;
302     }
303     
304     public RequestMessage getRequestHeader()
305     {
306     return requestHeader;
307     }
308     
309     public GIOPVersion getGIOPVersion()
310     {
311     if (messageHeader != null) {
312         return messageHeader.getGIOPVersion();
313     }
314     return getRequestHeader().getGIOPVersion();
315     }
316
317     public byte getEncodingVersion() {
318     if (messageHeader != null) {
319         return messageHeader.getEncodingVersion();
320     }
321     return getRequestHeader().getEncodingVersion();
322     }
323
324     public int getRequestId()
325     {
326     return getRequestHeader().getRequestId();
327     }
328
329     public Integer JavaDoc getRequestIdInteger()
330     {
331     if (requestIdInteger == null) {
332         requestIdInteger = new Integer JavaDoc(getRequestHeader().getRequestId());
333     }
334     return requestIdInteger;
335     }
336
337     public boolean isOneWay()
338     {
339     return ! getRequestHeader().isResponseExpected();
340     }
341
342     public short getAddrDisposition()
343     {
344     return addrDisposition;
345     }
346
347     public String JavaDoc getOperationName()
348     {
349     return getRequestHeader().getOperation();
350     }
351
352     public ServiceContexts getRequestServiceContexts()
353     {
354     return getRequestHeader().getServiceContexts();
355     }
356
357     public ServiceContexts getReplyServiceContexts()
358     {
359     return getReplyHeader().getServiceContexts();
360     }
361
362     public void sendCancelRequestIfFinalFragmentNotSent()
363     {
364     if ((!sentFullMessage()) && sentFragment() &&
365         (!cancelRequestAlreadySent))
366         {
367         try {
368         if (orb.subcontractDebugFlag) {
369             dprint(".sendCancelRequestIfFinalFragmentNotSent->: "
370                + opAndId(this));
371         }
372         connection.sendCancelRequestWithLock(getGIOPVersion(),
373                              getRequestId());
374         // Case: first a location forward, then a marshaling
375
// exception (e.g., non-serializable object). Only
376
// send cancel once.
377
cancelRequestAlreadySent = true;
378         } catch (IOException JavaDoc e) {
379         if (orb.subcontractDebugFlag) {
380             dprint(".sendCancelRequestIfFinalFragmentNotSent: !ERROR : " + opAndId(this),
381                e);
382         }
383
384         // REVISIT: we could attempt to send a final incomplete
385
// fragment in this case.
386
throw interceptorWrapper.ioexceptionDuringCancelRequest(
387             CompletionStatus.COMPLETED_MAYBE, e );
388         } finally {
389         if (orb.subcontractDebugFlag) {
390             dprint(".sendCancelRequestIfFinalFragmentNotSent<-: "
391                + opAndId(this));
392         }
393         }
394     }
395     }
396
397     public boolean sentFullMessage()
398     {
399     return outputObject.getBufferManager().sentFullMessage();
400     }
401
402     public boolean sentFragment()
403     {
404     return outputObject.getBufferManager().sentFragment();
405     }
406
407     public void setDIIInfo(org.omg.CORBA.Request JavaDoc diiRequest)
408     {
409     this.diiRequest = diiRequest;
410     }
411
412     public boolean isDIIRequest()
413     {
414     return diiRequest != null;
415     }
416
417     public Exception JavaDoc unmarshalDIIUserException(String JavaDoc repoId, InputStream JavaDoc is)
418     {
419     if (! isDIIRequest()) {
420         return null;
421     }
422
423     ExceptionList JavaDoc _exceptions = diiRequest.exceptions();
424
425     try {
426         // Find the typecode for the exception
427
for (int i=0; i<_exceptions.count() ; i++) {
428         TypeCode JavaDoc tc = _exceptions.item(i);
429         if ( tc.id().equals(repoId) ) {
430             // Since we dont have the actual user exception
431
// class, the spec says we have to create an
432
// UnknownUserException and put it in the
433
// environment.
434
Any JavaDoc eany = orb.create_any();
435             eany.read_value(is, (TypeCode JavaDoc)tc);
436
437             return new UnknownUserException JavaDoc(eany);
438         }
439         }
440     } catch (Exception JavaDoc b) {
441         throw wrapper.unexpectedDiiException(b);
442     }
443
444     // must be a truly unknown exception
445
return wrapper.unknownCorbaExc( CompletionStatus.COMPLETED_MAYBE);
446     }
447
448     public void setDIIException(Exception JavaDoc exception)
449     {
450     diiRequest.env().exception(exception);
451     }
452
453     public void handleDIIReply(InputStream JavaDoc inputStream)
454     {
455     if (! isDIIRequest()) {
456         return;
457     }
458     ((RequestImpl)diiRequest).unmarshalReply(inputStream);
459     }
460
461     public Message JavaDoc getDispatchHeader()
462     {
463     return dispatchHeader;
464     }
465
466     public void setDispatchHeader(Message JavaDoc msg)
467     {
468     dispatchHeader = msg;
469     }
470
471     public ByteBuffer JavaDoc getDispatchBuffer()
472     {
473     return dispatchByteBuffer;
474     }
475
476     public void setDispatchBuffer(ByteBuffer JavaDoc byteBuffer)
477     {
478     dispatchByteBuffer = byteBuffer;
479     }
480
481     public int getThreadPoolToUse() {
482     int poolToUse = 0;
483     Message JavaDoc msg = getDispatchHeader();
484     // A null msg should never happen. But, we'll be
485
// defensive just in case.
486
if (msg != null) {
487         poolToUse = msg.getThreadPoolToUse();
488     }
489     return poolToUse;
490     }
491
492     public byte getStreamFormatVersion()
493     {
494     // REVISIT: ContactInfo/Acceptor output object factories
495
// just use this. Maybe need to distinguish:
496
// createOutputObjectForRequest
497
// createOutputObjectForReply
498
// then do getStreamFormatVersionForRequest/ForReply here.
499
if (streamFormatVersionSet) {
500         return streamFormatVersion;
501     }
502     return getStreamFormatVersionForReply();
503     }
504
505     /**
506      * If the RMI-IIOP maximum stream format version service context
507      * is present, it indicates the maximum stream format version we
508      * could use for the reply. If it isn't present, the default is
509      * 2 for GIOP 1.3 or greater, 1 for lower.
510      *
511      * This is only sent on requests. Clients can find out the
512      * server's maximum by looking for a tagged component in the IOR.
513      */

514     public byte getStreamFormatVersionForReply() {
515
516     // NOTE: The request service contexts may indicate the max.
517
ServiceContexts svc = getRequestServiceContexts();
518
519     MaxStreamFormatVersionServiceContext msfvsc
520         = (MaxStreamFormatVersionServiceContext)svc.get(
521         MaxStreamFormatVersionServiceContext.SERVICE_CONTEXT_ID);
522         
523     if (msfvsc != null) {
524             byte localMaxVersion = ORBUtility.getMaxStreamFormatVersion();
525             byte remoteMaxVersion = msfvsc.getMaximumStreamFormatVersion();
526
527             return (byte)Math.min(localMaxVersion, remoteMaxVersion);
528         } else {
529             // Defaults to 1 for GIOP 1.2 or less, 2 for
530
// GIOP 1.3 or higher.
531
if (getGIOPVersion().lessThan(GIOPVersion.V1_3))
532                 return ORBConstants.STREAM_FORMAT_VERSION_1;
533             else
534                 return ORBConstants.STREAM_FORMAT_VERSION_2;
535         }
536     }
537
538     public boolean isSystemExceptionReply()
539     {
540     return replyHeader.getReplyStatus() == ReplyMessage.SYSTEM_EXCEPTION;
541     }
542
543     public boolean isUserExceptionReply()
544     {
545     return replyHeader.getReplyStatus() == ReplyMessage.USER_EXCEPTION;
546     }
547
548     public boolean isLocationForwardReply()
549     {
550     return ( (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD) ||
551          (replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD_PERM) );
552     //return replyHeader.getReplyStatus() == ReplyMessage.LOCATION_FORWARD;
553
}
554     
555     public boolean isDifferentAddrDispositionRequestedReply()
556     {
557     return replyHeader.getReplyStatus() == ReplyMessage.NEEDS_ADDRESSING_MODE;
558     }
559     
560     public short getAddrDispositionReply()
561     {
562     return replyHeader.getAddrDisposition();
563     }
564     
565     public IOR getForwardedIOR()
566     {
567     return replyHeader.getIOR();
568     }
569
570     public SystemException JavaDoc getSystemExceptionReply()
571     {
572     return replyHeader.getSystemException(replyExceptionDetailMessage);
573     }
574
575     ////////////////////////////////////////////////////
576
//
577
// Used by server side.
578
//
579

580     public ObjectKey getObjectKey()
581     {
582     return getRequestHeader().getObjectKey();
583     }
584
585     public void setProtocolHandler(CorbaProtocolHandler protocolHandler)
586     {
587     throw wrapper.methodShouldNotBeCalled() ;
588     }
589
590     public CorbaProtocolHandler getProtocolHandler()
591     {
592     // REVISIT: should look up in orb registry.
593
return this;
594     }
595
596     ////////////////////////////////////////////////////
597
//
598
// ResponseHandler
599
//
600

601     public org.omg.CORBA.portable.OutputStream JavaDoc createReply()
602     {
603     // Note: relies on side-effect of setting mediator output field.
604
// REVISIT - cast - need interface
605
getProtocolHandler().createResponse(this, (ServiceContexts) null);
606     return (OutputStream JavaDoc) getOutputObject();
607     }
608
609     public org.omg.CORBA.portable.OutputStream JavaDoc createExceptionReply()
610     {
611     // Note: relies on side-effect of setting mediator output field.
612
// REVISIT - cast - need interface
613
getProtocolHandler().createUserExceptionResponse(this, (ServiceContexts) null);
614     return (OutputStream JavaDoc) getOutputObject();
615     }
616
617     public boolean executeReturnServantInResponseConstructor()
618     {
619     return _executeReturnServantInResponseConstructor;
620
621     }
622
623     public void setExecuteReturnServantInResponseConstructor(boolean b)
624     {
625     _executeReturnServantInResponseConstructor = b;
626     }
627
628     public boolean executeRemoveThreadInfoInResponseConstructor()
629     {
630     return _executeRemoveThreadInfoInResponseConstructor;
631     }
632
633     public void setExecuteRemoveThreadInfoInResponseConstructor(boolean b)
634     {
635     _executeRemoveThreadInfoInResponseConstructor = b;
636     }
637
638     public boolean executePIInResponseConstructor()
639     {
640     return _executePIInResponseConstructor;
641     }
642
643     public void setExecutePIInResponseConstructor( boolean b )
644     {
645     _executePIInResponseConstructor = b;
646     }
647
648     private byte getStreamFormatVersionForThisRequest(IOR ior,
649                                                       GIOPVersion giopVersion)
650     {
651
652         byte localMaxVersion
653             = ORBUtility.getMaxStreamFormatVersion();
654
655     IOR effectiveTargetIOR =
656         ((CorbaContactInfo)this.contactInfo).getEffectiveTargetIOR();
657         IIOPProfileTemplate temp =
658         (IIOPProfileTemplate)effectiveTargetIOR.getProfile().getTaggedProfileTemplate();
659         Iterator JavaDoc iter = temp.iteratorById(TAG_RMI_CUSTOM_MAX_STREAM_FORMAT.value);
660         if (!iter.hasNext()) {
661             // Didn't have the max stream format version tagged
662
// component.
663
if (giopVersion.lessThan(GIOPVersion.V1_3))
664                 return ORBConstants.STREAM_FORMAT_VERSION_1;
665             else
666                 return ORBConstants.STREAM_FORMAT_VERSION_2;
667         }
668
669         byte remoteMaxVersion
670             = ((MaxStreamFormatVersionComponent)iter.next()).getMaxStreamFormatVersion();
671
672         return (byte)Math.min(localMaxVersion, remoteMaxVersion);
673     }
674
675     ////////////////////////////////////////////////////////////////////////
676
////////////////////////////////////////////////////////////////////////
677
////////////////////////////////////////////////////////////////////////
678

679     // REVISIT - This could be a separate implementation object looked
680
// up in a registry. However it needs some state in the message
681
// mediator so combine for now.
682

683
684     protected boolean isThreadDone = false;
685
686     ////////////////////////////////////////////////////
687
//
688
// pept.protocol.ProtocolHandler
689
//
690

691     public boolean handleRequest(MessageMediator messageMediator)
692     {
693     try {
694         dispatchHeader.callback(this);
695     } catch (IOException JavaDoc e) {
696         // REVISIT - this should be handled internally.
697
;
698     }
699     return isThreadDone;
700     }
701
702     ////////////////////////////////////////////////////
703
//
704
// iiop.messages.MessageHandler
705
//
706

707     private void setWorkThenPoolOrResumeSelect(Message JavaDoc header)
708     {
709     if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
710         resumeSelect(header);
711     } else {
712         // Leader/Follower when using reader thread.
713
// When this thread is done working it will go back in pool.
714

715         isThreadDone = true;
716
717         // First unregister current registration.
718
orb.getTransportManager().getSelector(0)
719         .unregisterForEvent(getConnection().getEventHandler());
720         // Have another thread become the reader.
721
orb.getTransportManager().getSelector(0)
722         .registerForEvent(getConnection().getEventHandler());
723     }
724     }
725
726     private void setWorkThenReadOrResumeSelect(Message JavaDoc header)
727     {
728     if (getConnection().getEventHandler().shouldUseSelectThreadToWait()) {
729         resumeSelect(header);
730     } else {
731         // When using reader thread then wen this thread is
732
// done working it will continue reading.
733
isThreadDone = false;
734     }
735     }
736
737     private void resumeSelect(Message JavaDoc header)
738     {
739     // NOTE: VERY IMPORTANT:
740
// Only participate in select after getting to the point
741
// that proper serialization of fragments is ensured.
742

743     if (transportDebug()) {
744         dprint(".resumeSelect:->");
745         // REVISIT: not-OO:
746
String JavaDoc requestId = "?";
747         if (header instanceof RequestMessage) {
748         requestId =
749             new Integer JavaDoc(((RequestMessage)header)
750                 .getRequestId()).toString();
751         } else if (header instanceof ReplyMessage) {
752         requestId =
753             new Integer JavaDoc(((ReplyMessage)header)
754                 .getRequestId()).toString();
755         } else if (header instanceof FragmentMessage_1_2) {
756         requestId =
757             new Integer JavaDoc(((FragmentMessage_1_2)header)
758                 .getRequestId()).toString();
759         }
760         dprint(".resumeSelect: id/"
761            + requestId
762            + " " + getConnection()
763            );
764
765     }
766
767     // IMPORTANT: To avoid bug (4953599), we force the Thread that does the NIO select
768
// to also do the enable/disable of Ops using SelectionKey.interestOps(Ops of Interest).
769
// Otherwise, the SelectionKey.interestOps(Ops of Interest) may block indefinitely in
770
// this thread.
771
EventHandler eventHandler = getConnection().getEventHandler();
772     orb.getTransportManager().getSelector(0).registerInterestOps(eventHandler);
773
774     if (transportDebug()) {
775         dprint(".resumeSelect:<-");
776     }
777     }
778
779     private void setInputObject()
780     {
781     // REVISIT: refactor createInputObject (and createMessageMediator)
782
// into base PlugInFactory. Get via connection (either ContactInfo
783
// or Acceptor).
784
if (getConnection().getContactInfo() != null) {
785         inputObject = (CDRInputObject)
786         getConnection().getContactInfo()
787         .createInputObject(orb, this);
788     } else if (getConnection().getAcceptor() != null) {
789         inputObject = (CDRInputObject)
790         getConnection().getAcceptor()
791         .createInputObject(orb, this);
792     } else {
793         throw new RuntimeException JavaDoc("CorbaMessageMediatorImpl.setInputObject");
794     }
795     inputObject.setMessageMediator(this);
796     setInputObject(inputObject);
797     }
798
799     private void signalResponseReceived()
800     {
801     // This will end up using the MessageMediator associated with
802
// the original request instead of the current mediator (which
803
// need to be constructed to hold the dispatchBuffer and connection).
804
connection.getResponseWaitingRoom()
805         .responseReceived((InputObject)inputObject);
806     }
807
808     // This handles message types for which we don't create classes.
809
public void handleInput(Message JavaDoc header) throws IOException JavaDoc
810     {
811     try {
812         messageHeader = header;
813
814         if (transportDebug())
815         dprint(".handleInput->: "
816                + MessageBase.typeToString(header.getType()));
817
818         setWorkThenReadOrResumeSelect(header);
819
820         switch(header.getType())
821             {
822             case Message.GIOPCloseConnection:
823         if (transportDebug()) {
824             dprint(".handleInput: CloseConnection: purging");
825         }
826                 connection.purgeCalls(wrapper.connectionRebind(), true, false);
827                 break;
828             case Message.GIOPMessageError:
829         if (transportDebug()) {
830             dprint(".handleInput: MessageError: purging");
831         }
832                 connection.purgeCalls(wrapper.recvMsgError(), true, false);
833                 break;
834             default:
835         if (transportDebug()) {
836             dprint(".handleInput: ERROR: "
837                + MessageBase.typeToString(header.getType()));
838         }
839         throw wrapper.badGiopRequestType() ;
840         }
841             releaseByteBufferToPool();
842     } finally {
843         if (transportDebug()) {
844         dprint(".handleInput<-: "
845                + MessageBase.typeToString(header.getType()));
846         }
847     }
848     }
849
850     public void handleInput(RequestMessage_1_0 header) throws IOException JavaDoc
851     {
852     try {
853         if (transportDebug()) dprint(".REQUEST 1.0->: " + header);
854         try {
855         messageHeader = requestHeader = (RequestMessage) header;
856         setInputObject();
857         } finally {
858         setWorkThenPoolOrResumeSelect(header);
859         }
860         getProtocolHandler().handleRequest(header, this);
861     } catch (Throwable JavaDoc t) {
862         if (transportDebug())
863         dprint(".REQUEST 1.0: !!ERROR!!: " + header, t);
864         // Mask the exception from thread.;
865
} finally {
866         if (transportDebug()) dprint(".REQUEST 1.0<-: " + header);
867     }
868     }
869     
870     public void handleInput(RequestMessage_1_1 header) throws IOException JavaDoc
871     {
872     try {
873         if (transportDebug()) dprint(".REQUEST 1.1->: " + header);
874         try {
875         messageHeader = requestHeader = (RequestMessage) header;
876         setInputObject();
877         connection.serverRequest_1_1_Put(this);
878         } finally {
879         setWorkThenPoolOrResumeSelect(header);
880         }
881         getProtocolHandler().handleRequest(header, this);
882     } catch (Throwable JavaDoc t) {
883         if (transportDebug())
884         dprint(".REQUEST 1.1: !!ERROR!!: " + header, t);
885         // Mask the exception from thread.;
886
} finally {
887         if (transportDebug()) dprint(".REQUEST 1.1<-: " + header);
888     }
889     }
890
891     // REVISIT: this is identical to 1_0 except for fragment part.
892
public void handleInput(RequestMessage_1_2 header) throws IOException JavaDoc
893     {
894     try {
895         try {
896
897         messageHeader = requestHeader = (RequestMessage) header;
898
899         header.unmarshalRequestID(dispatchByteBuffer);
900         setInputObject();
901
902         if (transportDebug()) dprint(".REQUEST 1.2->: id/"
903                          + header.getRequestId()
904                          + ": "
905                          + header);
906         
907         // NOTE: in the old code this used to be done conditionally:
908
// if (header.moreFragmentsToFollow()).
909
// Now we always put it in. We take it out when
910
// the response is done.
911
// This must happen now so if a header is fragmented the stream
912
// may be found.
913
connection.serverRequestMapPut(header.getRequestId(), this);
914         } finally {
915         // Leader/Follower.
916
// Note: This *MUST* come after putting stream in above map
917
// since the header may be fragmented and you do not want to
918
// start reading again until the map above is set.
919
setWorkThenPoolOrResumeSelect(header);
920         }
921         //inputObject.unmarshalHeader(); // done in subcontract.
922
getProtocolHandler().handleRequest(header, this);
923     } catch (Throwable JavaDoc t) {
924         if (transportDebug()) dprint(".REQUEST 1.2: id/"
925                      + header.getRequestId()
926                      + ": !!ERROR!!: "
927                      + header,
928                      t);
929         // Mask the exception from thread.;
930
} finally {
931         connection.serverRequestMapRemove(header.getRequestId());
932
933         if (transportDebug()) dprint(".REQUEST 1.2<-: id/"
934                      + header.getRequestId()
935                      + ": "
936                      + header);
937     }
938     }
939
940     public void handleInput(ReplyMessage_1_0 header) throws IOException JavaDoc
941     {
942     try {
943         try {
944         if (transportDebug()) dprint(".REPLY 1.0->: " + header);
945         messageHeader = replyHeader = (ReplyMessage) header;
946         setInputObject();
947
948         // REVISIT: this should be done by waiting thread.
949
inputObject.unmarshalHeader();
950
951         signalResponseReceived();
952         } finally{
953         setWorkThenReadOrResumeSelect(header);
954         }
955     } catch (Throwable JavaDoc t) {
956         if (transportDebug())dprint(".REPLY 1.0: !!ERROR!!: " + header, t);
957         // Mask the exception from thread.;
958
} finally {
959         if (transportDebug()) dprint(".REPLY 1.0<-: " + header);
960     }
961     }
962     
963     public void handleInput(ReplyMessage_1_1 header) throws IOException JavaDoc
964     {
965     try {
966         if (transportDebug()) dprint(".REPLY 1.1->: " + header);
967         messageHeader = replyHeader = (ReplyMessage) header;
968         setInputObject();
969
970         if (header.moreFragmentsToFollow()) {
971
972         // More fragments are coming to complete this reply, so keep
973
// a reference to the InputStream so we can add the fragments
974
connection.clientReply_1_1_Put(this);
975             
976         // In 1.1, we can't assume that we have the request ID in the
977
// first fragment. Thus, another thread is used
978
// to be the reader while this thread unmarshals
979
// the extended header and wakes up the client thread.
980
setWorkThenPoolOrResumeSelect(header);
981
982         // REVISIT - error handling.
983
// This must be done now.
984
inputObject.unmarshalHeader();
985
986         signalResponseReceived();
987
988         } else {
989
990         // Not fragmented, therefore we know the request
991
// ID is here. Thus, we can unmarshal the extended header
992
// and wake up the client thread without using a third
993
// thread as above.
994

995         // REVISIT - error handling during unmarshal.
996
// This must be done now to get the request id.
997
inputObject.unmarshalHeader();
998
999         signalResponseReceived();
1000
1001        setWorkThenReadOrResumeSelect(header);
1002        }
1003    } catch (Throwable JavaDoc t) {
1004        if (transportDebug()) dprint(".REPLY 1.1: !!ERROR!!: " + header);
1005        // Mask the exception from thread.;
1006
} finally {
1007        if (transportDebug()) dprint(".REPLY 1.1<-: " + header);
1008    }
1009    }
1010
1011    public void handleInput(ReplyMessage_1_2 header) throws IOException JavaDoc
1012    {
1013    try {
1014        try {
1015        messageHeader = replyHeader = (ReplyMessage) header;
1016
1017        // We know that the request ID is in the first fragment
1018
header.unmarshalRequestID(dispatchByteBuffer);
1019
1020        if (transportDebug()) {
1021            dprint(".REPLY 1.2->: id/"
1022               + + header.getRequestId()
1023               + ": more?: " + header.moreFragmentsToFollow()
1024               + ": " + header);
1025        }
1026        
1027        setInputObject();
1028
1029        signalResponseReceived();
1030        } finally {
1031        setWorkThenReadOrResumeSelect(header);
1032        }
1033    } catch (Throwable JavaDoc t) {
1034        if (transportDebug()) dprint(".REPLY 1.2: id/"
1035                     + header.getRequestId()
1036                     + ": !!ERROR!!: "
1037                     + header, t);
1038        // Mask the exception from thread.;
1039
} finally {
1040        if (transportDebug()) dprint(".REPLY 1.2<-: id/"
1041                     + header.getRequestId()
1042                     + ": "
1043                     + header);
1044    }
1045    }
1046
1047    public void handleInput(LocateRequestMessage_1_0 header) throws IOException JavaDoc
1048    {
1049    try {
1050        if (transportDebug())
1051        dprint(".LOCATE_REQUEST 1.0->: " + header);
1052        try {
1053        messageHeader = header;
1054        setInputObject();
1055        } finally {
1056        setWorkThenPoolOrResumeSelect(header);
1057        }
1058        getProtocolHandler().handleRequest(header, this);
1059    } catch (Throwable JavaDoc t) {
1060        if (transportDebug())
1061        dprint(".LOCATE_REQUEST 1.0: !!ERROR!!: " + header, t);
1062        // Mask the exception from thread.;
1063
} finally {
1064        if (transportDebug())
1065        dprint(".LOCATE_REQUEST 1.0<-: " + header);
1066    }
1067
1068    }
1069
1070    public void handleInput(LocateRequestMessage_1_1 header) throws IOException JavaDoc
1071    {
1072    try {
1073        if (transportDebug())
1074        dprint(".LOCATE_REQUEST 1.1->: " + header);
1075        try {
1076        messageHeader = header;
1077        setInputObject();
1078        } finally {
1079        setWorkThenPoolOrResumeSelect(header);
1080        }
1081        getProtocolHandler().handleRequest(header, this);
1082    } catch (Throwable JavaDoc t) {
1083        if (transportDebug())
1084        dprint(".LOCATE_REQUEST 1.1: !!ERROR!!: " + header, t);
1085        // Mask the exception from thread.;
1086
} finally {
1087        if (transportDebug())
1088        dprint(".LOCATE_REQUEST 1.1<-:" + header);
1089    }
1090    }
1091
1092    public void handleInput(LocateRequestMessage_1_2 header) throws IOException JavaDoc
1093    {
1094    try {
1095        try {
1096        messageHeader = header;
1097
1098        header.unmarshalRequestID(dispatchByteBuffer);
1099        setInputObject();
1100
1101        if (transportDebug())
1102            dprint(".LOCATE_REQUEST 1.2->: id/"
1103               + header.getRequestId()
1104               + ": "
1105               + header);
1106
1107        if (header.moreFragmentsToFollow()) {
1108            connection.serverRequestMapPut(header.getRequestId(),this);
1109        }
1110        } finally {
1111        setWorkThenPoolOrResumeSelect(header);
1112        }
1113        getProtocolHandler().handleRequest(header, this);
1114    } catch (Throwable JavaDoc t) {
1115        if (transportDebug())
1116        dprint(".LOCATE_REQUEST 1.2: id/"
1117               + header.getRequestId()
1118               + ": !!ERROR!!: "
1119               + header, t);
1120        // Mask the exception from thread.;
1121
} finally {
1122        if (transportDebug())
1123        dprint(".LOCATE_REQUEST 1.2<-: id/"
1124               + header.getRequestId()
1125               + ": "
1126               + header);
1127    }
1128    }
1129
1130    public void handleInput(LocateReplyMessage_1_0 header) throws IOException JavaDoc
1131    {
1132    try {
1133        if (transportDebug())
1134        dprint(".LOCATE_REPLY 1.0->:" + header);
1135        try {
1136        messageHeader = header;
1137        setInputObject();
1138        inputObject.unmarshalHeader(); // REVISIT Put in subcontract.
1139
signalResponseReceived();
1140        } finally {
1141        setWorkThenReadOrResumeSelect(header);
1142        }
1143    } catch (Throwable JavaDoc t) {
1144        if (transportDebug())
1145        dprint(".LOCATE_REPLY 1.0: !!ERROR!!: " + header, t);
1146        // Mask the exception from thread.;
1147
} finally {
1148        if (transportDebug())
1149        dprint(".LOCATE_REPLY 1.0<-: " + header);
1150    }
1151    }
1152
1153    public void handleInput(LocateReplyMessage_1_1 header) throws IOException JavaDoc
1154    {
1155    try {
1156        if (transportDebug()) dprint(".LOCATE_REPLY 1.1->: " + header);
1157        try {
1158        messageHeader = header;
1159        setInputObject();
1160        // Fragmented LocateReplies are not allowed in 1.1.
1161
inputObject.unmarshalHeader();
1162        signalResponseReceived();
1163        } finally {
1164        setWorkThenReadOrResumeSelect(header);
1165        }
1166    } catch (Throwable JavaDoc t) {
1167        if (transportDebug())
1168        dprint(".LOCATE_REPLY 1.1: !!ERROR!!: " + header, t);
1169        // Mask the exception from thread.;
1170
} finally {
1171        if (transportDebug()) dprint(".LOCATE_REPLY 1.1<-: " + header);
1172    }
1173    }
1174
1175    public void handleInput(LocateReplyMessage_1_2 header) throws IOException JavaDoc
1176    {
1177    try {
1178        try {
1179        messageHeader = header;
1180
1181        // No need to put in client reply map - already there.
1182
header.unmarshalRequestID(dispatchByteBuffer);
1183
1184        setInputObject();
1185
1186        if (transportDebug()) dprint(".LOCATE_REPLY 1.2->: id/"
1187                         + header.getRequestId()
1188                         + ": "
1189                         + header);
1190
1191        signalResponseReceived();
1192        } finally {
1193        setWorkThenPoolOrResumeSelect(header); // REVISIT
1194
}
1195    } catch (Throwable JavaDoc t) {
1196        if (transportDebug())
1197        dprint(".LOCATE_REPLY 1.2: id/"
1198               + header.getRequestId()
1199               + ": !!ERROR!!: "
1200               + header, t);
1201        // Mask the exception from thread.;
1202
} finally {
1203        if (transportDebug()) dprint(".LOCATE_REPLY 1.2<-: id/"
1204                     + header.getRequestId()
1205                     + ": "
1206                     + header);
1207    }
1208    }
1209
1210    public void handleInput(FragmentMessage_1_1 header) throws IOException JavaDoc
1211    {
1212    try {
1213        if (transportDebug()) {
1214        dprint(".FRAGMENT 1.1->: "
1215               + "more?: " + header.moreFragmentsToFollow()
1216               + ": " + header);
1217        }
1218        try {
1219        messageHeader = header;
1220        MessageMediator mediator = null;
1221        CDRInputObject inputObject = null;
1222
1223        if (connection.isServer()) {
1224            mediator = connection.serverRequest_1_1_Get();
1225        } else {
1226            mediator = connection.clientReply_1_1_Get();
1227        }
1228        if (mediator != null) {
1229            inputObject = (CDRInputObject) mediator.getInputObject();
1230        }
1231
1232        // If no input stream available, then discard the fragment.
1233
// This can happen:
1234
// 1. if a fragment message is received prior to receiving
1235
// the original request/reply message. Very unlikely.
1236
// 2. if a fragment message is received after the
1237
// reply has been sent (early replies)
1238
// Note: In the case of early replies, the fragments received
1239
// during the request processing (which are never unmarshaled),
1240
// will eventually be discarded by the GC.
1241
if (inputObject == null) {
1242            if (transportDebug())
1243            dprint(".FRAGMENT 1.1: ++++DISCARDING++++: " + header);
1244                    // need to release dispatchByteBuffer to pool if
1245
// we are discarding
1246
releaseByteBufferToPool();
1247            return;
1248        }
1249
1250        inputObject.getBufferManager()
1251            .processFragment(dispatchByteBuffer, header);
1252
1253        if (! header.moreFragmentsToFollow()) {
1254            if (connection.isServer()) {
1255            connection.serverRequest_1_1_Remove();
1256            } else {
1257            connection.clientReply_1_1_Remove();
1258            }
1259        }
1260        } finally {
1261        // NOTE: This *must* come after queing the fragment
1262
// when using the selector to ensure fragments stay in order.
1263
setWorkThenReadOrResumeSelect(header);
1264        }
1265    } catch (Throwable JavaDoc t) {
1266        if (transportDebug())
1267        dprint(".FRAGMENT 1.1: !!ERROR!!: " + header, t);
1268        // Mask the exception from thread.;
1269
} finally {
1270        if (transportDebug()) dprint(".FRAGMENT 1.1<-: " + header);
1271    }
1272    }
1273
1274    public void handleInput(FragmentMessage_1_2 header) throws IOException JavaDoc
1275    {
1276    try {
1277        try {
1278        messageHeader = header;
1279
1280        // Note: We know it's a 1.2 fragment, we have the data, but
1281
// we need the IIOPInputStream instance to unmarshal the
1282
// request ID... but we need the request ID to get the
1283
// IIOPInputStream instance. So we peek at the raw bytes.
1284

1285        header.unmarshalRequestID(dispatchByteBuffer);
1286
1287        if (transportDebug()) {
1288            dprint(".FRAGMENT 1.2->: id/"
1289               + header.getRequestId()
1290               + ": more?: " + header.moreFragmentsToFollow()
1291               + ": " + header);
1292        }
1293
1294        MessageMediator mediator = null;
1295        InputObject inputObject = null;
1296
1297        if (connection.isServer()) {
1298            mediator =
1299            connection.serverRequestMapGet(header.getRequestId());
1300        } else {
1301            mediator =
1302            connection.clientRequestMapGet(header.getRequestId());
1303        }
1304        if (mediator != null) {
1305            inputObject = mediator.getInputObject();
1306        }
1307        // See 1.1 comments.
1308
if (inputObject == null) {
1309            if (transportDebug()) {
1310            dprint(".FRAGMENT 1.2: id/"
1311                   + header.getRequestId()
1312                   + ": ++++DISCARDING++++: "
1313                   + header);
1314            }
1315                    // need to release dispatchByteBuffer to pool if
1316
// we are discarding
1317
releaseByteBufferToPool();
1318            return;
1319        }
1320        ((CDRInputObject)inputObject)
1321            .getBufferManager().processFragment(
1322                                     dispatchByteBuffer, header);
1323
1324        // REVISIT: but if it is a server don't you have to remove the
1325
// stream from the map?
1326
if (! connection.isServer()) {
1327            /* REVISIT
1328             * No need to do anything.
1329             * Should we mark that last was received?
1330             if (! header.moreFragmentsToFollow()) {
1331             // Last fragment.
1332             }
1333            */

1334        }
1335        } finally {
1336        // NOTE: This *must* come after queing the fragment
1337
// when using the selector to ensure fragments stay in order.
1338
setWorkThenReadOrResumeSelect(header);
1339        }
1340    } catch (Throwable JavaDoc t) {
1341        if (transportDebug())
1342        dprint(".FRAGMENT 1.2: id/"
1343               + header.getRequestId()
1344               + ": !!ERROR!!: "
1345               + header, t);
1346        // Mask the exception from thread.;
1347
} finally {
1348        if (transportDebug()) dprint(".FRAGMENT 1.2<-: id/"
1349                     + header.getRequestId()
1350                     + ": "
1351                     + header);
1352    }
1353    }
1354
1355    public void handleInput(CancelRequestMessage header) throws IOException JavaDoc
1356    {
1357    try {
1358        try {
1359        messageHeader = header;
1360        setInputObject();
1361
1362        // REVISIT: Move these two to subcontract.
1363
inputObject.unmarshalHeader();
1364
1365        if (transportDebug()) dprint(".CANCEL->: id/"
1366                         + header.getRequestId() + ": "
1367                         + header.getGIOPVersion() + ": "
1368                         + header);
1369
1370        processCancelRequest(header.getRequestId());
1371                releaseByteBufferToPool();
1372        } finally {
1373        setWorkThenReadOrResumeSelect(header);
1374        }
1375    } catch (Throwable JavaDoc t) {
1376        if (transportDebug()) dprint(".CANCEL: id/"
1377                     + header.getRequestId()
1378                     + ": !!ERROR!!: "
1379                     + header, t);
1380        // Mask the exception from thread.;
1381
} finally {
1382        if (transportDebug()) dprint(".CANCEL<-: id/"
1383                     + header.getRequestId() + ": "
1384                     + header.getGIOPVersion() + ": "
1385                     + header);
1386    }
1387    }
1388    
1389    private void throwNotImplemented()
1390    {
1391    isThreadDone = false;
1392    throwNotImplemented("");
1393    }
1394
1395    private void throwNotImplemented(String JavaDoc msg)
1396    {
1397    throw new RuntimeException JavaDoc("CorbaMessageMediatorImpl: not implemented " + msg);
1398    }
1399
1400    private void dprint(String JavaDoc msg, Throwable JavaDoc t)
1401    {
1402    dprint(msg);
1403    t.printStackTrace(System.out);
1404    }
1405
1406    private void dprint(String JavaDoc msg)
1407    {
1408    ORBUtility.dprint("CorbaMessageMediatorImpl", msg);
1409    }
1410
1411    protected String JavaDoc opAndId(CorbaMessageMediator mediator)
1412    {
1413    return ORBUtility.operationNameAndRequestId(mediator);
1414    }
1415
1416    private boolean transportDebug()
1417    {
1418    return orb.transportDebugFlag;
1419    }
1420
1421    // REVISIT: move this to subcontract (but both client and server need it).
1422
private final void processCancelRequest(int cancelReqId) {
1423
1424        // The GIOP version of CancelRequest does not matter, since
1425
// CancelRequest_1_0 could be sent to cancel a request which
1426
// has a different GIOP version.
1427

1428        /*
1429         * CancelRequest processing logic :
1430         *
1431         * - find the request with matching requestId
1432         *
1433         * - call cancelProcessing() in BufferManagerRead [BMR]
1434         *
1435         * - the hope is that worker thread would call BMR.underflow()
1436         * to wait for more fragments to come in. When BMR.underflow() is
1437         * called, if a CancelRequest had already arrived,
1438     * the worker thread would throw ThreadDeath,
1439         * else the thread would wait to be notified of the
1440         * arrival of a new fragment or CancelRequest. Upon notification,
1441         * the woken up thread would check to see if a CancelRequest had
1442         * arrived and if so throw a ThreadDeath or it will continue to
1443         * process the received fragment.
1444         *
1445         * - if all the fragments had been received prior to CancelRequest
1446         * then the worker thread would never block in BMR.underflow().
1447         * So, setting the abort flag in BMR has no effect. The request
1448         * processing will complete normally.
1449         *
1450         * - in the case where the server has received enough fragments to
1451     * start processing the request and the server sends out
1452     * an early reply. In such a case if the CancelRequest arrives
1453     * after the reply has been sent, it has no effect.
1454         */

1455
1456        if (!connection.isServer()) {
1457        return; // we do not support bi-directional giop yet, ignore.
1458
}
1459
1460        // Try to get hold of the InputStream buffer.
1461
// In the case of 1.0 requests there is no way to get hold of
1462
// InputStream. Try out the 1.1 and 1.2 cases.
1463

1464        // was the request 1.2 ?
1465
MessageMediator mediator = connection.serverRequestMapGet(cancelReqId);
1466    int requestId ;
1467        if (mediator == null) {
1468        // was the request 1.1 ?
1469
mediator = connection.serverRequest_1_1_Get();
1470            if (mediator == null) {
1471        // XXX log this!
1472
// either the request was 1.0
1473
// or an early reply has already been sent
1474
// or request processing is over
1475
// or its a spurious CancelRequest
1476
return; // do nothing.
1477
}
1478
1479        requestId = ((CorbaMessageMediator) mediator).getRequestId();
1480
1481            if (requestId != cancelReqId) {
1482                // A spurious 1.1 CancelRequest has been received.
1483
// XXX log this!
1484
return; // do nothing
1485
}
1486
1487        if (requestId == 0) { // special case
1488
// XXX log this
1489
// this means that
1490
// 1. the 1.1 requests' requestId has not been received
1491
// i.e., a CancelRequest was received even before the
1492
// 1.1 request was received. The spec disallows this.
1493
// 2. or the 1.1 request has a requestId 0.
1494
//
1495
// It is a little tricky to distinguish these two. So, be
1496
// conservative and do not cancel the request. Downside is that
1497
// 1.1 requests with requestId of 0 will never be cancelled.
1498
return; // do nothing
1499
}
1500    } else {
1501        requestId = ((CorbaMessageMediator) mediator).getRequestId();
1502    }
1503
1504    Message JavaDoc msg = ((CorbaMessageMediator)mediator).getRequestHeader();
1505    if (msg.getType() != Message.GIOPRequest) {
1506        // Any mediator obtained here should only ever be for a GIOP
1507
// request.
1508
wrapper.badMessageTypeForCancel() ;
1509    }
1510
1511    // At this point we have a valid message mediator that contains
1512
// a valid requestId.
1513

1514        // at this point we have chosen a request to be cancelled. But we
1515
// do not know if the target object's method has been invoked or not.
1516
// Request input stream being available simply means that the request
1517
// processing is not over yet. simply set the abort flag in the
1518
// BMRS and hope that the worker thread would notice it (this can
1519
// happen only if the request stream is being unmarshalled and the
1520
// target's method has not been invoked yet). This guarantees
1521
// that the requests which have been dispatched to the
1522
// target's method will never be cancelled.
1523

1524        BufferManagerReadStream bufferManager = (BufferManagerReadStream)
1525        ((CDRInputObject)mediator.getInputObject()).getBufferManager();
1526        bufferManager.cancelProcessing(cancelReqId);
1527    }
1528
1529    ////////////////////////////////////////////////////
1530
//
1531
// spi.protocol.CorbaProtocolHandler
1532
//
1533

1534    public void handleRequest(RequestMessage msg,
1535                  CorbaMessageMediator messageMediator)
1536    {
1537    try {
1538        beginRequest(messageMediator);
1539        try {
1540        handleRequestRequest(messageMediator);
1541        if (messageMediator.isOneWay()) {
1542            return;
1543        }
1544        } catch (Throwable JavaDoc t) {
1545        if (messageMediator.isOneWay()) {
1546            return;
1547        }
1548        handleThrowableDuringServerDispatch(
1549                    messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
1550        }
1551        sendResponse(messageMediator);
1552        } catch (Throwable JavaDoc t) {
1553        dispatchError(messageMediator, "RequestMessage", t);
1554    } finally {
1555        endRequest(messageMediator);
1556    }
1557    }
1558
1559    public void handleRequest(LocateRequestMessage msg,
1560                  CorbaMessageMediator messageMediator)
1561    {
1562    try {
1563        beginRequest(messageMediator);
1564        try {
1565        handleLocateRequest(messageMediator);
1566        } catch (Throwable JavaDoc t) {
1567        handleThrowableDuringServerDispatch(
1568                messageMediator, t, CompletionStatus.COMPLETED_MAYBE);
1569        }
1570        sendResponse(messageMediator);
1571        } catch (Throwable JavaDoc t) {
1572        dispatchError(messageMediator, "LocateRequestMessage", t);
1573    } finally {
1574        endRequest(messageMediator);
1575    }
1576    }
1577
1578    private void beginRequest(CorbaMessageMediator messageMediator)
1579    {
1580    ORB orb = (ORB) messageMediator.getBroker();
1581    if (orb.subcontractDebugFlag) {
1582        dprint(".handleRequest->:");
1583    }
1584    connection.serverRequestProcessingBegins();
1585    }
1586
1587    private void dispatchError(CorbaMessageMediator messageMediator,
1588                   String JavaDoc msg, Throwable JavaDoc t)
1589    {
1590    if (orb.subcontractDebugFlag) {
1591        dprint(".handleRequest: " + opAndId(messageMediator)
1592           + ": !!ERROR!!: "
1593           + msg,
1594           t);
1595    }
1596    // REVISIT - this makes hcks sendTwoObjects fail
1597
// messageMediator.getConnection().close();
1598
}
1599
1600    private void sendResponse(CorbaMessageMediator messageMediator)
1601    {
1602    if (orb.subcontractDebugFlag) {
1603        dprint(".handleRequest: " + opAndId(messageMediator)
1604           + ": sending response");
1605    }
1606    // REVISIT - type and location
1607
CDROutputObject outputObject = (CDROutputObject)
1608        messageMediator.getOutputObject();
1609    if (outputObject != null) {
1610        // REVISIT - can be null for TRANSIENT below.
1611
outputObject.finishSendingMessage();
1612    }
1613    }
1614
1615    private void endRequest(CorbaMessageMediator messageMediator)
1616    {
1617    ORB orb = (ORB) messageMediator.getBroker();
1618    if (orb.subcontractDebugFlag) {
1619        dprint(".handleRequest<-: " + opAndId(messageMediator));
1620    }
1621
1622        // release NIO ByteBuffers to ByteBufferPool
1623

1624        try {
1625            OutputObject outputObj = messageMediator.getOutputObject();
1626            if (outputObj != null) {
1627        outputObj.close();
1628            }
1629            InputObject inputObj = messageMediator.getInputObject();
1630            if (inputObj != null) {
1631        inputObj.close();
1632            }
1633        } catch (IOException JavaDoc ex) {
1634            // Given what close() does, this catch shouldn't ever happen.
1635
// See CDRInput/OutputObject.close() for more info.
1636
// It also won't result in a Corba error if an IOException happens.
1637
if (orb.subcontractDebugFlag) {
1638                dprint(".endRequest: IOException:" + ex.getMessage(), ex);
1639        }
1640        } finally {
1641        ((CorbaConnection)messageMediator.getConnection()).serverRequestProcessingEnds();
1642    }
1643    }
1644
1645    protected void handleRequestRequest(CorbaMessageMediator messageMediator)
1646    {
1647    // Does nothing if already unmarshaled.
1648
((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
1649
1650        ORB orb = (ORB)messageMediator.getBroker();
1651    orb.checkShutdownState();
1652
1653    ObjectKey okey = messageMediator.getObjectKey();
1654        if (orb.subcontractDebugFlag) {
1655        ObjectKeyTemplate oktemp = okey.getTemplate() ;
1656        dprint( ".handleRequest: " + opAndId(messageMediator)
1657            + ": dispatching to scid: " + oktemp.getSubcontractId());
1658    }
1659
1660    CorbaServerRequestDispatcher sc = okey.getServerRequestDispatcher(orb);
1661
1662    if (orb.subcontractDebugFlag) {
1663        dprint(".handleRequest: " + opAndId(messageMediator)
1664           + ": dispatching to sc: " + sc);
1665    }
1666
1667    if (sc == null) {
1668        throw wrapper.noServerScInDispatch() ;
1669    }
1670
1671    // NOTE:
1672
// This is necessary so mediator can act as ResponseHandler
1673
// and pass necessary info to response constructors located
1674
// in the subcontract.
1675
// REVISIT - same class right now.
1676
//messageMediator.setProtocolHandler(this);
1677

1678        try {
1679            orb.startingDispatch();
1680        sc.dispatch(messageMediator);
1681        } finally {
1682            orb.finishedDispatch();
1683        }
1684    }
1685
1686    protected void handleLocateRequest(CorbaMessageMediator messageMediator)
1687    {
1688    ORB orb = (ORB)messageMediator.getBroker();
1689    LocateRequestMessage msg = (LocateRequestMessage)
1690        messageMediator.getDispatchHeader();
1691    IOR ior = null;
1692    LocateReplyMessage reply = null;
1693    short addrDisp = -1;
1694
1695    try {
1696        ((CDRInputObject)messageMediator.getInputObject()).unmarshalHeader();
1697        CorbaServerRequestDispatcher sc =
1698        msg.getObjectKey().getServerRequestDispatcher( orb ) ;
1699        if (sc == null) {
1700        return;
1701        }
1702
1703        ior = sc.locate(msg.getObjectKey());
1704
1705        if ( ior == null ) {
1706        reply = MessageBase.createLocateReply(
1707                    orb, msg.getGIOPVersion(),
1708                msg.getEncodingVersion(),
1709                            msg.getRequestId(),
1710                LocateReplyMessage.OBJECT_HERE, null);
1711
1712        } else {
1713        reply = MessageBase.createLocateReply(
1714                    orb, msg.getGIOPVersion(),
1715                msg.getEncodingVersion(),
1716                            msg.getRequestId(),
1717                LocateReplyMessage.OBJECT_FORWARD, ior);
1718        }
1719        // REVISIT: Should we catch SystemExceptions?
1720

1721    } catch (AddressingDispositionException ex) {
1722
1723        // create a response containing the expected target
1724
// addressing disposition.
1725

1726        reply = MessageBase.createLocateReply(
1727                orb, msg.getGIOPVersion(),
1728            msg.getEncodingVersion(),
1729                        msg.getRequestId(),
1730            LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE, null);
1731
1732        addrDisp = ex.expectedAddrDisp();
1733
1734    } catch (RequestCanceledException ex) {
1735
1736        return; // no need to send reply
1737

1738    } catch ( Exception JavaDoc ex ) {
1739
1740        // REVISIT If exception is not OBJECT_NOT_EXIST, it should
1741
// have a different reply
1742

1743        // This handles OBJECT_NOT_EXIST exceptions thrown in
1744
// the subcontract or obj manager. Send back UNKNOWN_OBJECT.
1745

1746        reply = MessageBase.createLocateReply(
1747                orb, msg.getGIOPVersion(),
1748            msg.getEncodingVersion(),
1749            msg.getRequestId(),
1750            LocateReplyMessage.UNKNOWN_OBJECT, null);
1751    }
1752
1753    CDROutputObject outputObject =
1754        createAppropriateOutputObject(messageMediator,
1755                      msg, reply);
1756    messageMediator.setOutputObject(outputObject);
1757    outputObject.setMessageMediator(messageMediator);
1758
1759    reply.write(outputObject);
1760    // outputObject.setMessage(reply); // REVISIT - not necessary
1761
if (ior != null) {
1762        ior.write(outputObject);
1763    }
1764    if (addrDisp != -1) {
1765        AddressingDispositionHelper.write(outputObject, addrDisp);
1766    }
1767    }
1768
1769    private CDROutputObject createAppropriateOutputObject(
1770        CorbaMessageMediator messageMediator,
1771    Message JavaDoc msg, LocateReplyMessage reply)
1772    {
1773    CDROutputObject outputObject;
1774
1775    if (msg.getGIOPVersion().lessThan(GIOPVersion.V1_2)) {
1776        // locate msgs 1.0 & 1.1 :=> grow,
1777
// REVISIT - build from factory
1778
outputObject = new CDROutputObject(
1779                     (ORB) messageMediator.getBroker(),
1780                 this,
1781                 GIOPVersion.V1_0,
1782                 (CorbaConnection) messageMediator.getConnection(),
1783                 reply,
1784                 ORBConstants.STREAM_FORMAT_VERSION_1);
1785    } else {
1786        // 1.2 :=> stream
1787
// REVISIT - build from factory
1788
outputObject = new CDROutputObject(
1789                     (ORB) messageMediator.getBroker(),
1790                 messageMediator,
1791                 reply,
1792                 ORBConstants.STREAM_FORMAT_VERSION_1);
1793    }
1794    return outputObject;
1795    }
1796
1797    public void handleThrowableDuringServerDispatch(
1798        CorbaMessageMediator messageMediator,
1799        Throwable JavaDoc throwable,
1800        CompletionStatus JavaDoc completionStatus)
1801    {
1802    if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
1803        dprint(".handleThrowableDuringServerDispatch: "
1804           + opAndId(messageMediator) + ": "
1805           + throwable);
1806    }
1807
1808    // If we haven't unmarshaled the header, we probably don't
1809
// have enough information to even send back a reply.
1810

1811    // REVISIT
1812
// Cannot do this check. When target addressing disposition does
1813
// not match (during header unmarshaling) it throws an exception
1814
// to be handled here.
1815
/*
1816    if (! ((CDRInputObject)messageMediator.getInputObject())
1817        .unmarshaledHeader()) {
1818        return;
1819    }
1820    */

1821    handleThrowableDuringServerDispatch(messageMediator,
1822                        throwable,
1823                        completionStatus,
1824                        1);
1825    }
1826
1827
1828    // REVISIT - catch and ignore RequestCanceledException.
1829

1830    protected void handleThrowableDuringServerDispatch(
1831        CorbaMessageMediator messageMediator,
1832    Throwable JavaDoc throwable,
1833    CompletionStatus JavaDoc completionStatus,
1834    int iteration)
1835    {
1836    if (iteration > 10) {
1837        if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
1838        dprint(".handleThrowableDuringServerDispatch: "
1839               + opAndId(messageMediator)
1840               + ": cannot handle: "
1841               + throwable);
1842        }
1843
1844        // REVISIT - should we close connection?
1845
RuntimeException JavaDoc rte =
1846        new RuntimeException JavaDoc("handleThrowableDuringServerDispatch: " +
1847                     "cannot create response.");
1848        rte.initCause(throwable);
1849        throw rte;
1850    }
1851
1852    try {
1853        if (throwable instanceof ForwardException) {
1854        ForwardException fex = (ForwardException)throwable ;
1855        createLocationForward( messageMediator, fex.getIOR(), null ) ;
1856        return;
1857        }
1858
1859        if (throwable instanceof AddressingDispositionException) {
1860        handleAddressingDisposition(
1861                    messageMediator,
1862            (AddressingDispositionException)throwable);
1863        return;
1864        }
1865
1866        // Else.
1867

1868        SystemException JavaDoc sex =
1869        convertThrowableToSystemException(throwable, completionStatus);
1870
1871        createSystemExceptionResponse(messageMediator, sex, null);
1872        return;
1873
1874    } catch (Throwable JavaDoc throwable2) {
1875
1876        // User code (e.g., postinvoke, interceptors) may change
1877
// the exception, so we end up back here.
1878
// Report the changed exception.
1879

1880        handleThrowableDuringServerDispatch(messageMediator,
1881                        throwable2,
1882                        completionStatus,
1883                        iteration + 1);
1884        return;
1885    }
1886    }
1887
1888    protected SystemException JavaDoc convertThrowableToSystemException(
1889        Throwable JavaDoc throwable,
1890    CompletionStatus JavaDoc completionStatus)
1891    {
1892    if (throwable instanceof SystemException JavaDoc) {
1893        return (SystemException JavaDoc)throwable;
1894    }
1895
1896    if (throwable instanceof RequestCanceledException) {
1897        // Reporting an exception response causes the
1898
// poa current stack, the interceptor stacks, etc.
1899
// to be balanced. It also notifies interceptors
1900
// that the request was cancelled.
1901

1902        return wrapper.requestCanceled( throwable ) ;
1903    }
1904
1905    // NOTE: We do not trap ThreadDeath above Throwable.
1906
// There is no reason to stop the thread. It is
1907
// just a worker thread. The ORB never throws
1908
// ThreadDeath. Client code may (e.g., in ServantManagers,
1909
// interceptors, or servants) but that should not
1910
// effect the ORB threads. So it is just handled
1911
// generically.
1912

1913    //
1914
// Last resort.
1915
// If user code throws a non-SystemException report it generically.
1916
//
1917

1918    return wrapper.runtimeexception( CompletionStatus.COMPLETED_MAYBE, throwable ) ;
1919    }
1920
1921    protected void handleAddressingDisposition(
1922        CorbaMessageMediator messageMediator,
1923    AddressingDispositionException ex)
1924    {
1925
1926    short addrDisp = -1;
1927
1928    // from iiop.RequestProcessor.
1929

1930    // Respond with expected target addressing disposition.
1931

1932    switch (messageMediator.getRequestHeader().getType()) {
1933    case Message.GIOPRequest :
1934        ReplyMessage replyHeader = MessageBase.createReply(
1935                  (ORB)messageMediator.getBroker(),
1936              messageMediator.getGIOPVersion(),
1937              messageMediator.getEncodingVersion(),
1938              messageMediator.getRequestId(),
1939              ReplyMessage.NEEDS_ADDRESSING_MODE,
1940              null, null);
1941        // REVISIT: via acceptor factory.
1942
CDROutputObject outputObject = new CDROutputObject(
1943                (ORB)messageMediator.getBroker(),
1944        this,
1945        messageMediator.getGIOPVersion(),
1946        (CorbaConnection)messageMediator.getConnection(),
1947        replyHeader,
1948        ORBConstants.STREAM_FORMAT_VERSION_1);
1949        messageMediator.setOutputObject(outputObject);
1950        outputObject.setMessageMediator(messageMediator);
1951        replyHeader.write(outputObject);
1952        AddressingDispositionHelper.write(outputObject,
1953                          ex.expectedAddrDisp());
1954        return;
1955
1956    case Message.GIOPLocateRequest :
1957        LocateReplyMessage locateReplyHeader = MessageBase.createLocateReply(
1958            (ORB)messageMediator.getBroker(),
1959        messageMediator.getGIOPVersion(),
1960        messageMediator.getEncodingVersion(),
1961        messageMediator.getRequestId(),
1962        LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE,
1963        null);
1964
1965        addrDisp = ex.expectedAddrDisp();
1966
1967        // REVISIT: via acceptor factory.
1968
outputObject =
1969        createAppropriateOutputObject(messageMediator,
1970                          messageMediator.getRequestHeader(),
1971                          locateReplyHeader);
1972        messageMediator.setOutputObject(outputObject);
1973        outputObject.setMessageMediator(messageMediator);
1974        locateReplyHeader.write(outputObject);
1975        IOR ior = null;
1976        if (ior != null) {
1977        ior.write(outputObject);
1978        }
1979        if (addrDisp != -1) {
1980        AddressingDispositionHelper.write(outputObject, addrDisp);
1981        }
1982        return;
1983    }
1984    }
1985
1986    public CorbaMessageMediator createResponse(
1987        CorbaMessageMediator messageMediator,
1988    ServiceContexts svc)
1989    {
1990    // REVISIT: ignore service contexts during framework transition.
1991
// They are set in SubcontractResponseHandler to the wrong connection.
1992
// Then they would be set again here and a duplicate contexts
1993
// exception occurs.
1994
return createResponseHelper(
1995            messageMediator,
1996        getServiceContextsForReply(messageMediator, null));
1997    }
1998
1999    public CorbaMessageMediator createUserExceptionResponse(
2000        CorbaMessageMediator messageMediator, ServiceContexts svc)
2001    {
2002    // REVISIT - same as above
2003
return createResponseHelper(
2004            messageMediator,
2005        getServiceContextsForReply(messageMediator, null),
2006        true);
2007    }
2008
2009    public CorbaMessageMediator createUnknownExceptionResponse(
2010        CorbaMessageMediator messageMediator, UnknownException JavaDoc ex)
2011    {
2012    // NOTE: This service context container gets augmented in
2013
// tail call.
2014
ServiceContexts contexts = null;
2015    SystemException JavaDoc sys = new UNKNOWN JavaDoc( 0,
2016        CompletionStatus.COMPLETED_MAYBE);
2017    contexts = new ServiceContexts( (ORB)messageMediator.getBroker() );
2018    UEInfoServiceContext uei = new UEInfoServiceContext(sys);
2019    contexts.put( uei ) ;
2020    return createSystemExceptionResponse(messageMediator, sys, contexts);
2021    }
2022
2023    public CorbaMessageMediator createSystemExceptionResponse(
2024        CorbaMessageMediator messageMediator,
2025    SystemException JavaDoc ex,
2026    ServiceContexts svc)
2027    {
2028    if (messageMediator.getConnection() != null) {
2029        // It is possible that fragments of response have already been
2030
// sent. Then an error may occur (e.g. marshaling error like
2031
// non serializable object). In that case it is too late
2032
// to send the exception. We just return the existing fragmented
2033
// stream here. This will cause an incomplete last fragment
2034
// to be sent. Then the other side will get a marshaling error
2035
// when attempting to unmarshal.
2036

2037        // REVISIT: Impl - make interface method to do the following.
2038
CorbaMessageMediatorImpl mediator = (CorbaMessageMediatorImpl)
2039        ((CorbaConnection)messageMediator.getConnection())
2040        .serverRequestMapGet(messageMediator.getRequestId());
2041
2042        OutputObject existingOutputObject = null;
2043        if (mediator != null) {
2044        existingOutputObject = mediator.getOutputObject();
2045        }
2046
2047        // REVISIT: need to think about messageMediator containing correct
2048
// pointer to output object.
2049
if (existingOutputObject != null &&
2050        mediator.sentFragment() &&
2051        ! mediator.sentFullMessage())
2052        {
2053        return mediator;
2054        }
2055    }
2056    
2057    // Only do this if interceptors have been initialized on this request
2058
// and have not completed their lifecycle (otherwise the info stack
2059
// may be empty or have a different request's entry on top).
2060
if (messageMediator.executePIInResponseConstructor()) {
2061        // REVISIT: not necessary in framework now?
2062
// Inform Portable Interceptors of the SystemException. This is
2063
// required to be done here because the ending interception point
2064
// is called in the when creating the response below
2065
// but we do not currently write the SystemException into the
2066
// response until after the ending point is called.
2067
((ORB)messageMediator.getBroker()).getPIHandler().setServerPIInfo( ex );
2068    }
2069
2070    if (((ORB)messageMediator.getBroker()).subcontractDebugFlag &&
2071        ex != null)
2072        {
2073            dprint(".createSystemExceptionResponse: "
2074           + opAndId(messageMediator),
2075           ex);
2076    }
2077
2078    ServiceContexts serviceContexts =
2079        getServiceContextsForReply(messageMediator, svc);
2080
2081    // NOTE: We MUST add the service context before creating
2082
// the response since service contexts are written to the
2083
// stream when the response object is created.
2084

2085    addExceptionDetailMessage(messageMediator, ex, serviceContexts);
2086
2087        CorbaMessageMediator response =
2088        createResponseHelper(messageMediator, serviceContexts, false);
2089
2090    // NOTE: From here on, it is too late to add more service contexts.
2091
// They have already been serialized to the stream (and maybe fragments
2092
// sent).
2093

2094    ORBUtility.writeSystemException(
2095            ex, (OutputStream JavaDoc)response.getOutputObject());
2096
2097    return response;
2098    }
2099
2100    private void addExceptionDetailMessage(CorbaMessageMediator mediator,
2101                       SystemException JavaDoc ex,
2102                       ServiceContexts serviceContexts)
2103    {
2104    ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
2105    PrintWriter JavaDoc pw = new PrintWriter JavaDoc(baos);
2106    ex.printStackTrace(pw);
2107    pw.flush(); // NOTE: you must flush or baos will be empty.
2108
EncapsOutputStream encapsOutputStream =
2109        new EncapsOutputStream((ORB)mediator.getBroker());
2110    encapsOutputStream.putEndian();
2111    encapsOutputStream.write_wstring(baos.toString());
2112    UnknownServiceContext serviceContext =
2113        new UnknownServiceContext(ExceptionDetailMessage.value,
2114                      encapsOutputStream.toByteArray());
2115    serviceContexts.put(serviceContext);
2116    }
2117
2118    public CorbaMessageMediator createLocationForward(
2119        CorbaMessageMediator messageMediator, IOR ior, ServiceContexts svc)
2120    {
2121        ReplyMessage reply
2122            = MessageBase.createReply(
2123                  (ORB)messageMediator.getBroker(),
2124          messageMediator.getGIOPVersion(),
2125          messageMediator.getEncodingVersion(),
2126          messageMediator.getRequestId(),
2127          ReplyMessage.LOCATION_FORWARD,
2128          getServiceContextsForReply(messageMediator, svc),
2129          ior);
2130
2131    return createResponseHelper(messageMediator, reply, ior);
2132    }
2133
2134    protected CorbaMessageMediator createResponseHelper(
2135        CorbaMessageMediator messageMediator, ServiceContexts svc)
2136    {
2137    ReplyMessage message =
2138        MessageBase.createReply(
2139        (ORB)messageMediator.getBroker(),
2140        messageMediator.getGIOPVersion(),
2141        messageMediator.getEncodingVersion(),
2142        messageMediator.getRequestId(),
2143        ReplyMessage.NO_EXCEPTION,
2144        svc,
2145        null);
2146    return createResponseHelper(messageMediator, message, null);
2147    }
2148
2149    protected CorbaMessageMediator createResponseHelper(
2150        CorbaMessageMediator messageMediator, ServiceContexts svc,boolean user)
2151    {
2152    ReplyMessage message =
2153            MessageBase.createReply(
2154                (ORB)messageMediator.getBroker(),
2155        messageMediator.getGIOPVersion(),
2156        messageMediator.getEncodingVersion(),
2157        messageMediator.getRequestId(),
2158        user ? ReplyMessage.USER_EXCEPTION :
2159               ReplyMessage.SYSTEM_EXCEPTION,
2160        svc,
2161        null);
2162    return createResponseHelper(messageMediator, message, null);
2163    }
2164
2165    // REVISIT - IOR arg is ignored.
2166
protected CorbaMessageMediator createResponseHelper(
2167        CorbaMessageMediator messageMediator, ReplyMessage reply, IOR ior)
2168    {
2169    // REVISIT - these should be invoked from subcontract.
2170
runServantPostInvoke(messageMediator);
2171    runInterceptors(messageMediator, reply);
2172    runRemoveThreadInfo(messageMediator);
2173
2174        if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
2175        dprint(".createResponseHelper: "
2176           + opAndId(messageMediator) + ": "
2177           + reply);
2178    }
2179              
2180    messageMediator.setReplyHeader(reply);
2181
2182    OutputObject replyOutputObject;
2183    // REVISIT = do not use null.
2184
//
2185
if (messageMediator.getConnection() == null) {
2186        // REVISIT - needs factory
2187
replyOutputObject =
2188        new CDROutputObject(orb, messageMediator,
2189                    messageMediator.getReplyHeader(),
2190                    messageMediator.getStreamFormatVersion(),
2191                    BufferManagerFactory.GROW);
2192    } else {
2193        replyOutputObject = messageMediator.getConnection().getAcceptor()
2194         .createOutputObject(messageMediator.getBroker(), messageMediator);
2195    }
2196    messageMediator.setOutputObject(replyOutputObject);
2197    messageMediator.getOutputObject().setMessageMediator(messageMediator);
2198
2199    reply.write((OutputStream JavaDoc) messageMediator.getOutputObject());
2200    if (reply.getIOR() != null) {
2201        reply.getIOR().write((OutputStream JavaDoc) messageMediator.getOutputObject());
2202    }
2203    // REVISIT - not necessary?
2204
//messageMediator.this.replyIOR = reply.getIOR();
2205

2206    // NOTE: The mediator holds onto output object so return value
2207
// not really necessary.
2208
return messageMediator;
2209    }
2210
2211    protected void runServantPostInvoke(CorbaMessageMediator messageMediator)
2212    {
2213    // Run ServantLocator::postinvoke. This may cause a SystemException
2214
// which will throw out of the constructor and return later
2215
// to construct a reply for that exception. The internal logic
2216
// of returnServant makes sure that postinvoke is only called once.
2217
// REVISIT: instead of instanceof, put method on all orbs.
2218
ORB orb = null;
2219    // This flag is to deal with BootstrapServer use of reply streams,
2220
// with ServerRequestDispatcher's use of reply streams, etc.
2221
if (messageMediator.executeReturnServantInResponseConstructor()) {
2222        // It is possible to get marshaling errors in the skeleton after
2223
// postinvoke has completed. We must set this to false so that
2224
// when the error exception reply is constructed we don't try
2225
// to incorrectly access poa current (which will be the wrong
2226
// one or an empty stack.
2227
messageMediator.setExecuteReturnServantInResponseConstructor(false);
2228        messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(true);
2229
2230        try {
2231        orb = (ORB)messageMediator.getBroker();
2232        OAInvocationInfo info = orb.peekInvocationInfo() ;
2233        ObjectAdapter oa = info.oa();
2234        try {
2235            oa.returnServant() ;
2236        } catch (Throwable JavaDoc thr) {
2237            wrapper.unexpectedException( thr ) ;
2238
2239            if (thr instanceof Error JavaDoc)
2240            throw (Error JavaDoc)thr ;
2241            else if (thr instanceof RuntimeException JavaDoc)
2242            throw (RuntimeException JavaDoc)thr ;
2243        } finally {
2244            oa.exit();
2245        }
2246        } catch (EmptyStackException JavaDoc ese) {
2247        throw wrapper.emptyStackRunServantPostInvoke( ese ) ;
2248        }
2249    }
2250    }
2251
2252    protected void runInterceptors(CorbaMessageMediator messageMediator,
2253                   ReplyMessage reply)
2254    {
2255    if( messageMediator.executePIInResponseConstructor() ) {
2256        // Invoke server request ending interception points (send_*):
2257
// Note: this may end up with a SystemException or an internal
2258
// Runtime ForwardRequest
2259
((ORB)messageMediator.getBroker()).getPIHandler().
2260        invokeServerPIEndingPoint( reply );
2261
2262        // Note this will be executed even if a ForwardRequest or
2263
// SystemException is thrown by a Portable Interceptors ending
2264
// point since we end up in this constructor again anyway.
2265
((ORB)messageMediator.getBroker()).getPIHandler().
2266        cleanupServerPIRequest();
2267
2268        // See createSystemExceptionResponse for why this is necesary.
2269
messageMediator.setExecutePIInResponseConstructor(false);
2270    }
2271    }
2272
2273    protected void runRemoveThreadInfo(CorbaMessageMediator messageMediator)
2274    {
2275    // Once you get here then the final reply is available (i.e.,
2276
// postinvoke and interceptors have completed.
2277
if (messageMediator.executeRemoveThreadInfoInResponseConstructor()) {
2278        messageMediator.setExecuteRemoveThreadInfoInResponseConstructor(false);
2279        ((ORB)messageMediator.getBroker()).popInvocationInfo() ;
2280    }
2281    }
2282
2283    protected ServiceContexts getServiceContextsForReply(
2284        CorbaMessageMediator messageMediator, ServiceContexts contexts)
2285    {
2286    CorbaConnection c = (CorbaConnection) messageMediator.getConnection();
2287
2288        if (((ORB)messageMediator.getBroker()).subcontractDebugFlag) {
2289            dprint(".getServiceContextsForReply: "
2290           + opAndId(messageMediator)
2291           + ": " + c);
2292    }
2293
2294        if (contexts == null) {
2295            contexts = new ServiceContexts(((ORB)messageMediator.getBroker()));
2296    }
2297            
2298    // NOTE : We only want to send the runtime context the first time
2299

2300    if (c != null && !c.isPostInitialContexts()) {
2301        c.setPostInitialContexts();
2302        SendingContextServiceContext scsc =
2303        new SendingContextServiceContext(
2304            ((ORB)messageMediator.getBroker()).getFVDCodeBaseIOR()) ;
2305
2306        if (contexts.get( scsc.getId() ) != null)
2307        throw wrapper.duplicateSendingContextServiceContext() ;
2308
2309        contexts.put( scsc ) ;
2310
2311        if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag)
2312                dprint(".getServiceContextsForReply: "
2313               + opAndId(messageMediator)
2314               + ": added SendingContextServiceContext" ) ;
2315    }
2316
2317        // send ORBVersion servicecontext as part of the Reply
2318

2319        ORBVersionServiceContext ovsc
2320            = new ORBVersionServiceContext(ORBVersionFactory.getORBVersion());
2321
2322    if (contexts.get( ovsc.getId() ) != null)
2323        throw wrapper.duplicateOrbVersionServiceContext() ;
2324
2325    contexts.put( ovsc ) ;
2326
2327    if ( ((ORB)messageMediator.getBroker()).subcontractDebugFlag)
2328        dprint(".getServiceContextsForReply: "
2329           + opAndId(messageMediator)
2330               + ": added ORB version service context");
2331
2332        return contexts;
2333    }
2334
2335    // REVISIT - this method should be migrated to orbutil.ORBUtility
2336
// since all locations that release ByteBuffers use
2337
// very similar logic and debug information.
2338
private void releaseByteBufferToPool() {
2339        if (dispatchByteBuffer != null) {
2340            orb.getByteBufferPool().releaseByteBuffer(dispatchByteBuffer);
2341            if (transportDebug()) {
2342                int bbId = System.identityHashCode(dispatchByteBuffer);
2343                StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
2344                sb.append(".handleInput: releasing ByteBuffer (" + bbId +
2345                          ") to ByteBufferPool");
2346                dprint(sb.toString());
2347             }
2348        }
2349    }
2350}
2351
2352// End of file.
2353

2354
2355
Popular Tags