KickJava   Java API By Example, From Geeks To Geeks.

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


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

15
16
17 package com.sun.corba.se.impl.protocol;
18
19 import org.omg.PortableServer.Servant JavaDoc ;
20
21 import org.omg.CORBA.SystemException JavaDoc;
22 import org.omg.CORBA.INTERNAL JavaDoc;
23 import org.omg.CORBA.UNKNOWN JavaDoc;
24 import org.omg.CORBA.CompletionStatus JavaDoc;
25 import org.omg.CORBA.Any JavaDoc;
26
27 import org.omg.CORBA.portable.InvokeHandler JavaDoc;
28 import org.omg.CORBA.portable.InputStream JavaDoc;
29 import org.omg.CORBA.portable.OutputStream JavaDoc;
30 import org.omg.CORBA.portable.UnknownException JavaDoc;
31 import org.omg.CORBA.portable.ResponseHandler JavaDoc;
32
33 import com.sun.org.omg.SendingContext.CodeBase;
34
35 import com.sun.corba.se.pept.encoding.OutputObject;
36 import com.sun.corba.se.pept.protocol.MessageMediator;
37
38 import com.sun.corba.se.spi.orb.ORB;
39 import com.sun.corba.se.spi.orb.ORBVersion;
40 import com.sun.corba.se.spi.orb.ORBVersionFactory;
41 import com.sun.corba.se.spi.ior.IOR ;
42 import com.sun.corba.se.spi.ior.ObjectKey;
43 import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
44 import com.sun.corba.se.spi.ior.ObjectAdapterId;
45 import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
46 import com.sun.corba.se.spi.oa.ObjectAdapter;
47 import com.sun.corba.se.spi.oa.OAInvocationInfo;
48 import com.sun.corba.se.spi.oa.OADestroyed;
49 import com.sun.corba.se.spi.oa.NullServant;
50 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
51 import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
52 import com.sun.corba.se.spi.protocol.ForwardException ;
53 import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
54 import com.sun.corba.se.spi.transport.CorbaConnection;
55 import com.sun.corba.se.spi.logging.CORBALogDomains;
56 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
57
58 import com.sun.corba.se.impl.protocol.SpecialMethod ;
59 import com.sun.corba.se.spi.servicecontext.ServiceContext;
60 import com.sun.corba.se.spi.servicecontext.ServiceContexts;
61 import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
62 import com.sun.corba.se.spi.servicecontext.CodeSetServiceContext;
63 import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
64 import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
65
66 import com.sun.corba.se.impl.corba.ServerRequestImpl ;
67 import com.sun.corba.se.impl.encoding.MarshalInputStream;
68 import com.sun.corba.se.impl.encoding.MarshalOutputStream;
69 import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
70 import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
71 import com.sun.corba.se.impl.orbutil.ORBConstants;
72 import com.sun.corba.se.impl.orbutil.ORBUtility;
73 import com.sun.corba.se.impl.protocol.RequestCanceledException;
74 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
75 import com.sun.corba.se.impl.logging.POASystemException;
76
77 public class CorbaServerRequestDispatcherImpl
78     implements CorbaServerRequestDispatcher
79 {
80     protected ORB orb; // my ORB instance
81
private ORBUtilSystemException wrapper ;
82     private POASystemException poaWrapper ;
83
84     // Added from last version because it broke the build - RTW
85
// XXX remove me and rebuild: probably no longer needed
86
// public static final int UNKNOWN_EXCEPTION_INFO_ID = 9;
87

88     public CorbaServerRequestDispatcherImpl(ORB orb)
89     {
90     this.orb = orb;
91     wrapper = ORBUtilSystemException.get( orb,
92         CORBALogDomains.RPC_PROTOCOL ) ;
93     poaWrapper = POASystemException.get( orb,
94         CORBALogDomains.RPC_PROTOCOL ) ;
95     }
96
97     /** XXX/REVISIT:
98      * We do not want to look for a servant in the POA/ServantManager case,
99      * but we could in most other cases. The OA could have a method that
100      * returns true if the servant MAY exist, and false only if the servant
101      * definitely DOES NOT exist.
102      *
103      * XXX/REVISIT:
104      * We may wish to indicate OBJECT_HERE by some mechanism other than
105      * returning a null result.
106      *
107      * Called from ORB.locate when a LocateRequest arrives.
108      * Result is not always absolutely correct: may indicate OBJECT_HERE
109      * for non-existent objects, which is resolved on invocation. This
110      * "bug" is unavoidable, since in general the object may be destroyed
111      * between a locate and a request. Note that this only checks that
112      * the appropriate ObjectAdapter is available, not that the servant
113      * actually exists.
114      * Need to signal one of OBJECT_HERE, OBJECT_FORWARD, OBJECT_NOT_EXIST.
115      * @return Result is null if object is (possibly) implemented here, otherwise
116      * an IOR indicating objref to forward the request to.
117      * @exception OBJECT_NOT_EXIST is thrown if we know the object does not
118      * exist here, and we are not forwarding.
119      */

120     public IOR locate(ObjectKey okey)
121     {
122     try {
123         if (orb.subcontractDebugFlag)
124         dprint(".locate->");
125
126         ObjectKeyTemplate oktemp = okey.getTemplate() ;
127
128         try {
129         checkServerId(okey);
130         } catch (ForwardException fex) {
131         return fex.getIOR() ;
132         }
133
134         // Called only for its side-effect of throwing appropriate exceptions
135
findObjectAdapter(oktemp);
136
137         return null ;
138     } finally {
139         if (orb.subcontractDebugFlag)
140         dprint(".locate<-");
141     }
142     }
143
144     public void dispatch(MessageMediator messageMediator)
145     {
146     CorbaMessageMediator request = (CorbaMessageMediator) messageMediator;
147     try {
148         if (orb.subcontractDebugFlag) {
149         dprint(".dispatch->: " + opAndId(request));
150         }
151
152         // to set the codebase information, if any transmitted; and also
153
// appropriate ORB Version.
154
consumeServiceContexts(request);
155
156         // Now that we have the service contexts processed and the
157
// correct ORBVersion set, we must finish initializing the
158
// stream.
159
((MarshalInputStream)request.getInputObject())
160         .performORBVersionSpecificInit();
161
162         ObjectKey okey = request.getObjectKey();
163
164         // Check that this server is the right server
165
try {
166         checkServerId(okey);
167         } catch (ForwardException fex) {
168         if (orb.subcontractDebugFlag) {
169             dprint(".dispatch: " + opAndId(request)
170                + ": bad server id");
171         }
172
173         request.getProtocolHandler()
174             .createLocationForward(request, fex.getIOR(), null);
175         return;
176         }
177
178         String JavaDoc operation = request.getOperationName();
179         ObjectAdapter objectAdapter = null ;
180
181         try {
182         byte[] objectId = okey.getId().getId() ;
183         ObjectKeyTemplate oktemp = okey.getTemplate() ;
184         objectAdapter = findObjectAdapter(oktemp);
185
186         java.lang.Object JavaDoc servant = getServantWithPI(request, objectAdapter,
187             objectId, oktemp, operation);
188
189         dispatchToServant(servant, request, objectId, objectAdapter);
190         } catch (ForwardException ex) {
191         if (orb.subcontractDebugFlag) {
192             dprint(".dispatch: " + opAndId(request)
193                + ": ForwardException caught");
194         }
195
196         // Thrown by Portable Interceptors from InterceptorInvoker,
197
// through Response constructor.
198
request.getProtocolHandler()
199             .createLocationForward(request, ex.getIOR(), null);
200         } catch (OADestroyed ex) {
201         if (orb.subcontractDebugFlag) {
202             dprint(".dispatch: " + opAndId(request)
203                + ": OADestroyed exception caught");
204         }
205
206         // DO NOT CALL THIS HERE:
207
// releaseServant(objectAdapter);
208
// The problem is that OADestroyed is only thrown by oa.enter, in
209
// which case oa.exit should NOT be called, and neither should
210
// the invocationInfo stack be popped.
211

212         // Destroyed POAs can be recreated by normal adapter activation.
213
// So just restart the dispatch.
214
dispatch(request);
215         } catch (RequestCanceledException ex) {
216         if (orb.subcontractDebugFlag) {
217             dprint(".dispatch: " + opAndId(request)
218                + ": RequestCanceledException caught");
219         }
220
221         // IDLJ generated non-tie based skeletons do not catch the
222
// RequestCanceledException. Rethrow the exception, which will
223
// cause the worker thread to unwind the dispatch and wait for
224
// other requests.
225
throw ex;
226         } catch (UnknownException JavaDoc ex) {
227         if (orb.subcontractDebugFlag) {
228             dprint(".dispatch: " + opAndId(request)
229                + ": UnknownException caught " + ex);
230         }
231
232         // RMIC generated tie skeletons convert all Throwable exception
233
// types (including RequestCanceledException, ThreadDeath)
234
// thrown during reading fragments into UnknownException.
235
// If RequestCanceledException was indeed raised,
236
// then rethrow it, which will eventually cause the worker
237
// thread to unstack the dispatch and wait for other requests.
238
if (ex.originalEx instanceof RequestCanceledException) {
239             throw (RequestCanceledException) ex.originalEx;
240         }
241
242         ServiceContexts contexts = new ServiceContexts(orb);
243         UEInfoServiceContext usc = new UEInfoServiceContext(
244             ex.originalEx);
245
246         contexts.put( usc ) ;
247
248         SystemException JavaDoc sysex = wrapper.unknownExceptionInDispatch(
249             CompletionStatus.COMPLETED_MAYBE, ex ) ;
250         request.getProtocolHandler()
251             .createSystemExceptionResponse(request, sysex,
252             contexts);
253         } catch (Throwable JavaDoc ex) {
254         if (orb.subcontractDebugFlag) {
255             dprint(".dispatch: " + opAndId(request)
256                + ": other exception " + ex);
257         }
258         request.getProtocolHandler()
259             .handleThrowableDuringServerDispatch(
260                         request, ex, CompletionStatus.COMPLETED_MAYBE);
261         }
262         return;
263     } finally {
264         if (orb.subcontractDebugFlag) {
265         dprint(".dispatch<-: " + opAndId(request));
266         }
267     }
268     }
269
270     private void releaseServant(ObjectAdapter objectAdapter)
271     {
272     try {
273         if (orb.subcontractDebugFlag) {
274         dprint(".releaseServant->");
275         }
276
277         if (objectAdapter == null) {
278         if (orb.subcontractDebugFlag) {
279             dprint(".releaseServant: null object adapter");
280         }
281         return ;
282         }
283
284         try {
285         objectAdapter.returnServant();
286         } finally {
287         objectAdapter.exit();
288         orb.popInvocationInfo() ;
289         }
290     } finally {
291         if (orb.subcontractDebugFlag) {
292         dprint(".releaseServant<-");
293         }
294     }
295     }
296
297     // Note that objectAdapter.enter() must be called before getServant.
298
private java.lang.Object JavaDoc getServant(ObjectAdapter objectAdapter, byte[] objectId,
299     String JavaDoc operation)
300     throws OADestroyed
301     {
302     try {
303         if (orb.subcontractDebugFlag) {
304         dprint(".getServant->");
305         }
306
307         OAInvocationInfo info = objectAdapter.makeInvocationInfo(objectId);
308         info.setOperation(operation);
309         orb.pushInvocationInfo(info);
310         objectAdapter.getInvocationServant(info);
311         return info.getServantContainer() ;
312     } finally {
313         if (orb.subcontractDebugFlag) {
314         dprint(".getServant<-");
315         }
316     }
317     }
318
319     protected java.lang.Object JavaDoc getServantWithPI(CorbaMessageMediator request,
320                          ObjectAdapter objectAdapter,
321     byte[] objectId, ObjectKeyTemplate oktemp, String JavaDoc operation)
322     throws OADestroyed
323     {
324     try {
325         if (orb.subcontractDebugFlag) {
326         dprint(".getServantWithPI->");
327         }
328
329         // Prepare Portable Interceptors for a new server request
330
// and invoke receive_request_service_contexts. The starting
331
// point may throw a SystemException or ForwardException.
332
orb.getPIHandler().initializeServerPIInfo(request, objectAdapter,
333         objectId, oktemp);
334         orb.getPIHandler().invokeServerPIStartingPoint();
335
336         objectAdapter.enter() ;
337
338         // This must be set just after the enter so that exceptions thrown by
339
// enter do not cause
340
// the exception reply to pop the thread stack and do an extra oa.exit.
341
if (request != null)
342         request.setExecuteReturnServantInResponseConstructor(true);
343
344         java.lang.Object JavaDoc servant = getServant(objectAdapter, objectId,
345         operation);
346
347         // Note: we do not know the MDI on a null servant.
348
// We only end up in that situation if _non_existent called,
349
// so that the following handleNullServant call does not throw an
350
// exception.
351
String JavaDoc mdi = "unknown" ;
352
353         if (servant instanceof NullServant)
354         handleNullServant(operation, (NullServant)servant);
355         else
356         mdi = objectAdapter.getInterfaces(servant, objectId)[0] ;
357
358         orb.getPIHandler().setServerPIInfo(servant, mdi);
359
360         if (((servant != null) &&
361         !(servant instanceof org.omg.CORBA.DynamicImplementation JavaDoc) &&
362         !(servant instanceof org.omg.PortableServer.DynamicImplementation JavaDoc)) ||
363         (SpecialMethod.getSpecialMethod(operation) != null)) {
364         orb.getPIHandler().invokeServerPIIntermediatePoint();
365         }
366
367         return servant ;
368     } finally {
369         if (orb.subcontractDebugFlag) {
370         dprint(".getServantWithPI<-");
371         }
372     }
373     }
374
375     protected void checkServerId(ObjectKey okey)
376     {
377     try {
378         if (orb.subcontractDebugFlag) {
379         dprint(".checkServerId->");
380         }
381
382         ObjectKeyTemplate oktemp = okey.getTemplate() ;
383         int sId = oktemp.getServerId() ;
384         int scid = oktemp.getSubcontractId() ;
385
386         if (!orb.isLocalServerId(scid, sId)) {
387         if (orb.subcontractDebugFlag) {
388             dprint(".checkServerId: bad server id");
389         }
390
391         orb.handleBadServerId(okey);
392         }
393     } finally {
394         if (orb.subcontractDebugFlag) {
395         dprint(".checkServerId<-");
396         }
397     }
398     }
399
400     private ObjectAdapter findObjectAdapter(ObjectKeyTemplate oktemp)
401     {
402     try {
403         if (orb.subcontractDebugFlag) {
404         dprint(".findObjectAdapter->");
405         }
406
407         RequestDispatcherRegistry scr = orb.getRequestDispatcherRegistry() ;
408         int scid = oktemp.getSubcontractId() ;
409         ObjectAdapterFactory oaf = scr.getObjectAdapterFactory(scid);
410         if (oaf == null) {
411         if (orb.subcontractDebugFlag) {
412             dprint(".findObjectAdapter: failed to find ObjectAdapterFactory");
413         }
414
415         throw wrapper.noObjectAdapterFactory() ;
416         }
417
418         ObjectAdapterId oaid = oktemp.getObjectAdapterId() ;
419         ObjectAdapter oa = oaf.find(oaid);
420
421         if (oa == null) {
422         if (orb.subcontractDebugFlag) {
423             dprint(".findObjectAdapter: failed to find ObjectAdaptor");
424         }
425
426         throw wrapper.badAdapterId() ;
427         }
428
429         return oa ;
430     } finally {
431         if (orb.subcontractDebugFlag) {
432         dprint(".findObjectAdapter<-");
433         }
434     }
435     }
436
437     /** Always throws OBJECT_NOT_EXIST if operation is not a special method.
438     * If operation is _non_existent or _not_existent, this will just
439     * return without performing any action, so that _non_existent can return
440     * false. Always throws OBJECT_NOT_EXIST for any other special method.
441     * Update for issue 4385.
442     */

443     protected void handleNullServant(String JavaDoc operation, NullServant nserv )
444     {
445     try {
446         if (orb.subcontractDebugFlag) {
447         dprint(".handleNullServant->: " + operation);
448         }
449
450         SpecialMethod specialMethod =
451         SpecialMethod.getSpecialMethod(operation);
452
453         if ((specialMethod == null) ||
454         !specialMethod.isNonExistentMethod()) {
455         if (orb.subcontractDebugFlag) {
456             dprint(".handleNullServant: " + operation
457                + ": throwing OBJECT_NOT_EXIST");
458         }
459
460         throw nserv.getException() ;
461         }
462     } finally {
463         if (orb.subcontractDebugFlag) {
464         dprint(".handleNullServant<-: " + operation);
465         }
466     }
467     }
468
469     protected void consumeServiceContexts(CorbaMessageMediator request)
470     {
471     try {
472         if (orb.subcontractDebugFlag) {
473         dprint(".consumeServiceContexts->: "
474                + opAndId(request));
475         }
476
477         ServiceContexts ctxts = request.getRequestServiceContexts();
478         ServiceContext sc ;
479
480         GIOPVersion giopVersion = request.getGIOPVersion();
481
482         // we cannot depend on this since for our local case, we do not send
483
// in this service context. Can we rely on just the CodeSetServiceContext?
484
// boolean rtSC = false; // Runtime ServiceContext
485

486         boolean hasCodeSetContext = processCodeSetContext(request, ctxts);
487
488         if (orb.subcontractDebugFlag) {
489         dprint(".consumeServiceContexts: " + opAndId(request)
490                + ": GIOP version: " + giopVersion);
491         dprint(".consumeServiceContexts: " + opAndId(request)
492                + ": as code set context? " + hasCodeSetContext);
493         }
494
495         sc = ctxts.get(
496         SendingContextServiceContext.SERVICE_CONTEXT_ID ) ;
497
498         if (sc != null) {
499         SendingContextServiceContext scsc =
500             (SendingContextServiceContext)sc ;
501         IOR ior = scsc.getIOR() ;
502
503         try {
504             ((CorbaConnection)request.getConnection())
505             .setCodeBaseIOR(ior);
506         } catch (ThreadDeath JavaDoc td) {
507             throw td ;
508         } catch (Throwable JavaDoc t) {
509             throw wrapper.badStringifiedIor( t ) ;
510         }
511         }
512
513         // the RTSC is sent only once during session establishment. We
514
// need to find out if the CodeBaseRef is already set. If yes,
515
// then also the rtSC flag needs to be set to true
516
// this is not possible for the LocalCase since there is no
517
// IIOPConnection for the LocalCase
518

519         // used for a case where we have JDK 1.3 supporting 1.0 protocol,
520
// but sending 2 service contexts, that is not normal as per
521
// GIOP rules, based on above information, we figure out that we
522
// are talking to the legacy ORB and set the ORB Version Accordingly.
523

524         // this special case tell us that it is legacy SUN orb
525
// and not a foreign one
526
// rtSC is not available for localcase due to which this generic
527
// path would fail if relying on rtSC
528
//if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext && rtSC)
529
boolean isForeignORB = false;
530
531         if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext) {
532         if (orb.subcontractDebugFlag) {
533             dprint(".consumeServiceCOntexts: " + opAndId(request)
534                + ": Determined to be an old Sun ORB");
535         }
536             
537         orb.setORBVersion(ORBVersionFactory.getOLD()) ;
538         // System.out.println("setting legacy ORB version");
539
} else {
540         // If it didn't include our ORB version service context (below),
541
// then it must be a foreign ORB.
542
isForeignORB = true;
543         }
544
545         // try to get the ORBVersion sent as part of the ServiceContext
546
// if any
547
sc = ctxts.get( ORBVersionServiceContext.SERVICE_CONTEXT_ID ) ;
548         if (sc != null) {
549         ORBVersionServiceContext ovsc =
550            (ORBVersionServiceContext) sc;
551
552         ORBVersion version = ovsc.getVersion();
553         orb.setORBVersion(version);
554
555         isForeignORB = false;
556         }
557
558         if (isForeignORB) {
559         if (orb.subcontractDebugFlag) {
560             dprint(".consumeServiceContexts: " + opAndId(request)
561                + ": Determined to be a foreign ORB");
562         }
563
564         orb.setORBVersion(ORBVersionFactory.getFOREIGN());
565         }
566     } finally {
567         if (orb.subcontractDebugFlag) {
568         dprint(".consumeServiceContexts<-: " + opAndId(request));
569         }
570     }
571     }
572     
573     protected CorbaMessageMediator dispatchToServant(
574         java.lang.Object JavaDoc servant,
575     CorbaMessageMediator req,
576     byte[] objectId, ObjectAdapter objectAdapter)
577     {
578     try {
579         if (orb.subcontractDebugFlag) {
580         dprint(".dispatchToServant->: " + opAndId(req));
581         }
582
583         CorbaMessageMediator response = null ;
584
585         String JavaDoc operation = req.getOperationName() ;
586
587         SpecialMethod method = SpecialMethod.getSpecialMethod(operation) ;
588         if (method != null) {
589         if (orb.subcontractDebugFlag) {
590             dprint(".dispatchToServant: " + opAndId(req)
591                + ": Handling special method");
592         }
593
594         response = method.invoke(servant, req, objectId, objectAdapter);
595         return response ;
596         }
597         
598         // Invoke on the servant using the portable DSI skeleton
599
if (servant instanceof org.omg.CORBA.DynamicImplementation JavaDoc) {
600         if (orb.subcontractDebugFlag) {
601             dprint(".dispatchToServant: " + opAndId(req)
602                + ": Handling old style DSI type servant");
603         }
604
605         org.omg.CORBA.DynamicImplementation JavaDoc dynimpl =
606             (org.omg.CORBA.DynamicImplementation JavaDoc)servant;
607         ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
608
609         // Note: When/if dynimpl.invoke calls arguments() or
610
// set_exception() then intermediate points are run.
611
dynimpl.invoke(sreq);
612         
613         response = handleDynamicResult(sreq, req);
614         } else if (servant instanceof org.omg.PortableServer.DynamicImplementation JavaDoc) {
615         if (orb.subcontractDebugFlag) {
616             dprint(".dispatchToServant: " + opAndId(req)
617                + ": Handling POA DSI type servant");
618         }
619
620         org.omg.PortableServer.DynamicImplementation JavaDoc dynimpl =
621             (org.omg.PortableServer.DynamicImplementation JavaDoc)servant;
622         ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
623
624         // Note: When/if dynimpl.invoke calls arguments() or
625
// set_exception() then intermediate points are run.
626
dynimpl.invoke(sreq);
627         
628         response = handleDynamicResult(sreq, req);
629         } else {
630         if (orb.subcontractDebugFlag) {
631             dprint(".dispatchToServant: " + opAndId(req)
632                + ": Handling invoke handler type servant");
633         }
634
635         InvokeHandler JavaDoc invhandle = (InvokeHandler JavaDoc)servant ;
636
637         OutputStream JavaDoc stream =
638             (OutputStream JavaDoc)invhandle._invoke(
639                       operation,
640               (org.omg.CORBA.portable.InputStream JavaDoc)req.getInputObject(),
641               req);
642         response = (CorbaMessageMediator)
643             ((OutputObject)stream).getMessageMediator();
644         }
645
646         return response ;
647     } finally {
648         if (orb.subcontractDebugFlag) {
649         dprint(".dispatchToServant<-: " + opAndId(req));
650         }
651     }
652     }
653
654     protected CorbaMessageMediator handleDynamicResult(
655         ServerRequestImpl sreq,
656     CorbaMessageMediator req)
657     {
658     try {
659         if (orb.subcontractDebugFlag) {
660         dprint(".handleDynamicResult->: " + opAndId(req));
661         }
662
663         CorbaMessageMediator response = null ;
664
665         // Check if ServerRequestImpl.result() has been called
666
Any JavaDoc excany = sreq.checkResultCalled();
667
668         if (excany == null) { // normal return
669
if (orb.subcontractDebugFlag) {
670             dprint(".handleDynamicResult: " + opAndId(req)
671                + ": handling normal result");
672         }
673
674         // Marshal out/inout/return parameters into the ReplyMessage
675
response = sendingReply(req);
676         OutputStream JavaDoc os = (OutputStream JavaDoc) response.getOutputObject();
677         sreq.marshalReplyParams(os);
678         } else {
679         if (orb.subcontractDebugFlag) {
680             dprint(".handleDynamicResult: " + opAndId(req)
681                + ": handling error");
682         }
683
684         response = sendingReply(req, excany);
685         }
686
687         return response ;
688     } finally {
689         if (orb.subcontractDebugFlag) {
690         dprint(".handleDynamicResult<-: " + opAndId(req));
691         }
692     }
693     }
694
695     protected CorbaMessageMediator sendingReply(CorbaMessageMediator req)
696     {
697     try {
698         if (orb.subcontractDebugFlag) {
699         dprint(".sendingReply->: " + opAndId(req));
700         }
701
702         ServiceContexts scs = new ServiceContexts(orb);
703         return req.getProtocolHandler().createResponse(req, scs);
704     } finally {
705         if (orb.subcontractDebugFlag) {
706         dprint(".sendingReply<-: " + opAndId(req));
707         }
708     }
709     }
710
711     /** Must always be called, just after the servant's method returns.
712      * Creates the ReplyMessage header and puts in the transaction context
713      * if necessary.
714      */

715     protected CorbaMessageMediator sendingReply(CorbaMessageMediator req, Any JavaDoc excany)
716     {
717     try {
718         if (orb.subcontractDebugFlag) {
719         dprint(".sendingReply/Any->: " + opAndId(req));
720         }
721
722         ServiceContexts scs = new ServiceContexts(orb);
723
724         // Check if the servant set a SystemException or
725
// UserException
726
CorbaMessageMediator resp;
727         String JavaDoc repId=null;
728         try {
729         repId = excany.type().id();
730         } catch (org.omg.CORBA.TypeCodePackage.BadKind JavaDoc e) {
731         throw wrapper.problemWithExceptionTypecode( e ) ;
732         }
733
734         if (ORBUtility.isSystemException(repId)) {
735         if (orb.subcontractDebugFlag) {
736             dprint(".sendingReply/Any: " + opAndId(req)
737                + ": handling system exception");
738         }
739
740         // Get the exception object from the Any
741
InputStream JavaDoc in = excany.create_input_stream();
742         SystemException JavaDoc ex = ORBUtility.readSystemException(in);
743         // Marshal the exception back
744
resp = req.getProtocolHandler()
745             .createSystemExceptionResponse(req, ex, scs);
746         } else {
747         if (orb.subcontractDebugFlag) {
748             dprint(".sendingReply/Any: " + opAndId(req)
749                + ": handling user exception");
750         }
751
752         resp = req.getProtocolHandler()
753             .createUserExceptionResponse(req, scs);
754         OutputStream JavaDoc os = (OutputStream JavaDoc)resp.getOutputObject();
755         excany.write_value(os);
756         }
757
758         return resp;
759     } finally {
760         if (orb.subcontractDebugFlag) {
761         dprint(".sendingReply/Any<-: " + opAndId(req));
762         }
763     }
764     }
765
766     /**
767      * Handles setting the connection's code sets if required.
768      * Returns true if the CodeSetContext was in the request, false
769      * otherwise.
770      */

771     protected boolean processCodeSetContext(
772     CorbaMessageMediator request, ServiceContexts contexts)
773     {
774     try {
775         if (orb.subcontractDebugFlag) {
776         dprint(".processCodeSetContext->: " + opAndId(request));
777         }
778
779         ServiceContext sc = contexts.get(
780         CodeSetServiceContext.SERVICE_CONTEXT_ID);
781         if (sc != null) {
782         // Somehow a code set service context showed up in the local case.
783
if (request.getConnection() == null) {
784             return true;
785         }
786
787         // If it's GIOP 1.0, it shouldn't have this context at all. Our legacy
788
// ORBs sent it and we need to know if it's here to make ORB versioning
789
// decisions, but we don't use the contents.
790
if (request.getGIOPVersion().equals(GIOPVersion.V1_0)) {
791             return true;
792         }
793
794         CodeSetServiceContext cssc = (CodeSetServiceContext)sc ;
795         CodeSetComponentInfo.CodeSetContext csctx = cssc.getCodeSetContext();
796
797         // Note on threading:
798
//
799
// getCodeSetContext and setCodeSetContext are synchronized
800
// on the Connection. At worst, this will result in
801
// multiple threads entering this block and calling
802
// setCodeSetContext but not actually changing the
803
// values on the Connection.
804
//
805
// Alternative would be to lock the connection for the
806
// whole block, but it's fine either way.
807

808         // The connection's codeSetContext is null until we've received a
809
// request with a code set context with the negotiated code sets.
810
if (((CorbaConnection)request.getConnection())
811             .getCodeSetContext() == null)
812                 {
813
814             // Use these code sets on this connection
815
if (orb.subcontractDebugFlag) {
816             dprint(".processCodeSetContext: " + opAndId(request)
817                    + ": Setting code sets to: " + csctx);
818             }
819
820             ((CorbaConnection)request.getConnection())
821             .setCodeSetContext(csctx);
822
823             // We had to read the method name using ISO 8859-1
824
// (which is the default in the CDRInputStream for
825
// char data), but now we may have a new char
826
// code set. If it isn't ISO8859-1, we must tell
827
// the CDR stream to null any converter references
828
// it has created so that it will reacquire
829
// the code sets again using the new info.
830
//
831
// This should probably compare with the stream's
832
// char code set rather than assuming it's ISO8859-1.
833
// (However, the operation name is almost certainly
834
// ISO8859-1 or ASCII.)
835
if (csctx.getCharCodeSet() !=
836             OSFCodeSetRegistry.ISO_8859_1.getNumber()) {
837             ((MarshalInputStream)request.getInputObject())
838                 .resetCodeSetConverters();
839             }
840         }
841         }
842
843         // If no code set information is ever sent from the client,
844
// the server will use ISO8859-1 for char and throw an
845
// exception for any wchar transmissions.
846
//
847
// In the local case, we use ORB provided streams for
848
// marshaling and unmarshaling. Currently, they use
849
// ISO8859-1 for char/string and UTF16 for wchar/wstring.
850
return sc != null ;
851     } finally {
852         if (orb.subcontractDebugFlag) {
853         dprint(".processCodeSetContext<-: " + opAndId(request));
854         }
855     }
856     }
857
858     protected void dprint(String JavaDoc msg)
859     {
860         ORBUtility.dprint("CorbaServerRequestDispatcherImpl", msg);
861     }
862
863     protected String JavaDoc opAndId(CorbaMessageMediator mediator)
864     {
865     return ORBUtility.operationNameAndRequestId(mediator);
866     }
867 }
868
869 // End of file.
870

871
Popular Tags