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. package com.sun.corba.se.impl.protocol;
  16. import org.omg.PortableServer.Servant ;
  17. import org.omg.CORBA.SystemException;
  18. import org.omg.CORBA.INTERNAL;
  19. import org.omg.CORBA.UNKNOWN;
  20. import org.omg.CORBA.CompletionStatus;
  21. import org.omg.CORBA.Any;
  22. import org.omg.CORBA.portable.InvokeHandler;
  23. import org.omg.CORBA.portable.InputStream;
  24. import org.omg.CORBA.portable.OutputStream;
  25. import org.omg.CORBA.portable.UnknownException;
  26. import org.omg.CORBA.portable.ResponseHandler;
  27. import com.sun.org.omg.SendingContext.CodeBase;
  28. import com.sun.corba.se.pept.encoding.OutputObject;
  29. import com.sun.corba.se.pept.protocol.MessageMediator;
  30. import com.sun.corba.se.spi.orb.ORB;
  31. import com.sun.corba.se.spi.orb.ORBVersion;
  32. import com.sun.corba.se.spi.orb.ORBVersionFactory;
  33. import com.sun.corba.se.spi.ior.IOR ;
  34. import com.sun.corba.se.spi.ior.ObjectKey;
  35. import com.sun.corba.se.spi.ior.ObjectKeyTemplate;
  36. import com.sun.corba.se.spi.ior.ObjectAdapterId;
  37. import com.sun.corba.se.spi.oa.ObjectAdapterFactory;
  38. import com.sun.corba.se.spi.oa.ObjectAdapter;
  39. import com.sun.corba.se.spi.oa.OAInvocationInfo;
  40. import com.sun.corba.se.spi.oa.OADestroyed;
  41. import com.sun.corba.se.spi.oa.NullServant;
  42. import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
  43. import com.sun.corba.se.spi.protocol.CorbaServerRequestDispatcher;
  44. import com.sun.corba.se.spi.protocol.ForwardException ;
  45. import com.sun.corba.se.spi.protocol.RequestDispatcherRegistry;
  46. import com.sun.corba.se.spi.transport.CorbaConnection;
  47. import com.sun.corba.se.spi.logging.CORBALogDomains;
  48. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  49. import com.sun.corba.se.impl.protocol.SpecialMethod ;
  50. import com.sun.corba.se.spi.servicecontext.ServiceContext;
  51. import com.sun.corba.se.spi.servicecontext.ServiceContexts;
  52. import com.sun.corba.se.spi.servicecontext.UEInfoServiceContext;
  53. import com.sun.corba.se.spi.servicecontext.CodeSetServiceContext;
  54. import com.sun.corba.se.spi.servicecontext.SendingContextServiceContext;
  55. import com.sun.corba.se.spi.servicecontext.ORBVersionServiceContext;
  56. import com.sun.corba.se.impl.corba.ServerRequestImpl ;
  57. import com.sun.corba.se.impl.encoding.MarshalInputStream;
  58. import com.sun.corba.se.impl.encoding.MarshalOutputStream;
  59. import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
  60. import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
  61. import com.sun.corba.se.impl.orbutil.ORBConstants;
  62. import com.sun.corba.se.impl.orbutil.ORBUtility;
  63. import com.sun.corba.se.impl.protocol.RequestCanceledException;
  64. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  65. import com.sun.corba.se.impl.logging.POASystemException;
  66. public class CorbaServerRequestDispatcherImpl
  67. implements CorbaServerRequestDispatcher
  68. {
  69. protected ORB orb; // my ORB instance
  70. private ORBUtilSystemException wrapper ;
  71. private POASystemException poaWrapper ;
  72. // Added from last version because it broke the build - RTW
  73. // XXX remove me and rebuild: probably no longer needed
  74. // public static final int UNKNOWN_EXCEPTION_INFO_ID = 9;
  75. public CorbaServerRequestDispatcherImpl(ORB orb)
  76. {
  77. this.orb = orb;
  78. wrapper = ORBUtilSystemException.get( orb,
  79. CORBALogDomains.RPC_PROTOCOL ) ;
  80. poaWrapper = POASystemException.get( orb,
  81. CORBALogDomains.RPC_PROTOCOL ) ;
  82. }
  83. /** XXX/REVISIT:
  84. * We do not want to look for a servant in the POA/ServantManager case,
  85. * but we could in most other cases. The OA could have a method that
  86. * returns true if the servant MAY exist, and false only if the servant
  87. * definitely DOES NOT exist.
  88. *
  89. * XXX/REVISIT:
  90. * We may wish to indicate OBJECT_HERE by some mechanism other than
  91. * returning a null result.
  92. *
  93. * Called from ORB.locate when a LocateRequest arrives.
  94. * Result is not always absolutely correct: may indicate OBJECT_HERE
  95. * for non-existent objects, which is resolved on invocation. This
  96. * "bug" is unavoidable, since in general the object may be destroyed
  97. * between a locate and a request. Note that this only checks that
  98. * the appropriate ObjectAdapter is available, not that the servant
  99. * actually exists.
  100. * Need to signal one of OBJECT_HERE, OBJECT_FORWARD, OBJECT_NOT_EXIST.
  101. * @return Result is null if object is (possibly) implemented here, otherwise
  102. * an IOR indicating objref to forward the request to.
  103. * @exception OBJECT_NOT_EXIST is thrown if we know the object does not
  104. * exist here, and we are not forwarding.
  105. */
  106. public IOR locate(ObjectKey okey)
  107. {
  108. try {
  109. if (orb.subcontractDebugFlag)
  110. dprint(".locate->");
  111. ObjectKeyTemplate oktemp = okey.getTemplate() ;
  112. try {
  113. checkServerId(okey);
  114. } catch (ForwardException fex) {
  115. return fex.getIOR() ;
  116. }
  117. // Called only for its side-effect of throwing appropriate exceptions
  118. findObjectAdapter(oktemp);
  119. return null ;
  120. } finally {
  121. if (orb.subcontractDebugFlag)
  122. dprint(".locate<-");
  123. }
  124. }
  125. public void dispatch(MessageMediator messageMediator)
  126. {
  127. CorbaMessageMediator request = (CorbaMessageMediator) messageMediator;
  128. try {
  129. if (orb.subcontractDebugFlag) {
  130. dprint(".dispatch->: " + opAndId(request));
  131. }
  132. // to set the codebase information, if any transmitted; and also
  133. // appropriate ORB Version.
  134. consumeServiceContexts(request);
  135. // Now that we have the service contexts processed and the
  136. // correct ORBVersion set, we must finish initializing the
  137. // stream.
  138. ((MarshalInputStream)request.getInputObject())
  139. .performORBVersionSpecificInit();
  140. ObjectKey okey = request.getObjectKey();
  141. // Check that this server is the right server
  142. try {
  143. checkServerId(okey);
  144. } catch (ForwardException fex) {
  145. if (orb.subcontractDebugFlag) {
  146. dprint(".dispatch: " + opAndId(request)
  147. + ": bad server id");
  148. }
  149. request.getProtocolHandler()
  150. .createLocationForward(request, fex.getIOR(), null);
  151. return;
  152. }
  153. String operation = request.getOperationName();
  154. ObjectAdapter objectAdapter = null ;
  155. try {
  156. byte[] objectId = okey.getId().getId() ;
  157. ObjectKeyTemplate oktemp = okey.getTemplate() ;
  158. objectAdapter = findObjectAdapter(oktemp);
  159. java.lang.Object servant = getServantWithPI(request, objectAdapter,
  160. objectId, oktemp, operation);
  161. dispatchToServant(servant, request, objectId, objectAdapter);
  162. } catch (ForwardException ex) {
  163. if (orb.subcontractDebugFlag) {
  164. dprint(".dispatch: " + opAndId(request)
  165. + ": ForwardException caught");
  166. }
  167. // Thrown by Portable Interceptors from InterceptorInvoker,
  168. // through Response constructor.
  169. request.getProtocolHandler()
  170. .createLocationForward(request, ex.getIOR(), null);
  171. } catch (OADestroyed ex) {
  172. if (orb.subcontractDebugFlag) {
  173. dprint(".dispatch: " + opAndId(request)
  174. + ": OADestroyed exception caught");
  175. }
  176. // DO NOT CALL THIS HERE:
  177. // releaseServant(objectAdapter);
  178. // The problem is that OADestroyed is only thrown by oa.enter, in
  179. // which case oa.exit should NOT be called, and neither should
  180. // the invocationInfo stack be popped.
  181. // Destroyed POAs can be recreated by normal adapter activation.
  182. // So just restart the dispatch.
  183. dispatch(request);
  184. } catch (RequestCanceledException ex) {
  185. if (orb.subcontractDebugFlag) {
  186. dprint(".dispatch: " + opAndId(request)
  187. + ": RequestCanceledException caught");
  188. }
  189. // IDLJ generated non-tie based skeletons do not catch the
  190. // RequestCanceledException. Rethrow the exception, which will
  191. // cause the worker thread to unwind the dispatch and wait for
  192. // other requests.
  193. throw ex;
  194. } catch (UnknownException ex) {
  195. if (orb.subcontractDebugFlag) {
  196. dprint(".dispatch: " + opAndId(request)
  197. + ": UnknownException caught " + ex);
  198. }
  199. // RMIC generated tie skeletons convert all Throwable exception
  200. // types (including RequestCanceledException, ThreadDeath)
  201. // thrown during reading fragments into UnknownException.
  202. // If RequestCanceledException was indeed raised,
  203. // then rethrow it, which will eventually cause the worker
  204. // thread to unstack the dispatch and wait for other requests.
  205. if (ex.originalEx instanceof RequestCanceledException) {
  206. throw (RequestCanceledException) ex.originalEx;
  207. }
  208. ServiceContexts contexts = new ServiceContexts(orb);
  209. UEInfoServiceContext usc = new UEInfoServiceContext(
  210. ex.originalEx);
  211. contexts.put( usc ) ;
  212. SystemException sysex = wrapper.unknownExceptionInDispatch(
  213. CompletionStatus.COMPLETED_MAYBE, ex ) ;
  214. request.getProtocolHandler()
  215. .createSystemExceptionResponse(request, sysex,
  216. contexts);
  217. } catch (Throwable ex) {
  218. if (orb.subcontractDebugFlag) {
  219. dprint(".dispatch: " + opAndId(request)
  220. + ": other exception " + ex);
  221. }
  222. request.getProtocolHandler()
  223. .handleThrowableDuringServerDispatch(
  224. request, ex, CompletionStatus.COMPLETED_MAYBE);
  225. }
  226. return;
  227. } finally {
  228. if (orb.subcontractDebugFlag) {
  229. dprint(".dispatch<-: " + opAndId(request));
  230. }
  231. }
  232. }
  233. private void releaseServant(ObjectAdapter objectAdapter)
  234. {
  235. try {
  236. if (orb.subcontractDebugFlag) {
  237. dprint(".releaseServant->");
  238. }
  239. if (objectAdapter == null) {
  240. if (orb.subcontractDebugFlag) {
  241. dprint(".releaseServant: null object adapter");
  242. }
  243. return ;
  244. }
  245. try {
  246. objectAdapter.returnServant();
  247. } finally {
  248. objectAdapter.exit();
  249. orb.popInvocationInfo() ;
  250. }
  251. } finally {
  252. if (orb.subcontractDebugFlag) {
  253. dprint(".releaseServant<-");
  254. }
  255. }
  256. }
  257. // Note that objectAdapter.enter() must be called before getServant.
  258. private java.lang.Object getServant(ObjectAdapter objectAdapter, byte[] objectId,
  259. String operation)
  260. throws OADestroyed
  261. {
  262. try {
  263. if (orb.subcontractDebugFlag) {
  264. dprint(".getServant->");
  265. }
  266. OAInvocationInfo info = objectAdapter.makeInvocationInfo(objectId);
  267. info.setOperation(operation);
  268. orb.pushInvocationInfo(info);
  269. objectAdapter.getInvocationServant(info);
  270. return info.getServantContainer() ;
  271. } finally {
  272. if (orb.subcontractDebugFlag) {
  273. dprint(".getServant<-");
  274. }
  275. }
  276. }
  277. protected java.lang.Object getServantWithPI(CorbaMessageMediator request,
  278. ObjectAdapter objectAdapter,
  279. byte[] objectId, ObjectKeyTemplate oktemp, String operation)
  280. throws OADestroyed
  281. {
  282. try {
  283. if (orb.subcontractDebugFlag) {
  284. dprint(".getServantWithPI->");
  285. }
  286. // Prepare Portable Interceptors for a new server request
  287. // and invoke receive_request_service_contexts. The starting
  288. // point may throw a SystemException or ForwardException.
  289. orb.getPIHandler().initializeServerPIInfo(request, objectAdapter,
  290. objectId, oktemp);
  291. orb.getPIHandler().invokeServerPIStartingPoint();
  292. objectAdapter.enter() ;
  293. // This must be set just after the enter so that exceptions thrown by
  294. // enter do not cause
  295. // the exception reply to pop the thread stack and do an extra oa.exit.
  296. if (request != null)
  297. request.setExecuteReturnServantInResponseConstructor(true);
  298. java.lang.Object servant = getServant(objectAdapter, objectId,
  299. operation);
  300. // Note: we do not know the MDI on a null servant.
  301. // We only end up in that situation if _non_existent called,
  302. // so that the following handleNullServant call does not throw an
  303. // exception.
  304. String mdi = "unknown" ;
  305. if (servant instanceof NullServant)
  306. handleNullServant(operation, (NullServant)servant);
  307. else
  308. mdi = objectAdapter.getInterfaces(servant, objectId)[0] ;
  309. orb.getPIHandler().setServerPIInfo(servant, mdi);
  310. if (((servant != null) &&
  311. !(servant instanceof org.omg.CORBA.DynamicImplementation) &&
  312. !(servant instanceof org.omg.PortableServer.DynamicImplementation)) ||
  313. (SpecialMethod.getSpecialMethod(operation) != null)) {
  314. orb.getPIHandler().invokeServerPIIntermediatePoint();
  315. }
  316. return servant ;
  317. } finally {
  318. if (orb.subcontractDebugFlag) {
  319. dprint(".getServantWithPI<-");
  320. }
  321. }
  322. }
  323. protected void checkServerId(ObjectKey okey)
  324. {
  325. try {
  326. if (orb.subcontractDebugFlag) {
  327. dprint(".checkServerId->");
  328. }
  329. ObjectKeyTemplate oktemp = okey.getTemplate() ;
  330. int sId = oktemp.getServerId() ;
  331. int scid = oktemp.getSubcontractId() ;
  332. if (!orb.isLocalServerId(scid, sId)) {
  333. if (orb.subcontractDebugFlag) {
  334. dprint(".checkServerId: bad server id");
  335. }
  336. orb.handleBadServerId(okey);
  337. }
  338. } finally {
  339. if (orb.subcontractDebugFlag) {
  340. dprint(".checkServerId<-");
  341. }
  342. }
  343. }
  344. private ObjectAdapter findObjectAdapter(ObjectKeyTemplate oktemp)
  345. {
  346. try {
  347. if (orb.subcontractDebugFlag) {
  348. dprint(".findObjectAdapter->");
  349. }
  350. RequestDispatcherRegistry scr = orb.getRequestDispatcherRegistry() ;
  351. int scid = oktemp.getSubcontractId() ;
  352. ObjectAdapterFactory oaf = scr.getObjectAdapterFactory(scid);
  353. if (oaf == null) {
  354. if (orb.subcontractDebugFlag) {
  355. dprint(".findObjectAdapter: failed to find ObjectAdapterFactory");
  356. }
  357. throw wrapper.noObjectAdapterFactory() ;
  358. }
  359. ObjectAdapterId oaid = oktemp.getObjectAdapterId() ;
  360. ObjectAdapter oa = oaf.find(oaid);
  361. if (oa == null) {
  362. if (orb.subcontractDebugFlag) {
  363. dprint(".findObjectAdapter: failed to find ObjectAdaptor");
  364. }
  365. throw wrapper.badAdapterId() ;
  366. }
  367. return oa ;
  368. } finally {
  369. if (orb.subcontractDebugFlag) {
  370. dprint(".findObjectAdapter<-");
  371. }
  372. }
  373. }
  374. /** Always throws OBJECT_NOT_EXIST if operation is not a special method.
  375. * If operation is _non_existent or _not_existent, this will just
  376. * return without performing any action, so that _non_existent can return
  377. * false. Always throws OBJECT_NOT_EXIST for any other special method.
  378. * Update for issue 4385.
  379. */
  380. protected void handleNullServant(String operation, NullServant nserv )
  381. {
  382. try {
  383. if (orb.subcontractDebugFlag) {
  384. dprint(".handleNullServant->: " + operation);
  385. }
  386. SpecialMethod specialMethod =
  387. SpecialMethod.getSpecialMethod(operation);
  388. if ((specialMethod == null) ||
  389. !specialMethod.isNonExistentMethod()) {
  390. if (orb.subcontractDebugFlag) {
  391. dprint(".handleNullServant: " + operation
  392. + ": throwing OBJECT_NOT_EXIST");
  393. }
  394. throw nserv.getException() ;
  395. }
  396. } finally {
  397. if (orb.subcontractDebugFlag) {
  398. dprint(".handleNullServant<-: " + operation);
  399. }
  400. }
  401. }
  402. protected void consumeServiceContexts(CorbaMessageMediator request)
  403. {
  404. try {
  405. if (orb.subcontractDebugFlag) {
  406. dprint(".consumeServiceContexts->: "
  407. + opAndId(request));
  408. }
  409. ServiceContexts ctxts = request.getRequestServiceContexts();
  410. ServiceContext sc ;
  411. GIOPVersion giopVersion = request.getGIOPVersion();
  412. // we cannot depend on this since for our local case, we do not send
  413. // in this service context. Can we rely on just the CodeSetServiceContext?
  414. // boolean rtSC = false; // Runtime ServiceContext
  415. boolean hasCodeSetContext = processCodeSetContext(request, ctxts);
  416. if (orb.subcontractDebugFlag) {
  417. dprint(".consumeServiceContexts: " + opAndId(request)
  418. + ": GIOP version: " + giopVersion);
  419. dprint(".consumeServiceContexts: " + opAndId(request)
  420. + ": as code set context? " + hasCodeSetContext);
  421. }
  422. sc = ctxts.get(
  423. SendingContextServiceContext.SERVICE_CONTEXT_ID ) ;
  424. if (sc != null) {
  425. SendingContextServiceContext scsc =
  426. (SendingContextServiceContext)sc ;
  427. IOR ior = scsc.getIOR() ;
  428. try {
  429. ((CorbaConnection)request.getConnection())
  430. .setCodeBaseIOR(ior);
  431. } catch (ThreadDeath td) {
  432. throw td ;
  433. } catch (Throwable t) {
  434. throw wrapper.badStringifiedIor( t ) ;
  435. }
  436. }
  437. // the RTSC is sent only once during session establishment. We
  438. // need to find out if the CodeBaseRef is already set. If yes,
  439. // then also the rtSC flag needs to be set to true
  440. // this is not possible for the LocalCase since there is no
  441. // IIOPConnection for the LocalCase
  442. // used for a case where we have JDK 1.3 supporting 1.0 protocol,
  443. // but sending 2 service contexts, that is not normal as per
  444. // GIOP rules, based on above information, we figure out that we
  445. // are talking to the legacy ORB and set the ORB Version Accordingly.
  446. // this special case tell us that it is legacy SUN orb
  447. // and not a foreign one
  448. // rtSC is not available for localcase due to which this generic
  449. // path would fail if relying on rtSC
  450. //if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext && rtSC)
  451. boolean isForeignORB = false;
  452. if (giopVersion.equals(GIOPVersion.V1_0) && hasCodeSetContext) {
  453. if (orb.subcontractDebugFlag) {
  454. dprint(".consumeServiceCOntexts: " + opAndId(request)
  455. + ": Determined to be an old Sun ORB");
  456. }
  457. orb.setORBVersion(ORBVersionFactory.getOLD()) ;
  458. // System.out.println("setting legacy ORB version");
  459. } else {
  460. // If it didn't include our ORB version service context (below),
  461. // then it must be a foreign ORB.
  462. isForeignORB = true;
  463. }
  464. // try to get the ORBVersion sent as part of the ServiceContext
  465. // if any
  466. sc = ctxts.get( ORBVersionServiceContext.SERVICE_CONTEXT_ID ) ;
  467. if (sc != null) {
  468. ORBVersionServiceContext ovsc =
  469. (ORBVersionServiceContext) sc;
  470. ORBVersion version = ovsc.getVersion();
  471. orb.setORBVersion(version);
  472. isForeignORB = false;
  473. }
  474. if (isForeignORB) {
  475. if (orb.subcontractDebugFlag) {
  476. dprint(".consumeServiceContexts: " + opAndId(request)
  477. + ": Determined to be a foreign ORB");
  478. }
  479. orb.setORBVersion(ORBVersionFactory.getFOREIGN());
  480. }
  481. } finally {
  482. if (orb.subcontractDebugFlag) {
  483. dprint(".consumeServiceContexts<-: " + opAndId(request));
  484. }
  485. }
  486. }
  487. protected CorbaMessageMediator dispatchToServant(
  488. java.lang.Object servant,
  489. CorbaMessageMediator req,
  490. byte[] objectId, ObjectAdapter objectAdapter)
  491. {
  492. try {
  493. if (orb.subcontractDebugFlag) {
  494. dprint(".dispatchToServant->: " + opAndId(req));
  495. }
  496. CorbaMessageMediator response = null ;
  497. String operation = req.getOperationName() ;
  498. SpecialMethod method = SpecialMethod.getSpecialMethod(operation) ;
  499. if (method != null) {
  500. if (orb.subcontractDebugFlag) {
  501. dprint(".dispatchToServant: " + opAndId(req)
  502. + ": Handling special method");
  503. }
  504. response = method.invoke(servant, req, objectId, objectAdapter);
  505. return response ;
  506. }
  507. // Invoke on the servant using the portable DSI skeleton
  508. if (servant instanceof org.omg.CORBA.DynamicImplementation) {
  509. if (orb.subcontractDebugFlag) {
  510. dprint(".dispatchToServant: " + opAndId(req)
  511. + ": Handling old style DSI type servant");
  512. }
  513. org.omg.CORBA.DynamicImplementation dynimpl =
  514. (org.omg.CORBA.DynamicImplementation)servant;
  515. ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
  516. // Note: When/if dynimpl.invoke calls arguments() or
  517. // set_exception() then intermediate points are run.
  518. dynimpl.invoke(sreq);
  519. response = handleDynamicResult(sreq, req);
  520. } else if (servant instanceof org.omg.PortableServer.DynamicImplementation) {
  521. if (orb.subcontractDebugFlag) {
  522. dprint(".dispatchToServant: " + opAndId(req)
  523. + ": Handling POA DSI type servant");
  524. }
  525. org.omg.PortableServer.DynamicImplementation dynimpl =
  526. (org.omg.PortableServer.DynamicImplementation)servant;
  527. ServerRequestImpl sreq = new ServerRequestImpl(req, orb);
  528. // Note: When/if dynimpl.invoke calls arguments() or
  529. // set_exception() then intermediate points are run.
  530. dynimpl.invoke(sreq);
  531. response = handleDynamicResult(sreq, req);
  532. } else {
  533. if (orb.subcontractDebugFlag) {
  534. dprint(".dispatchToServant: " + opAndId(req)
  535. + ": Handling invoke handler type servant");
  536. }
  537. InvokeHandler invhandle = (InvokeHandler)servant ;
  538. OutputStream stream =
  539. (OutputStream)invhandle._invoke(
  540. operation,
  541. (org.omg.CORBA.portable.InputStream)req.getInputObject(),
  542. req);
  543. response = (CorbaMessageMediator)
  544. ((OutputObject)stream).getMessageMediator();
  545. }
  546. return response ;
  547. } finally {
  548. if (orb.subcontractDebugFlag) {
  549. dprint(".dispatchToServant<-: " + opAndId(req));
  550. }
  551. }
  552. }
  553. protected CorbaMessageMediator handleDynamicResult(
  554. ServerRequestImpl sreq,
  555. CorbaMessageMediator req)
  556. {
  557. try {
  558. if (orb.subcontractDebugFlag) {
  559. dprint(".handleDynamicResult->: " + opAndId(req));
  560. }
  561. CorbaMessageMediator response = null ;
  562. // Check if ServerRequestImpl.result() has been called
  563. Any excany = sreq.checkResultCalled();
  564. if (excany == null) { // normal return
  565. if (orb.subcontractDebugFlag) {
  566. dprint(".handleDynamicResult: " + opAndId(req)
  567. + ": handling normal result");
  568. }
  569. // Marshal out/inout/return parameters into the ReplyMessage
  570. response = sendingReply(req);
  571. OutputStream os = (OutputStream) response.getOutputObject();
  572. sreq.marshalReplyParams(os);
  573. } else {
  574. if (orb.subcontractDebugFlag) {
  575. dprint(".handleDynamicResult: " + opAndId(req)
  576. + ": handling error");
  577. }
  578. response = sendingReply(req, excany);
  579. }
  580. return response ;
  581. } finally {
  582. if (orb.subcontractDebugFlag) {
  583. dprint(".handleDynamicResult<-: " + opAndId(req));
  584. }
  585. }
  586. }
  587. protected CorbaMessageMediator sendingReply(CorbaMessageMediator req)
  588. {
  589. try {
  590. if (orb.subcontractDebugFlag) {
  591. dprint(".sendingReply->: " + opAndId(req));
  592. }
  593. ServiceContexts scs = new ServiceContexts(orb);
  594. return req.getProtocolHandler().createResponse(req, scs);
  595. } finally {
  596. if (orb.subcontractDebugFlag) {
  597. dprint(".sendingReply<-: " + opAndId(req));
  598. }
  599. }
  600. }
  601. /** Must always be called, just after the servant's method returns.
  602. * Creates the ReplyMessage header and puts in the transaction context
  603. * if necessary.
  604. */
  605. protected CorbaMessageMediator sendingReply(CorbaMessageMediator req, Any excany)
  606. {
  607. try {
  608. if (orb.subcontractDebugFlag) {
  609. dprint(".sendingReply/Any->: " + opAndId(req));
  610. }
  611. ServiceContexts scs = new ServiceContexts(orb);
  612. // Check if the servant set a SystemException or
  613. // UserException
  614. CorbaMessageMediator resp;
  615. String repId=null;
  616. try {
  617. repId = excany.type().id();
  618. } catch (org.omg.CORBA.TypeCodePackage.BadKind e) {
  619. throw wrapper.problemWithExceptionTypecode( e ) ;
  620. }
  621. if (ORBUtility.isSystemException(repId)) {
  622. if (orb.subcontractDebugFlag) {
  623. dprint(".sendingReply/Any: " + opAndId(req)
  624. + ": handling system exception");
  625. }
  626. // Get the exception object from the Any
  627. InputStream in = excany.create_input_stream();
  628. SystemException ex = ORBUtility.readSystemException(in);
  629. // Marshal the exception back
  630. resp = req.getProtocolHandler()
  631. .createSystemExceptionResponse(req, ex, scs);
  632. } else {
  633. if (orb.subcontractDebugFlag) {
  634. dprint(".sendingReply/Any: " + opAndId(req)
  635. + ": handling user exception");
  636. }
  637. resp = req.getProtocolHandler()
  638. .createUserExceptionResponse(req, scs);
  639. OutputStream os = (OutputStream)resp.getOutputObject();
  640. excany.write_value(os);
  641. }
  642. return resp;
  643. } finally {
  644. if (orb.subcontractDebugFlag) {
  645. dprint(".sendingReply/Any<-: " + opAndId(req));
  646. }
  647. }
  648. }
  649. /**
  650. * Handles setting the connection's code sets if required.
  651. * Returns true if the CodeSetContext was in the request, false
  652. * otherwise.
  653. */
  654. protected boolean processCodeSetContext(
  655. CorbaMessageMediator request, ServiceContexts contexts)
  656. {
  657. try {
  658. if (orb.subcontractDebugFlag) {
  659. dprint(".processCodeSetContext->: " + opAndId(request));
  660. }
  661. ServiceContext sc = contexts.get(
  662. CodeSetServiceContext.SERVICE_CONTEXT_ID);
  663. if (sc != null) {
  664. // Somehow a code set service context showed up in the local case.
  665. if (request.getConnection() == null) {
  666. return true;
  667. }
  668. // If it's GIOP 1.0, it shouldn't have this context at all. Our legacy
  669. // ORBs sent it and we need to know if it's here to make ORB versioning
  670. // decisions, but we don't use the contents.
  671. if (request.getGIOPVersion().equals(GIOPVersion.V1_0)) {
  672. return true;
  673. }
  674. CodeSetServiceContext cssc = (CodeSetServiceContext)sc ;
  675. CodeSetComponentInfo.CodeSetContext csctx = cssc.getCodeSetContext();
  676. // Note on threading:
  677. //
  678. // getCodeSetContext and setCodeSetContext are synchronized
  679. // on the Connection. At worst, this will result in
  680. // multiple threads entering this block and calling
  681. // setCodeSetContext but not actually changing the
  682. // values on the Connection.
  683. //
  684. // Alternative would be to lock the connection for the
  685. // whole block, but it's fine either way.
  686. // The connection's codeSetContext is null until we've received a
  687. // request with a code set context with the negotiated code sets.
  688. if (((CorbaConnection)request.getConnection())
  689. .getCodeSetContext() == null)
  690. {
  691. // Use these code sets on this connection
  692. if (orb.subcontractDebugFlag) {
  693. dprint(".processCodeSetContext: " + opAndId(request)
  694. + ": Setting code sets to: " + csctx);
  695. }
  696. ((CorbaConnection)request.getConnection())
  697. .setCodeSetContext(csctx);
  698. // We had to read the method name using ISO 8859-1
  699. // (which is the default in the CDRInputStream for
  700. // char data), but now we may have a new char
  701. // code set. If it isn't ISO8859-1, we must tell
  702. // the CDR stream to null any converter references
  703. // it has created so that it will reacquire
  704. // the code sets again using the new info.
  705. //
  706. // This should probably compare with the stream's
  707. // char code set rather than assuming it's ISO8859-1.
  708. // (However, the operation name is almost certainly
  709. // ISO8859-1 or ASCII.)
  710. if (csctx.getCharCodeSet() !=
  711. OSFCodeSetRegistry.ISO_8859_1.getNumber()) {
  712. ((MarshalInputStream)request.getInputObject())
  713. .resetCodeSetConverters();
  714. }
  715. }
  716. }
  717. // If no code set information is ever sent from the client,
  718. // the server will use ISO8859-1 for char and throw an
  719. // exception for any wchar transmissions.
  720. //
  721. // In the local case, we use ORB provided streams for
  722. // marshaling and unmarshaling. Currently, they use
  723. // ISO8859-1 for char/string and UTF16 for wchar/wstring.
  724. return sc != null ;
  725. } finally {
  726. if (orb.subcontractDebugFlag) {
  727. dprint(".processCodeSetContext<-: " + opAndId(request));
  728. }
  729. }
  730. }
  731. protected void dprint(String msg)
  732. {
  733. ORBUtility.dprint("CorbaServerRequestDispatcherImpl", msg);
  734. }
  735. protected String opAndId(CorbaMessageMediator mediator)
  736. {
  737. return ORBUtility.operationNameAndRequestId(mediator);
  738. }
  739. }
  740. // End of file.