KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)CorbaClientRequestDispatcherImpl.java 1.86 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 /*
9  * Licensed Materials - Property of IBM
10  * RMI-IIOP v1.0
11  * Copyright IBM Corp. 1998 1999 All Rights Reserved
12  *
13  * US Government Users Restricted Rights - Use, duplication or
14  * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
15  */

16
17 package com.sun.corba.se.impl.protocol;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.rmi.RemoteException JavaDoc;
22
23 import javax.rmi.CORBA.Util JavaDoc;
24 import javax.rmi.CORBA.Tie JavaDoc;
25
26 import org.omg.CORBA.COMM_FAILURE JavaDoc;
27 import org.omg.CORBA.INTERNAL JavaDoc;
28 import org.omg.CORBA.SystemException JavaDoc;
29 import org.omg.CORBA.Request JavaDoc;
30 import org.omg.CORBA.NamedValue JavaDoc;
31 import org.omg.CORBA.NVList JavaDoc;
32 import org.omg.CORBA.Context JavaDoc;
33 import org.omg.CORBA.ContextList JavaDoc;
34 import org.omg.CORBA.ExceptionList JavaDoc;
35 import org.omg.CORBA.TypeCode JavaDoc;
36 import org.omg.CORBA.portable.RemarshalException JavaDoc;
37 import org.omg.CORBA_2_3.portable.InputStream JavaDoc;
38 import org.omg.CORBA_2_3.portable.OutputStream JavaDoc;
39 import org.omg.CORBA.portable.Delegate JavaDoc;
40 import org.omg.CORBA.portable.ServantObject JavaDoc;
41 import org.omg.CORBA.portable.ApplicationException JavaDoc;
42 import org.omg.CORBA.portable.UnknownException JavaDoc;
43 import org.omg.IOP.ExceptionDetailMessage JavaDoc;
44 import org.omg.IOP.TAG_CODE_SETS JavaDoc;
45
46 import com.sun.org.omg.SendingContext.CodeBase;
47
48 import com.sun.corba.se.pept.broker.Broker;
49 import com.sun.corba.se.pept.encoding.InputObject;
50 import com.sun.corba.se.pept.encoding.OutputObject;
51 import com.sun.corba.se.pept.protocol.ClientRequestDispatcher;
52 import com.sun.corba.se.pept.protocol.MessageMediator;
53 import com.sun.corba.se.pept.transport.Connection;
54 import com.sun.corba.se.pept.transport.OutboundConnectionCache;
55 import com.sun.corba.se.pept.transport.ContactInfo;
56
57 import com.sun.corba.se.spi.ior.IOR;
58 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
59 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate;
60 import com.sun.corba.se.spi.ior.iiop.CodeSetsComponent;
61 import com.sun.corba.se.spi.oa.OAInvocationInfo;
62 import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
63 import com.sun.corba.se.spi.orb.ORB;
64 import com.sun.corba.se.spi.orb.ORBVersion;
65 import com.sun.corba.se.spi.orb.ORBVersionFactory;
66 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
67 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
68 import com.sun.corba.se.spi.transport.CorbaContactInfo ;
69 import com.sun.corba.se.spi.transport.CorbaContactInfoList ;
70 import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator ;
71 import com.sun.corba.se.spi.transport.CorbaConnection;
72 import com.sun.corba.se.spi.logging.CORBALogDomains;
73
74 import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
75 import com.sun.corba.se.spi.servicecontext.ServiceContext;
76 import com.sun.corba.se.spi.servicecontext.ServiceContexts;
77 import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
78 import com.sun.corba.se.spi.servicecontext.CodeSetServiceContext;
79 import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
80 import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
81 import com.sun.corba.se.spi.servicecontext.MaxStreamFormatVersionServiceContext;
82 import com.sun.corba.se.spi.servicecontext.UnknownServiceContext;
83
84 import com.sun.corba.se.impl.encoding.CDRInputObject;
85 import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
86 import com.sun.corba.se.impl.encoding.CodeSetConversion;
87 import com.sun.corba.se.impl.encoding.EncapsInputStream;
88 import com.sun.corba.se.impl.encoding.MarshalOutputStream;
89 import com.sun.corba.se.impl.encoding.MarshalInputStream;
90 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
91 import com.sun.corba.se.impl.orbutil.ORBUtility;
92 import com.sun.corba.se.impl.orbutil.ORBConstants;
93 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
94 import com.sun.corba.se.impl.protocol.giopmsgheaders.KeyAddr;
95 import com.sun.corba.se.impl.protocol.giopmsgheaders.ProfileAddr;
96 import com.sun.corba.se.impl.protocol.giopmsgheaders.ReferenceAddr;
97 import com.sun.corba.se.impl.transport.CorbaContactInfoListIteratorImpl;
98 import com.sun.corba.se.impl.util.JDKBridge;
99
100 /**
101  * ClientDelegate is the RMI client-side subcontract or representation
102  * It implements RMI delegate as well as our internal ClientRequestDispatcher
103  * interface.
104  */

105 public class CorbaClientRequestDispatcherImpl
106     implements
107     ClientRequestDispatcher
108 {
109     // Used for locking
110
private Object JavaDoc lock = new Object JavaDoc();
111
112     public OutputObject beginRequest(Object JavaDoc self, String JavaDoc opName,
113                      boolean isOneWay, ContactInfo contactInfo)
114     {
115       ORB orb = null;
116       try {
117     CorbaContactInfo corbaContactInfo = (CorbaContactInfo) contactInfo;
118     orb = (ORB)contactInfo.getBroker();
119
120     if (orb.subcontractDebugFlag) {
121         dprint(".beginRequest->: op/" + opName);
122     }
123
124     //
125
// Portable Interceptor initialization.
126
//
127

128         orb.getPIHandler().initiateClientPIRequest( false );
129
130     //
131
// Connection.
132
//
133

134     CorbaConnection connection = null;
135
136     // This locking is done so that multiple connections are not created
137
// for the same endpoint
138
synchronized (lock) {
139         if (contactInfo.isConnectionBased()) {
140         if (contactInfo.shouldCacheConnection()) {
141             connection = (CorbaConnection)
142             orb.getTransportManager()
143             .getOutboundConnectionCache(contactInfo).get(contactInfo);
144         }
145         if (connection != null) {
146             if (orb.subcontractDebugFlag) {
147             dprint(".beginRequest: op/" + opName
148                    + ": Using cached connection: " + connection);
149             }
150         } else {
151             try {
152             connection = (CorbaConnection)
153                 contactInfo.createConnection();
154             if (orb.subcontractDebugFlag) {
155                 dprint(".beginRequest: op/" + opName
156                    + ": Using created connection: " + connection);
157             }
158             } catch (RuntimeException JavaDoc e) {
159             if (orb.subcontractDebugFlag) {
160                 dprint(".beginRequest: op/" + opName
161                    + ": failed to create connection: " + e);
162             }
163             // REVISIT: this part similar to marshalingComplete below.
164
boolean retry = getContactInfoListIterator(orb)
165                        .reportException(contactInfo, e);
166             // REVISIT:
167
// this part similar to Remarshal in this method below
168
if (retry) {
169                 if(getContactInfoListIterator(orb).hasNext()) {
170                 contactInfo = (ContactInfo)
171                    getContactInfoListIterator(orb).next();
172                 return beginRequest(self, opName,
173                             isOneWay, contactInfo);
174                 } else {
175                 throw e;
176                 }
177             } else {
178                 throw e;
179             }
180             }
181             if (connection.shouldRegisterReadEvent()) {
182             // REVISIT: cast
183
orb.getTransportManager().getSelector(0)
184                 .registerForEvent(connection.getEventHandler());
185             connection.setState("ESTABLISHED");
186             }
187             // Do not do connection reclaim here since the connections
188
// are marked in use by registerWaiter() call and since this
189
// call happens later do it after that.
190
if (contactInfo.shouldCacheConnection()) {
191             OutboundConnectionCache connectionCache =
192              orb.getTransportManager()
193                 .getOutboundConnectionCache(contactInfo);
194             connectionCache.stampTime(connection);
195             connectionCache.put(contactInfo, connection);
196     // connectionCache.reclaim();
197
}
198         }
199         }
200     }
201
202     CorbaMessageMediator messageMediator = (CorbaMessageMediator)
203         contactInfo.createMessageMediator(
204             orb, contactInfo, connection, opName, isOneWay);
205     if (orb.subcontractDebugFlag) {
206         dprint(".beginRequest: " + opAndId(messageMediator)
207            + ": created message mediator: " + messageMediator);
208     }
209
210         // NOTE: Thread data so we can get the mediator in release reply
211
// in order to remove the waiter in CorbaConnection.
212
// We cannot depend on obtaining information in releaseReply
213
// via its InputStream argument since, on certain errors
214
// (e.g., client marshaling errors), the stream may be null.
215
// Likewise for releaseReply "self".
216
// NOTE: This must be done before initializing the message since
217
// that may start sending fragments which may end up in "early"
218
// replies or client marshaling exceptions.
219

220         orb.getInvocationInfo().setMessageMediator(messageMediator);
221
222     if (connection != null && connection.getCodeSetContext() == null) {
223         performCodeSetNegotiation(messageMediator);
224     }
225
226     addServiceContexts(messageMediator);
227
228     OutputObject outputObject =
229         contactInfo.createOutputObject(messageMediator);
230     if (orb.subcontractDebugFlag) {
231         dprint(".beginRequest: " + opAndId(messageMediator)
232            + ": created output object: " + outputObject);
233     }
234
235
236         // NOTE: Not necessary for oneways, but useful for debugging.
237
// This must be done BEFORE message initialization since fragments
238
// may be sent at that time.
239
registerWaiter(messageMediator);
240
241     // Do connection reclaim now
242
synchronized (lock) {
243         if (contactInfo.isConnectionBased()) {
244         if (contactInfo.shouldCacheConnection()) {
245             OutboundConnectionCache connectionCache =
246                  orb.getTransportManager()
247                 .getOutboundConnectionCache(contactInfo);
248             connectionCache.reclaim();
249         }
250         }
251     }
252
253     orb.getPIHandler().setClientPIInfo(messageMediator);
254     try {
255         // This MUST come before message is initialized so
256
// service contexts may be added by PI because
257
// initial fragments may be sent during message initialization.
258
orb.getPIHandler().invokeClientPIStartingPoint();
259     } catch( RemarshalException JavaDoc e ) {
260         if (orb.subcontractDebugFlag) {
261         dprint(".beginRequest: " + opAndId(messageMediator)
262                + ": Remarshal");
263         }
264
265         // NOTE: We get here because an interceptor raised ForwardRequest
266
// and updated the IOR/Iterator. Since we have a fresh iterator
267
// hasNext should succeed.
268

269         // REVISIT: We should feed ALL interceptor exceptions to
270
// iterator.reportException so it can determine if it wants
271
// to retry. Right now, SystemExceptions will flow to the
272
// client code.
273

274         // REVISIT:
275
// This assumes that interceptors update
276
// ContactInfoList outside of subcontract.
277
// Want to move that update to here.
278
if (getContactInfoListIterator(orb).hasNext()) {
279         contactInfo = (ContactInfo)
280             getContactInfoListIterator(orb).next();
281         return beginRequest(self, opName, isOneWay, contactInfo);
282         } else {
283         ORBUtilSystemException wrapper =
284             ORBUtilSystemException.get(orb,
285                            CORBALogDomains.RPC_PROTOCOL);
286         throw wrapper.remarshalWithNowhereToGo();
287         }
288     }
289
290     messageMediator.initializeMessage();
291     if (orb.subcontractDebugFlag) {
292         dprint(".beginRequest: " + opAndId(messageMediator)
293            + ": initialized message");
294     }
295
296     return outputObject;
297
298       } finally {
299     if (orb.subcontractDebugFlag) {
300         dprint(".beginRequest<-: op/" + opName);
301     }
302       }
303     }
304
305     public InputObject marshalingComplete(java.lang.Object JavaDoc self,
306                       OutputObject outputObject)
307     throws
308         ApplicationException JavaDoc,
309         org.omg.CORBA.portable.RemarshalException JavaDoc
310     {
311     ORB orb = null;
312     CorbaMessageMediator messageMediator = null;
313     try {
314         messageMediator = (CorbaMessageMediator)
315         outputObject.getMessageMediator();
316
317         orb = (ORB) messageMediator.getBroker();
318
319         if (orb.subcontractDebugFlag) {
320         dprint(".marshalingComplete->: " + opAndId(messageMediator));
321         }
322
323         InputObject inputObject =
324         marshalingComplete1(orb, messageMediator);
325
326         return processResponse(orb, messageMediator, inputObject);
327
328     } finally {
329         if (orb.subcontractDebugFlag) {
330         dprint(".marshalingComplete<-: " + opAndId(messageMediator));
331         }
332     }
333     }
334
335     public InputObject marshalingComplete1(
336             ORB orb, CorbaMessageMediator messageMediator)
337     throws
338         ApplicationException JavaDoc,
339         org.omg.CORBA.portable.RemarshalException JavaDoc
340     {
341     try {
342         messageMediator.finishSendingRequest();
343
344         if (orb.subcontractDebugFlag) {
345         dprint(".marshalingComplete: " + opAndId(messageMediator)
346                + ": finished sending request");
347         }
348
349         return messageMediator.waitForResponse();
350
351     } catch (RuntimeException JavaDoc e) {
352
353         if (orb.subcontractDebugFlag) {
354         dprint(".marshalingComplete: " + opAndId(messageMediator)
355                + ": exception: " + e.toString());
356         }
357
358         boolean retry =
359         getContactInfoListIterator(orb)
360                 .reportException(messageMediator.getContactInfo(), e);
361         if (retry) {
362         // Must run interceptor end point before retrying.
363
Exception JavaDoc newException =
364             orb.getPIHandler().invokeClientPIEndingPoint(
365                         ReplyMessage.SYSTEM_EXCEPTION, e);
366         if (newException == e) {
367             continueOrThrowSystemOrRemarshal(messageMediator,
368                              new RemarshalException JavaDoc());
369         } else {
370             continueOrThrowSystemOrRemarshal(messageMediator,
371                              newException);
372         }
373         } else {
374         // NOTE: Interceptor ending point will run in releaseReply.
375
throw e;
376         }
377         return null; // for compiler
378
}
379     }
380
381     protected InputObject processResponse(ORB orb,
382                       CorbaMessageMediator messageMediator,
383                       InputObject inputObject)
384     throws
385         ApplicationException JavaDoc,
386         org.omg.CORBA.portable.RemarshalException JavaDoc
387     {
388     ORBUtilSystemException wrapper =
389         ORBUtilSystemException.get( orb,
390         CORBALogDomains.RPC_PROTOCOL ) ;
391
392     if (orb.subcontractDebugFlag) {
393         dprint(".processResponse: " + opAndId(messageMediator)
394            + ": response received");
395     }
396
397         // We know for sure now that we've sent a message.
398
// So OK to not send initial again.
399
if (messageMediator.getConnection() != null) {
400             ((CorbaConnection)messageMediator.getConnection())
401         .setPostInitialContexts();
402         }
403
404         // NOTE: not necessary to set MessageMediator for PI.
405
// It already has it.
406

407     // Process the response.
408

409         Exception JavaDoc exception = null;
410
411         if (messageMediator.isOneWay()) {
412         getContactInfoListIterator(orb)
413         .reportSuccess(messageMediator.getContactInfo());
414             // Invoke Portable Interceptors with receive_other
415
exception = orb.getPIHandler().invokeClientPIEndingPoint(
416                 ReplyMessage.NO_EXCEPTION, exception );
417             continueOrThrowSystemOrRemarshal(messageMediator, exception);
418             return null;
419         }
420
421     consumeServiceContexts(orb, messageMediator);
422
423     // Now that we have the service contexts processed and the
424
// correct ORBVersion set, we must finish initializing the stream.
425
// REVISIT - need interface for this operation.
426
((CDRInputObject)inputObject).performORBVersionSpecificInit();
427
428         if (messageMediator.isSystemExceptionReply()) {
429
430             SystemException JavaDoc se = messageMediator.getSystemExceptionReply();
431
432         if (orb.subcontractDebugFlag) {
433         dprint(".processResponse: " + opAndId(messageMediator)
434                + ": received system exception: " + se);
435         }
436
437         boolean doRemarshal =
438             getContactInfoListIterator(orb)
439             .reportException(messageMediator.getContactInfo(), se);
440
441             if (doRemarshal) {
442                     
443         // Invoke Portable Interceptors with receive_exception:
444
exception = orb.getPIHandler().invokeClientPIEndingPoint(
445                     ReplyMessage.SYSTEM_EXCEPTION, se );
446
447         // If PI did not change the exception, throw a
448
// Remarshal.
449
if( se == exception ) {
450             // exception = null is to maintain symmetry with
451
// GenericPOAClientSC.
452
exception = null;
453             continueOrThrowSystemOrRemarshal(messageMediator,
454                              new RemarshalException JavaDoc());
455             throw wrapper.statementNotReachable1() ;
456                 } else {
457             // Otherwise, throw the exception PI wants thrown.
458
continueOrThrowSystemOrRemarshal(messageMediator,
459                              exception);
460             throw wrapper.statementNotReachable2() ;
461                 }
462             }
463
464         // No retry, so see if was unknown.
465

466             ServiceContexts contexts =
467         messageMediator.getReplyServiceContexts();
468             if (contexts != null) {
469         UEInfoServiceContext usc =
470             (UEInfoServiceContext)
471             contexts.get(UEInfoServiceContext.SERVICE_CONTEXT_ID);
472
473         if (usc != null) {
474             Throwable JavaDoc unknown = usc.getUE() ;
475             UnknownException JavaDoc ue = new UnknownException JavaDoc(unknown);
476
477             // Invoke Portable Interceptors with receive_exception:
478
exception = orb.getPIHandler().invokeClientPIEndingPoint(
479             ReplyMessage.SYSTEM_EXCEPTION, ue );
480
481             continueOrThrowSystemOrRemarshal(messageMediator, exception);
482             throw wrapper.statementNotReachable3() ;
483         }
484             }
485
486         // It was not a comm failure nor unknown.
487
// This is the general case.
488

489             // Invoke Portable Interceptors with receive_exception:
490
exception = orb.getPIHandler().invokeClientPIEndingPoint(
491                 ReplyMessage.SYSTEM_EXCEPTION, se );
492
493             continueOrThrowSystemOrRemarshal(messageMediator, exception);
494
495             // Note: We should never need to execute this line, but
496
// we should assert in case exception is null somehow.
497
throw wrapper.statementNotReachable4() ;
498         } else if (messageMediator.isUserExceptionReply()) {
499
500         if (orb.subcontractDebugFlag) {
501         dprint(".processResponse: " + opAndId(messageMediator)
502                + ": received user exception");
503         }
504
505         getContactInfoListIterator(orb)
506         .reportSuccess(messageMediator.getContactInfo());
507
508         String JavaDoc exceptionRepoId = peekUserExceptionId(inputObject);
509         Exception JavaDoc newException = null;
510
511         if (messageMediator.isDIIRequest()) {
512         exception = messageMediator.unmarshalDIIUserException(
513                                 exceptionRepoId, (InputStream JavaDoc)inputObject);
514         newException = orb.getPIHandler().invokeClientPIEndingPoint(
515                        ReplyMessage.USER_EXCEPTION, exception );
516         messageMediator.setDIIException(newException);
517         
518         } else {
519         ApplicationException JavaDoc appException =
520             new ApplicationException JavaDoc(
521                         exceptionRepoId,
522             (org.omg.CORBA.portable.InputStream JavaDoc)inputObject);
523         exception = appException;
524         newException = orb.getPIHandler().invokeClientPIEndingPoint(
525                                    ReplyMessage.USER_EXCEPTION, appException );
526         }
527
528             if (newException != exception) {
529                 continueOrThrowSystemOrRemarshal(messageMediator,newException);
530             }
531
532         if (newException instanceof ApplicationException JavaDoc) {
533         throw (ApplicationException JavaDoc)newException;
534         }
535         // For DII:
536
// This return will be ignored - already unmarshaled above.
537
return inputObject;
538
539         } else if (messageMediator.isLocationForwardReply()) {
540
541         if (orb.subcontractDebugFlag) {
542         dprint(".processResponse: " + opAndId(messageMediator)
543                + ": received location forward");
544         }
545         
546         // NOTE: Expects iterator to update target IOR
547
getContactInfoListIterator(orb).reportRedirect(
548             (CorbaContactInfo)messageMediator.getContactInfo(),
549             messageMediator.getForwardedIOR());
550
551             // Invoke Portable Interceptors with receive_other:
552
Exception JavaDoc newException = orb.getPIHandler().invokeClientPIEndingPoint(
553         ReplyMessage.LOCATION_FORWARD, null );
554
555         if( !(newException instanceof RemarshalException JavaDoc) ) {
556         exception = newException;
557         }
558
559             // If PI did not change exception, throw Remarshal, else
560
// throw the exception PI wants thrown.
561
// KMC: GenericPOAClientSC did not check exception != null
562
if( exception != null ) {
563                 continueOrThrowSystemOrRemarshal(messageMediator, exception);
564             }
565         continueOrThrowSystemOrRemarshal(messageMediator,
566                          new RemarshalException JavaDoc());
567         throw wrapper.statementNotReachable5() ;
568
569         } else if (messageMediator.isDifferentAddrDispositionRequestedReply()){
570
571         if (orb.subcontractDebugFlag) {
572         dprint(".processResponse: " + opAndId(messageMediator)
573                + ": received different addressing dispostion request");
574         }
575
576             // Set the desired target addressing disposition.
577
getContactInfoListIterator(orb).reportAddrDispositionRetry(
578             (CorbaContactInfo)messageMediator.getContactInfo(),
579                 messageMediator.getAddrDispositionReply());
580
581             // Invoke Portable Interceptors with receive_other:
582
Exception JavaDoc newException = orb.getPIHandler().invokeClientPIEndingPoint(
583         ReplyMessage.NEEDS_ADDRESSING_MODE, null);
584
585             // For consistency with corresponding code in GenericPOAClientSC:
586
if( !(newException instanceof RemarshalException JavaDoc) ) {
587         exception = newException;
588         }
589
590             // If PI did not change exception, throw Remarshal, else
591
// throw the exception PI wants thrown.
592
// KMC: GenericPOAClientSC did not include exception != null check
593
if( exception != null ) {
594                 continueOrThrowSystemOrRemarshal(messageMediator, exception);
595             }
596         continueOrThrowSystemOrRemarshal(messageMediator,
597                          new RemarshalException JavaDoc());
598         throw wrapper.statementNotReachable6() ;
599         } else /* normal response */ {
600
601         if (orb.subcontractDebugFlag) {
602         dprint(".processResponse: " + opAndId(messageMediator)
603                + ": received normal response");
604         }
605
606         getContactInfoListIterator(orb)
607         .reportSuccess(messageMediator.getContactInfo());
608
609         messageMediator.handleDIIReply((InputStream JavaDoc)inputObject);
610
611             // Invoke Portable Interceptors with receive_reply:
612
exception = orb.getPIHandler().invokeClientPIEndingPoint(
613                 ReplyMessage.NO_EXCEPTION, null );
614
615             // Remember: not thrown if exception is null.
616
continueOrThrowSystemOrRemarshal(messageMediator, exception);
617
618             return inputObject;
619         }
620     }
621
622     // Filters the given exception into a SystemException or a
623
// RemarshalException and throws it. Assumes the given exception is
624
// of one of these two types. This is a utility method for
625
// the above invoke code which must do this numerous times.
626
// If the exception is null, no exception is thrown.
627
//
628
// Note that this code is duplicated in GenericPOAClientSC.java
629
protected void continueOrThrowSystemOrRemarshal(
630         CorbaMessageMediator messageMediator, Exception JavaDoc exception)
631         throws
632         SystemException JavaDoc, RemarshalException JavaDoc
633     {
634
635     ORB orb = (ORB) messageMediator.getBroker();
636
637         if( exception == null ) {
638
639             // do nothing.
640

641         } else if( exception instanceof RemarshalException JavaDoc ) {
642
643         // REVISIT - unify with PI handling
644
orb.getInvocationInfo().setIsRetryInvocation(true);
645
646         // NOTE - We must unregister the waiter NOW for this request
647
// since the retry will result in a new request id. Therefore
648
// the old request id would be lost and we would have a memory
649
// leak in the responseWaitingRoom.
650
unregisterWaiter(orb);
651
652         if (orb.subcontractDebugFlag) {
653         dprint(".continueOrThrowSystemOrRemarshal: "
654                + opAndId(messageMediator)
655                + ": throwing Remarshal");
656         }
657
658             throw (RemarshalException JavaDoc)exception;
659
660         } else {
661
662         if (orb.subcontractDebugFlag) {
663         dprint(".continueOrThrowSystemOrRemarshal: "
664                + opAndId(messageMediator)
665                + ": throwing sex:"
666                + exception);
667         }
668
669             throw (SystemException JavaDoc)exception;
670         }
671     }
672
673     protected CorbaContactInfoListIterator getContactInfoListIterator(ORB orb)
674     {
675     return (CorbaContactInfoListIterator)
676         ((CorbaInvocationInfo)orb.getInvocationInfo())
677             .getContactInfoListIterator();
678     }
679
680     protected void registerWaiter(CorbaMessageMediator messageMediator)
681     {
682     if (messageMediator.getConnection() != null) {
683         messageMediator.getConnection().registerWaiter(messageMediator);
684     }
685     }
686
687     protected void unregisterWaiter(ORB orb)
688     {
689     MessageMediator messageMediator =
690         orb.getInvocationInfo().getMessageMediator();
691     if (messageMediator!=null && messageMediator.getConnection() != null) {
692         // REVISIT:
693
// The messageMediator may be null if COMM_FAILURE before
694
// it is created.
695
messageMediator.getConnection().unregisterWaiter(messageMediator);
696     }
697     }
698
699     protected void addServiceContexts(CorbaMessageMediator messageMediator)
700     {
701     ORB orb = (ORB)messageMediator.getBroker();
702     CorbaConnection c = (CorbaConnection) messageMediator.getConnection();
703     GIOPVersion giopVersion = messageMediator.getGIOPVersion();
704
705     ServiceContexts contexts = messageMediator.getRequestServiceContexts();
706
707         addCodeSetServiceContext(c, contexts, giopVersion);
708
709         // Add the RMI-IIOP max stream format version
710
// service context to every request. Once we have GIOP 1.3,
711
// we could skip it since we now support version 2, but
712
// probably safer to always send it.
713
contexts.put(MaxStreamFormatVersionServiceContext.singleton);
714
715     // ORBVersion servicecontext needs to be sent
716
ORBVersionServiceContext ovsc = new ORBVersionServiceContext(
717                     ORBVersionFactory.getORBVersion() ) ;
718     contexts.put( ovsc ) ;
719
720     // NOTE : We only want to send the runtime context the first time
721
if ((c != null) && !c.isPostInitialContexts()) {
722             // Do not do c.setPostInitialContexts() here.
723
// If a client interceptor send_request does a ForwardRequest
724
// which ends up using the same connection then the service
725
// context would not be sent.
726
SendingContextServiceContext scsc =
727         new SendingContextServiceContext( orb.getFVDCodeBaseIOR() ) ; //d11638
728
contexts.put( scsc ) ;
729     }
730     }
731
732     protected void consumeServiceContexts(ORB orb,
733                     CorbaMessageMediator messageMediator)
734     {
735     ServiceContexts ctxts = messageMediator.getReplyServiceContexts();
736     ServiceContext sc ;
737     ORBUtilSystemException wrapper = ORBUtilSystemException.get( orb,
738         CORBALogDomains.RPC_PROTOCOL ) ;
739
740         if (ctxts == null) {
741             return; // no service context available, return gracefully.
742
}
743
744     sc = ctxts.get( SendingContextServiceContext.SERVICE_CONTEXT_ID ) ;
745
746     if (sc != null) {
747         SendingContextServiceContext scsc =
748         (SendingContextServiceContext)sc ;
749         IOR ior = scsc.getIOR() ;
750
751         try {
752         // set the codebase returned by the server
753
if (messageMediator.getConnection() != null) {
754             ((CorbaConnection)messageMediator.getConnection()).setCodeBaseIOR(ior);
755         }
756         } catch (ThreadDeath JavaDoc td) {
757         throw td ;
758         } catch (Throwable JavaDoc t) {
759         throw wrapper.badStringifiedIor( t ) ;
760         }
761     }
762
763     // see if the version subcontract is present, if yes, then set
764
// the ORBversion
765
sc = ctxts.get( ORBVersionServiceContext.SERVICE_CONTEXT_ID ) ;
766
767     if (sc != null) {
768         ORBVersionServiceContext ovsc =
769            (ORBVersionServiceContext) sc;
770
771         ORBVersion version = ovsc.getVersion();
772         orb.setORBVersion( version ) ;
773     }
774
775     getExceptionDetailMessage(messageMediator, wrapper);
776     }
777
778     protected void getExceptionDetailMessage(
779         CorbaMessageMediator messageMediator,
780     ORBUtilSystemException wrapper)
781     {
782     ServiceContext sc = messageMediator.getReplyServiceContexts()
783         .get(ExceptionDetailMessage.value);
784     if (sc == null)
785         return ;
786
787     if (! (sc instanceof UnknownServiceContext)) {
788         throw wrapper.badExceptionDetailMessageServiceContextType();
789     }
790     byte[] data = ((UnknownServiceContext)sc).getData();
791     EncapsInputStream in =
792         new EncapsInputStream((ORB)messageMediator.getBroker(),
793                   data, data.length);
794     in.consumeEndian();
795
796     String JavaDoc msg =
797           "----------BEGIN server-side stack trace----------\n"
798         + in.read_wstring() + "\n"
799         + "----------END server-side stack trace----------";
800
801     messageMediator.setReplyExceptionDetailMessage(msg);
802     }
803
804     public void endRequest(Broker broker, Object JavaDoc self, InputObject inputObject)
805     {
806     ORB orb = (ORB)broker ;
807
808     try {
809         if (orb.subcontractDebugFlag) {
810         dprint(".endRequest->");
811         }
812
813         // Note: the inputObject may be null if an error occurs
814
// in request or before _invoke returns.
815
// Note: self may be null also (e.g., compiler generates null in stub).
816

817         MessageMediator messageMediator =
818         orb.getInvocationInfo().getMessageMediator();
819         if (messageMediator != null)
820             {
821                 if (messageMediator.getConnection() != null)
822                 {
823                     ((CorbaMessageMediator)messageMediator)
824                               .sendCancelRequestIfFinalFragmentNotSent();
825                 }
826
827                 // Release any outstanding NIO ByteBuffers to the ByteBufferPool
828

829                 InputObject inputObj = messageMediator.getInputObject();
830                 if (inputObj != null) {
831                     inputObj.close();
832                 }
833
834                 OutputObject outputObj = messageMediator.getOutputObject();
835                 if (outputObj != null) {
836                     outputObj.close();
837                 }
838
839             }
840
841         // XREVISIT NOTE - Assumes unregistering the waiter for
842
// location forwards has already happened somewhere else.
843
// The code below is only going to unregister the final successful
844
// request.
845

846         // NOTE: In the case of a recursive stack of endRequests in a
847
// finally block (because of Remarshal) only the first call to
848
// unregisterWaiter will remove the waiter. The rest will be
849
// noops.
850
unregisterWaiter(orb);
851
852         // Invoke Portable Interceptors cleanup. This is done to handle
853
// exceptions during stream marshaling. More generally, exceptions
854
// that occur in the ORB after send_request (which includes
855
// after returning from _request) before _invoke:
856
orb.getPIHandler().cleanupClientPIRequest();
857
858         // REVISIT: Early replies?
859
} catch (IOException JavaDoc ex) {
860             // See CDRInput/OutputObject.close() for more info.
861
// This won't result in a Corba error if an IOException happens.
862
if (orb.subcontractDebugFlag)
863             {
864             dprint(".endRequest: ignoring IOException - " + ex.toString());
865             }
866     } finally {
867         if (orb.subcontractDebugFlag) {
868         dprint(".endRequest<-");
869         }
870     }
871     }
872
873
874     protected void performCodeSetNegotiation(CorbaMessageMediator messageMediator)
875     {
876     CorbaConnection conn =
877         (CorbaConnection) messageMediator.getConnection();
878     IOR ior =
879         ((CorbaContactInfo)messageMediator.getContactInfo())
880         .getEffectiveTargetIOR();
881     GIOPVersion giopVersion = messageMediator.getGIOPVersion();
882
883     // XXX This seems to be a broken double checked locking idiom: FIX IT!
884

885         // conn.getCodeSetContext() is null when no other requests have
886
// been made on this connection to trigger code set negotation.
887
if (conn != null &&
888             conn.getCodeSetContext() == null &&
889             !giopVersion.equals(GIOPVersion.V1_0)) {
890                         
891             synchronized(conn) {
892                 // Double checking. Don't let any other
893
// threads use this connection until the
894
// code sets are straight.
895
if (conn.getCodeSetContext() != null)
896                     return;
897                 
898                 // This only looks at the first code set component. If
899
// there can be multiple locations with multiple code sets,
900
// this requires more work.
901
IIOPProfileTemplate temp =
902             (IIOPProfileTemplate)ior.getProfile().
903             getTaggedProfileTemplate();
904                 Iterator JavaDoc iter = temp.iteratorById(TAG_CODE_SETS.value);
905                 if (!iter.hasNext()) {
906                     // Didn't have a code set component. The default will
907
// be to use ISO8859-1 for char data and throw an
908
// exception if wchar data is used.
909
return;
910                 }
911
912                 // Get the native and conversion code sets the
913
// server specified in its IOR
914
CodeSetComponentInfo serverCodeSets
915                     = ((CodeSetsComponent)iter.next()).getCodeSetComponentInfo();
916
917                 // Perform the negotiation between this ORB's code sets and
918
// the ones from the IOR
919
CodeSetComponentInfo.CodeSetContext result
920                     = CodeSetConversion.impl().negotiate(
921                           conn.getBroker().getORBData().getCodeSetComponentInfo(),
922               serverCodeSets);
923                 
924                 conn.setCodeSetContext(result);
925             }
926         }
927     }
928
929     protected void addCodeSetServiceContext(CorbaConnection conn,
930                                           ServiceContexts ctxs,
931                                           GIOPVersion giopVersion) {
932
933         // REVISIT. OMG issue 3318 concerning sending the code set
934
// service context more than once was deemed too much for the
935
// RTF. Here's our strategy for the moment:
936
//
937
// Send it on every request (necessary in cases of fragmentation
938
// with multithreaded clients or when the first thing on a
939
// connection is a LocateRequest). Provide an ORB property
940
// to disable multiple sends.
941
//
942
// Note that the connection is null in the local case and no
943
// service context is included. We use the ORB provided
944
// encapsulation streams.
945
//
946
// Also, there will be no negotiation or service context
947
// in GIOP 1.0. ISO8859-1 is used for char/string, and
948
// wchar/wstring are illegal.
949
//
950
if (giopVersion.equals(GIOPVersion.V1_0) || conn == null)
951             return;
952         
953         CodeSetComponentInfo.CodeSetContext codeSetCtx = null;
954
955         if (conn.getBroker().getORBData().alwaysSendCodeSetServiceContext() ||
956             !conn.isPostInitialContexts()) {
957
958             // Get the negotiated code sets (if any) out of the connection
959
codeSetCtx = conn.getCodeSetContext();
960         }
961
962         // Either we shouldn't send the code set service context, or
963
// for some reason, the connection doesn't have its code sets.
964
// Perhaps the server didn't include them in the IOR. Uses
965
// ISO8859-1 for char and makes wchar/wstring illegal.
966
if (codeSetCtx == null)
967             return;
968
969         CodeSetServiceContext cssc = new CodeSetServiceContext(codeSetCtx);
970     ctxs.put(cssc);
971     }
972
973     protected String JavaDoc peekUserExceptionId(InputObject inputObject)
974     {
975     CDRInputObject cdrInputObject = (CDRInputObject) inputObject;
976     // REVISIT - need interface for mark/reset
977
cdrInputObject.mark(Integer.MAX_VALUE);
978         String JavaDoc result = cdrInputObject.read_string();
979     cdrInputObject.reset();
980         return result;
981     }
982
983     protected void dprint(String JavaDoc msg)
984     {
985     ORBUtility.dprint("CorbaClientRequestDispatcherImpl", msg);
986     }
987
988     protected String JavaDoc opAndId(CorbaMessageMediator mediator)
989     {
990     return ORBUtility.operationNameAndRequestId(mediator);
991     }
992 }
993
994 // End of file.
995
Popular Tags