1. /*
  2. * @(#)POAImpl.java 1.88 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.internal.POA;
  8. import org.omg.CORBA.*;
  9. import org.omg.CORBA.portable.*;
  10. import org.omg.PortableServer.*;
  11. import org.omg.PortableServer.POAPackage.*;
  12. import org.omg.PortableServer.ServantLocatorPackage.*;
  13. import com.sun.corba.se.internal.ior.IIOPProfileTemplate ;
  14. import com.sun.corba.se.internal.ior.ObjectKeyTemplate ;
  15. import com.sun.corba.se.internal.ior.POAObjectKeyTemplate ;
  16. import com.sun.corba.se.internal.ior.IORTemplate ;
  17. import com.sun.corba.se.internal.ior.ObjectId ;
  18. import com.sun.corba.se.internal.ior.IIOPAddress ;
  19. import com.sun.corba.se.internal.ior.IIOPAddressImpl ;
  20. import com.sun.corba.se.internal.ior.POAView ;
  21. import com.sun.corba.se.internal.ior.POAId ;
  22. import com.sun.corba.se.internal.ior.POAIdPOAView ;
  23. import org.omg.IOP.TAG_INTERNET_IOP ;
  24. import com.sun.corba.se.internal.core.*;
  25. import com.sun.corba.se.internal.corba.*;
  26. import com.sun.corba.se.internal.orbutil.ORBUtility; //d11638
  27. import com.sun.corba.se.internal.orbutil.ORBConstants; //d11638
  28. import java.util.*;
  29. /**
  30. * POAImpl is the implementation of the Portable Object Adapter. It
  31. * contains an implementation of the POA interfaces specified in
  32. * orbos/97-05-15.
  33. *
  34. */
  35. public class POAImpl extends org.omg.CORBA.LocalObject implements POA, POAView {
  36. protected POAORB orb;
  37. private int numLevels;
  38. private POAId poaId ;
  39. private String name;
  40. private POAManagerImpl manager;
  41. private POAImpl parent;
  42. private AdapterActivator activator;
  43. private ServantManager servantManager;
  44. private Servant defaultServant;
  45. private Policies policies;
  46. protected ActiveObjectMap activeObjectMap;
  47. protected Map children;
  48. protected int scid ;
  49. private Integer sysIdCounter = new Integer(0);
  50. private int nInvocations = 0; // pending invocations on this POA
  51. protected IORTemplate iortemp;
  52. protected byte[] adapterId ;
  53. // adapterActivatorCV has to be null
  54. // see its use in find_POA() and enter()
  55. private java.lang.Object adapterActivatorCV = null;
  56. // Wait on this CV for
  57. // AdapterActivator upcalls to complete
  58. private java.lang.Object invokeCV =
  59. new java.lang.Object(); // Wait on this CV for all active
  60. // invocations to complete
  61. // beingDestroyedCV has to be null
  62. // see its use in destroy() and enter()
  63. private java.lang.Object beingDestroyedCV = null;
  64. // Wait on this CV for the destroy
  65. // method to complete doing its work
  66. // thread local variable to store a boolean to detect deadlock in POA.destroy().
  67. // Note: This doesn't cover the case where an application starts more than one
  68. // thread which call POA.destroy. This variable could be extended to maintain
  69. // the current POA the thread is destroying so that the destroy threads don't
  70. // get in the way of each other.
  71. protected ThreadLocal isDestroying = new ThreadLocal () {
  72. protected java.lang.Object initialValue() {
  73. return Boolean.FALSE;
  74. }
  75. };
  76. private boolean destroyed = false;
  77. private boolean etherealizeFlag = false; // to check if the value has be
  78. // set already if destroy is called multiple times
  79. private boolean etherealizeValue = false; // to hold value from first call to
  80. // destroy, and this value is used for subsequent destroy calls
  81. // XXX temporary for timing: DO NOT RELEASE WITH THIS FLAG SET!
  82. private boolean normalState = false ;
  83. public POAImpl(String name, POAManagerImpl manager, Policies policies,
  84. POAImpl parent, AdapterActivator activator, POAORB orb)
  85. {
  86. this.policies = policies;
  87. this.name = name;
  88. this.manager = manager;
  89. this.parent = parent;
  90. this.activator = activator;
  91. this.orb = orb;
  92. pre_initialize();
  93. if( parent != null ) {
  94. // If this is not the Root POA, notify POAORB that IORInterceptors
  95. // should be invoked now.
  96. orb.invokeIORInterceptors( this );
  97. }
  98. post_initialize() ;
  99. }
  100. public POAImpl makePOA(
  101. String name, POAManagerImpl manager, Policies policies,
  102. POAImpl parent, AdapterActivator activator, POAORB orb )
  103. {
  104. return new POAImpl(
  105. name, manager, policies, parent, activator, orb ) ;
  106. }
  107. protected void pre_initialize()
  108. {
  109. if (parent == null)
  110. numLevels = 0 ;
  111. else
  112. numLevels = parent.getNumLevels() + 1 ;
  113. if (policies.retainServants())
  114. activeObjectMap = new ActiveObjectMap(policies.isMultipleIds());
  115. children = new HashMap();
  116. manager.addPOA(this);
  117. if (policies.isSingleThreaded())
  118. throw new org.omg.CORBA.NO_IMPLEMENT(
  119. "Single threaded model not implemented");
  120. // Construct the IORTemplate
  121. final POAORB poaorb = (POAORB)orb;
  122. int serverid;
  123. int port ;
  124. if ( policies.isTransient() ) {
  125. serverid = poaorb.getTransientServerId();
  126. port = poaorb.getServerEndpoint().getPort() ;
  127. if (policies.servantCachingAllowed())
  128. scid = ORBConstants.SCTransientSCID ;
  129. else
  130. scid = ORBConstants.TransientSCID ;
  131. } else {
  132. serverid = poaorb.getPersistentServerId();
  133. port = poaorb.getPersistentServerPort(EndPoint.IIOP_CLEAR_TEXT);
  134. if (policies.servantCachingAllowed())
  135. scid = ORBConstants.SCPersistentSCID ;
  136. else
  137. scid = ORBConstants.PersistentSCID ;
  138. }
  139. String host = poaorb.getServerEndpoint().getHostName() ;
  140. IIOPAddress addr = new IIOPAddressImpl( host, port ) ;
  141. // get the orb-id corresponding this ORB for putting in the Object Key
  142. String orbId = poaorb.getORBId();
  143. poaId = new POAIdPOAView( this ) ;
  144. // Construct the objectKey
  145. ObjectKeyTemplate oktemp = new POAObjectKeyTemplate(
  146. scid, serverid, orbId, poaId ) ;
  147. adapterId = oktemp.getAdapterId( orb ) ;
  148. GIOPVersion version = orb.getGIOPVersion() ;
  149. IIOPProfileTemplate temp = new StandardIIOPProfileTemplate( addr,
  150. version.major, version.minor, oktemp, null, orb ) ;
  151. iortemp = new IORTemplate() ;
  152. iortemp.add( temp ) ;
  153. }
  154. protected void post_initialize()
  155. {
  156. iortemp.makeImmutable() ;
  157. }
  158. public final Policies getPolicies() {
  159. return policies;
  160. }
  161. protected synchronized boolean hasServantInMap(Servant servant){
  162. if (activeObjectMap != null ) //Has retain policy set.
  163. return activeObjectMap.contains(servant);
  164. else //Has non-retain policy set.
  165. return false;
  166. }
  167. protected POA create_POA(String name,
  168. POAManagerImpl manager,
  169. Policies policies)
  170. throws AdapterAlreadyExists, InvalidPolicy {
  171. if (children.get(name) != null)
  172. adapterAlreadyExists();
  173. if (manager == null)
  174. manager = new POAManagerImpl(orb);
  175. POAImpl child = makePOA(name, manager, policies, this,
  176. null, orb);
  177. children.put(name, child);
  178. return child;
  179. }
  180. protected void removeChild(String name) {
  181. children.remove(name);
  182. }
  183. // XXX visible for ServantCachingPOAClientSC
  184. void enter() throws POADestroyed
  185. {
  186. if (destroyed) {
  187. // Avoid deadlock if this is the thread that is processing the POA.destroy
  188. // because this is the only thread that can notify waiters on beingDestroyedCV
  189. if (beingDestroyedCV != null && isDestroying.get() == Boolean.FALSE) {
  190. try {
  191. synchronized (beingDestroyedCV) {
  192. beingDestroyedCV.wait();
  193. }
  194. } catch (InterruptedException ex) { }
  195. }
  196. throw new POADestroyed();
  197. }
  198. if (parent != null && parent.adapterActivatorCV != null) {
  199. try {
  200. synchronized (parent.adapterActivatorCV) {
  201. parent.adapterActivatorCV.wait();
  202. }
  203. } catch (InterruptedException ex) { }
  204. }
  205. synchronized (this) {
  206. nInvocations++;
  207. }
  208. manager.enter();
  209. }
  210. // XXX visible for ServantCachingPOAClientSC
  211. void exit()
  212. {
  213. synchronized (this) {
  214. nInvocations--;
  215. if ((nInvocations == 0) && destroyed) {
  216. synchronized (invokeCV) {
  217. invokeCV.notifyAll();
  218. }
  219. }
  220. }
  221. manager.exit();
  222. }
  223. /** Called from the subcontract to get the servant to dispatch this
  224. * invocation to. The actual servant dispatch code is in the subcontract.
  225. */
  226. public Servant getServant(
  227. byte[] id, CookieHolder cookieHolder,
  228. String operation,
  229. com.sun.corba.se.internal.core.ServerRequest serverRequest)
  230. throws
  231. ForwardRequest,
  232. POADestroyed
  233. {
  234. enter();
  235. orb.getCurrent().addThreadInfo(this, id, cookieHolder, operation);
  236. // This must be set just after "enter" and the thread stack
  237. // has been pushed so if an exception occurs before this point then
  238. // the exception reply will not try to do returnServant.
  239. // serverRequest may be null in the rmi-iiop isLocal case.
  240. if (serverRequest != null) {
  241. serverRequest.setExecuteReturnServantInResponseConstructor(true);
  242. }
  243. Servant servant = internalGetServant(id, cookieHolder, operation);
  244. orb.getCurrent().setServant(servant);
  245. return servant;
  246. }
  247. /** Called from the subcontract to let this POA cleanup after an
  248. * invocation. Note: If getServant was called, then returnServant
  249. * MUST be called, even in the case of exceptions. This may be
  250. * called multiple times for a single request.
  251. */
  252. public void returnServant()
  253. {
  254. if ( !policies.retainServants()
  255. && policies.useServantManager()
  256. && orb.getCurrent().preInvokeCalled()
  257. && !orb.getCurrent().postInvokeCalled())
  258. {
  259. if (servantManager == null ||
  260. ! (servantManager instanceof ServantLocator) )
  261. {
  262. return;
  263. }
  264. ServantLocator locator = (ServantLocator)servantManager;
  265. POACurrent c = orb.getCurrent();
  266. try {
  267. locator.postinvoke(c.getObjectId(),
  268. c.getPOA(),
  269. c.getOperation(),
  270. c.getCookieHolder().value,
  271. c.getServant());
  272. } finally {
  273. orb.getCurrent().setPostInvokeCalled();
  274. }
  275. }
  276. }
  277. /** Called in GenericPOAServerSC rmi-iiop isLocal case.
  278. */
  279. public void returnServantAndRemoveThreadInfo()
  280. {
  281. try {
  282. returnServant();
  283. } finally {
  284. removeThreadInfo();
  285. }
  286. }
  287. /** Called from the subcontract to let this POA cleanup after an
  288. * invocation. Note: If getServant was called, then returnServant
  289. * MUST be called, even in the case of exceptions. This MUST
  290. * be called only once for a single request.
  291. */
  292. public void removeThreadInfo()
  293. {
  294. exit();
  295. orb.getCurrent().removeThreadInfo();
  296. }
  297. private Servant internalGetServant(byte[] id, CookieHolder cookieHolder,
  298. String operation)
  299. throws ForwardRequest, POADestroyed
  300. {
  301. boolean isSpecial = SpecialMethod.isSpecialMethod(operation);
  302. if (policies.retainServants() && policies.useActiveMapOnly())
  303. {
  304. // CHANGED (RAM J) 08/07/2000 raise OBJECT_NOT_EXIST exception
  305. // if servant not found in the activeObjectMap. Previously,
  306. // we were returning null, which is incorrect.
  307. //return activeObjectMap.get(id);
  308. Servant servant = activeObjectMap.get(id);
  309. if (servant == null) {
  310. if (! isSpecial) {
  311. objectNotExist(MinorCodes.NULL_SERVANT,
  312. CompletionStatus.COMPLETED_NO);
  313. } else {
  314. return null;
  315. }
  316. }
  317. return servant;
  318. }
  319. else if (policies.retainServants() && policies.useServantManager())
  320. {
  321. Servant servant = activeObjectMap.get(id);
  322. if ( servant == null) {
  323. if (servantManager == null)
  324. objAdapter(MinorCodes.POA_NO_SERVANT_MANAGER,
  325. CompletionStatus.COMPLETED_NO);
  326. if (!(servantManager instanceof ServantActivator))
  327. objAdapter(MinorCodes.POA_BAD_SERVANT_MANAGER,
  328. CompletionStatus.COMPLETED_NO);
  329. synchronized (servantManager) {
  330. // Check again if the servant exists in activeObjectMap:
  331. // this is necessary because two threads could call
  332. // the first activeObjectMap.get(id) simultaneously
  333. // and get nulls returned. We cant hold the
  334. // activeObjectMap lock during the incarnate call
  335. // because incarnate may take too long.
  336. servant = activeObjectMap.get(id);
  337. if (servant == null) {
  338. ServantActivator activator =
  339. (ServantActivator) servantManager;
  340. servant = activator.incarnate(id, this);
  341. if (servant == null) {
  342. if (! isSpecial) {
  343. throw new OBJ_ADAPTER(MinorCodes.NULL_SERVANT,
  344. CompletionStatus.COMPLETED_NO);
  345. } else {
  346. return null;
  347. }
  348. }
  349. // here check for unique_id policy, and if the servant
  350. // is already registered, for a different ID, then throw
  351. // OBJ_ADAPTER exception, else activate it. Section 11.3.5.1
  352. // 99-10-07.pdf
  353. if (policies.isUniqueIds()) {
  354. // check if the servant already is associated with some
  355. // id
  356. if (activeObjectMap.contains(servant)) {
  357. objAdapter(MinorCodes.POA_SERVANT_NOT_UNIQUE,
  358. CompletionStatus.COMPLETED_NO);
  359. }
  360. }
  361. activate(id, servant);
  362. }
  363. }
  364. }
  365. return servant;
  366. }
  367. else if (policies.retainServants() && policies.useDefaultServant())
  368. {
  369. Servant servant = activeObjectMap.get(id);
  370. if (servant != null)
  371. return servant;
  372. else if (defaultServant != null)
  373. return defaultServant;
  374. else
  375. objAdapter(MinorCodes.POA_NO_DEFAULT_SERVANT,
  376. CompletionStatus.COMPLETED_NO);
  377. }
  378. else if (!policies.retainServants() && policies.useServantManager())
  379. {
  380. if (servantManager == null)
  381. objAdapter(MinorCodes.POA_NO_SERVANT_MANAGER,
  382. CompletionStatus.COMPLETED_NO);
  383. if (! (servantManager instanceof ServantLocator) )
  384. objAdapter(MinorCodes.POA_BAD_SERVANT_MANAGER,
  385. CompletionStatus.COMPLETED_NO);
  386. ServantLocator locator = (ServantLocator) servantManager;
  387. // Try - finally is J2EE requirement.
  388. Servant servant;
  389. try{
  390. servant = locator.preinvoke(id, this, operation,
  391. cookieHolder);
  392. if (servant == null) {
  393. if (! isSpecial) {
  394. objectNotExist(MinorCodes.NULL_SERVANT,
  395. CompletionStatus.COMPLETED_NO);
  396. } else {
  397. return null;
  398. }
  399. }
  400. } finally {
  401. orb.getCurrent().setPreInvokeCalled();
  402. }
  403. setDelegate(servant, id);
  404. // Note: locator.postinvoke is called in internalReturnServant
  405. return servant;
  406. }
  407. else if (!policies.retainServants() && policies.useDefaultServant())
  408. {
  409. if (defaultServant != null)
  410. return defaultServant;
  411. else
  412. objAdapter(MinorCodes.POA_NO_DEFAULT_SERVANT,
  413. CompletionStatus.COMPLETED_NO);
  414. }
  415. else
  416. throw new INTERNAL(MinorCodes.POA_INTERNAL_GET_SERVANT_ERROR,
  417. CompletionStatus.COMPLETED_NO);
  418. return null; // to keep javac happy
  419. }
  420. void etherealizeAll() {
  421. if (policies.retainServants() && policies.useServantManager()
  422. && servantManager != null) {
  423. Enumeration keys = activeObjectMap.keys();
  424. while ( keys.hasMoreElements() ) {
  425. byte[] id = (byte[])keys.nextElement();
  426. Servant servant = activeObjectMap.get(id);
  427. boolean remaining_activations;
  428. if (activeObjectMap.hasMultipleIDs(servant))
  429. remaining_activations = true;
  430. else
  431. remaining_activations = false;
  432. synchronized (servantManager) {
  433. ((ServantActivator)
  434. servantManager).etherealize(id, this,
  435. servant,
  436. true,
  437. remaining_activations);
  438. }
  439. }
  440. }
  441. }
  442. /**
  443. * <code>create_POA</code>
  444. * <b>Section 3.3.8.2</b>
  445. */
  446. public synchronized POA create_POA(String name,
  447. POAManager manager,
  448. Policy[] policies)
  449. throws AdapterAlreadyExists, InvalidPolicy {
  450. return create_POA(name, (POAManagerImpl) manager,
  451. new Policies(policies));
  452. }
  453. /**
  454. * <code>find_POA</code>
  455. * <b>Section 3.3.8.3</b>
  456. */
  457. public synchronized POA find_POA(String name, boolean activate)
  458. throws AdapterNonExistent
  459. {
  460. POA found = (POA) children.get(name);
  461. if (found != null)
  462. return found;
  463. else if (activate) {
  464. if (activator == null)
  465. adapterNonExistent();
  466. else {
  467. boolean status;
  468. try {
  469. // this song and dance of creating a CV and then
  470. // notifying it is necessary to ensure that
  471. // invocations on the created child POA are queued
  472. // until unknown_adapter returns (see POAImpl.enter)
  473. adapterActivatorCV = new java.lang.Object();
  474. status = activator.unknown_adapter(this, name);
  475. synchronized (adapterActivatorCV) {
  476. adapterActivatorCV.notifyAll();
  477. adapterActivatorCV = null;
  478. }
  479. } catch (SystemException ex) {
  480. if (orb.poaDebugFlag)
  481. ORBUtility.dprint( this,
  482. "System exception in unknown_adapter call",
  483. ex ) ;
  484. objAdapter(MinorCodes.ADAPTER_ACTIVATOR_EXCEPTION,
  485. CompletionStatus.COMPLETED_NO);
  486. return null;
  487. }
  488. if (status == false) {
  489. // OMG Issue 3740 is resolved to throw AdapterNonExistent if
  490. // unknown_adapter() returns false.
  491. adapterNonExistent();
  492. }
  493. return (POA) children.get(name);
  494. }
  495. }
  496. adapterNonExistent();
  497. return null; // to keep javac quiet
  498. }
  499. /**
  500. * <code>destroy</code>
  501. * <b>Section 3.3.8.4</b>
  502. */
  503. public void destroy(boolean etherealize, boolean wait_for_completion) {
  504. // This is to avoid deadlock
  505. if (wait_for_completion && orb.isProcessingInvocation()) {
  506. throw new BAD_INV_ORDER(
  507. "Request to destroy POA with waiting for completion while servicing a request",
  508. 0,
  509. CompletionStatus.COMPLETED_NO);
  510. }
  511. destroyInternal(etherealize, wait_for_completion);
  512. }
  513. // Split destroy into destroy and destroyInternal.
  514. // This guarantees to have at most one DestroyThread started
  515. // if wait_for_completion == false. The recursive call to destroyInternal
  516. // uses "true" for all children which avoids starting new DestroyThreads.
  517. //
  518. void destroyInternal(boolean etherealize, boolean wait_for_completion) {
  519. // According to spec, the destroy may be called multiple time, and
  520. // it is allowed to proceed with it's own setting of the wait flag,
  521. // but the etherealize value is used from the first call to
  522. // destroy. Also all children should be destroyed before the
  523. // parent POA.
  524. synchronized (this) {
  525. if (!destroyed) {
  526. destroyed = true;
  527. }
  528. if (beingDestroyedCV == null) {
  529. beingDestroyedCV = new java.lang.Object();
  530. }
  531. if (!etherealizeFlag) {
  532. etherealizeValue = etherealize;
  533. etherealizeFlag = true;
  534. }
  535. }
  536. // Converted from anonymous class to local class
  537. // so that we can call performDestroy() directly.
  538. class DestroyThread extends Thread {
  539. private POAImpl poa ;
  540. public DestroyThread( POAImpl poa )
  541. {
  542. this.poa = poa ;
  543. }
  544. public void run() {
  545. performDestroy();
  546. }
  547. public void performDestroy() {
  548. poa.isDestroying.set(Boolean.TRUE);
  549. // Make sure that we have a copy of the children, notoy
  550. // an Iterator, otherwise ConcurrentModificationException can
  551. // occur.
  552. java.lang.Object[] childPoas = null ;
  553. synchronized (poa) {
  554. childPoas = poa.children.values().toArray() ;
  555. }
  556. for (int ctr=0; ctr<childPoas.length; ctr++) {
  557. POAImpl cpoa = (POAImpl)(childPoas[ctr]) ;
  558. // use wait_for_completion == true on the recursive destroy call so that
  559. // only a single DestroyThread is actually started.
  560. cpoa.destroyInternal( etherealizeValue, true ) ;
  561. }
  562. if (etherealizeValue)
  563. poa.etherealizeAll();
  564. // this check is required, because activeObjectMap would
  565. // be null for nonRetain Policy
  566. if (activeObjectMap != null) {
  567. poa.activeObjectMap.clear();
  568. poa.activeObjectMap = null;
  569. }
  570. }
  571. };
  572. DestroyThread destroyer = new DestroyThread( this );
  573. if (wait_for_completion) {
  574. // No need to start a new thread if we wait anyway.
  575. // In this case the current thread does the work.
  576. destroyer.performDestroy();
  577. } else {
  578. // Catch exceptions since setDaemon can cause a
  579. // security exception to be thrown under netscape
  580. // in the Applet mode
  581. try { destroyer.setDaemon(true); } catch (Exception e) {}
  582. // start a new thread
  583. destroyer.start();
  584. }
  585. if (wait_for_completion) {
  586. while (nInvocations != 0) {
  587. try {
  588. synchronized (invokeCV) {
  589. invokeCV.wait();
  590. }
  591. } catch (InterruptedException ex) { }
  592. }
  593. }
  594. manager.removePOA(this);
  595. if (parent != null) {
  596. parent.removeChild(name);
  597. }
  598. synchronized (beingDestroyedCV) {
  599. beingDestroyedCV.notifyAll();
  600. beingDestroyedCV = null;
  601. isDestroying.set(Boolean.FALSE);
  602. }
  603. }
  604. // XXX: Do the policy factory methods need to be synchronized?
  605. /**
  606. * <code>create_thread_policy</code>
  607. * <b>Section 3.3.8.5</b>
  608. */
  609. public ThreadPolicy
  610. create_thread_policy(ThreadPolicyValue
  611. value) {
  612. return new ThreadPolicyImpl(value);
  613. }
  614. /**
  615. * <code>create_lifespan_policy</code>
  616. * <b>Section 3.3.8.5</b>
  617. */
  618. public LifespanPolicy
  619. create_lifespan_policy(LifespanPolicyValue
  620. value) {
  621. return new LifespanPolicyImpl(value);
  622. }
  623. /**
  624. * <code>create_id_uniqueness_policy</code>
  625. * <b>Section 3.3.8.5</b>
  626. */
  627. public IdUniquenessPolicy
  628. create_id_uniqueness_policy(IdUniquenessPolicyValue
  629. value) {
  630. return new IdUniquenessPolicyImpl(value);
  631. }
  632. /**
  633. * <code>create_id_assignment_policy</code>
  634. * <b>Section 3.3.8.5</b>
  635. */
  636. public IdAssignmentPolicy
  637. create_id_assignment_policy(IdAssignmentPolicyValue
  638. value) {
  639. return new IdAssignmentPolicyImpl(value);
  640. }
  641. /**
  642. * <code>create_implicit_activation_policy</code>
  643. * <b>Section 3.3.8.5</b>
  644. */
  645. public ImplicitActivationPolicy
  646. create_implicit_activation_policy(ImplicitActivationPolicyValue
  647. value) {
  648. return new ImplicitActivationPolicyImpl(value);
  649. }
  650. /**
  651. * <code>create_servant_retention_policy</code>
  652. * <b>Section 3.3.8.5</b>
  653. */
  654. public ServantRetentionPolicy
  655. create_servant_retention_policy(ServantRetentionPolicyValue
  656. value) {
  657. return new ServantRetentionPolicyImpl(value);
  658. }
  659. /**
  660. * <code>create_request_processing_policy</code>
  661. * <b>Section 3.3.8.5</b>
  662. */
  663. public RequestProcessingPolicy
  664. create_request_processing_policy(RequestProcessingPolicyValue
  665. value) {
  666. return new RequestProcessingPolicyImpl(value);
  667. }
  668. /****** not needed for now
  669. public TransactionPolicy
  670. create_transaction_policy(TransactionPolicyValue
  671. value) {
  672. return new TransactionPolicyImpl(value);
  673. }
  674. ********/
  675. /**
  676. * <code>the_name</code>
  677. * <b>Section 3.3.8.6</b>
  678. */
  679. public String the_name() {
  680. return name;
  681. }
  682. /**
  683. * <code>the_parent</code>
  684. * <b>Section 3.3.8.7</b>
  685. */
  686. public POA the_parent()
  687. {
  688. return parent;
  689. }
  690. public POAView getParent()
  691. {
  692. return parent;
  693. }
  694. public int getNumLevels()
  695. {
  696. return numLevels ;
  697. }
  698. /**
  699. * <code>the_children</code>
  700. */
  701. synchronized public org.omg.PortableServer.POA[] the_children() {
  702. Collection coll = children.values() ;
  703. int size = coll.size() ;
  704. POA[] result = new POA[ size ] ;
  705. int index = 0 ;
  706. Iterator iter = coll.iterator() ;
  707. while (iter.hasNext()) {
  708. POA poa = (POA)(iter.next()) ;
  709. result[ index++ ] = poa ;
  710. }
  711. return result ;
  712. }
  713. /**
  714. * <code>the_POAManager</code>
  715. * <b>Section 3.3.8.8</b>
  716. */
  717. public POAManager the_POAManager() {
  718. return manager;
  719. }
  720. /**
  721. * <code>the_activator</code>
  722. * <b>Section 3.3.8.9</b>
  723. */
  724. public AdapterActivator the_activator() {
  725. return activator;
  726. }
  727. /**
  728. * <code>the_activator</code>
  729. * <b>Section 3.3.8.9</b>
  730. */
  731. public void the_activator(AdapterActivator
  732. activator) {
  733. this.activator = activator;
  734. }
  735. /**
  736. * <code>get_servant_manager</code>
  737. * <b>Section 3.3.8.10</b>
  738. */
  739. public ServantManager get_servant_manager()
  740. throws WrongPolicy {
  741. if (!policies.useServantManager())
  742. wrongPolicy();
  743. return servantManager;
  744. }
  745. // XXX: Need to sort this out w.r.t ServantActivator and
  746. // ServantLocator.
  747. /**
  748. * <code>set_servant_manager</code>
  749. * <b>Section 3.3.8.10</b>
  750. */
  751. public synchronized void set_servant_manager(ServantManager servantManager)
  752. throws WrongPolicy {
  753. if ( this.servantManager != null ) {
  754. throw new BAD_INV_ORDER( MinorCodes.SERVANT_MANAGER_ALREADY_SET,
  755. CompletionStatus.COMPLETED_NO );
  756. }
  757. if (!policies.useServantManager()) {
  758. wrongPolicy();
  759. }
  760. this.servantManager = servantManager;
  761. }
  762. /**
  763. * <code>get_servant</code>
  764. * <b>Section 3.3.8.12</b>
  765. */
  766. public Servant get_servant()
  767. throws NoServant, WrongPolicy {
  768. if (!policies.useDefaultServant())
  769. wrongPolicy();
  770. if (defaultServant == null)
  771. noServant();
  772. return defaultServant;
  773. }
  774. /**
  775. * <code>set_servant</code>
  776. * <b>Section 3.3.8.13</b>
  777. */
  778. public void set_servant(Servant defaultServant)
  779. throws WrongPolicy {
  780. if (!policies.useDefaultServant())
  781. wrongPolicy();
  782. this.defaultServant = defaultServant;
  783. setDelegate(defaultServant,
  784. "DefaultServant".getBytes());
  785. }
  786. /**
  787. * <code>activate_object</code>
  788. * <b>Section 3.3.8.14</b>
  789. */
  790. public synchronized byte[] activate_object(Servant servant)
  791. throws ServantAlreadyActive, WrongPolicy {
  792. if (!(policies.isSystemAssignedIds() &&
  793. policies.retainServants()))
  794. wrongPolicy();
  795. if (policies.isUniqueIds() &&
  796. activeObjectMap.contains(servant))
  797. servantAlreadyActive();
  798. // Allocate a new system-generated object-id.
  799. byte[] id = newId();
  800. activate(id, servant);
  801. return id;
  802. }
  803. /**
  804. * <code>activate_object_with_id</code>
  805. * <b>Section 3.3.8.15</b>
  806. */
  807. public synchronized void activate_object_with_id(byte[] id,
  808. Servant servant)
  809. throws ObjectAlreadyActive, ServantAlreadyActive, WrongPolicy
  810. {
  811. if (!policies.retainServants())
  812. wrongPolicy();
  813. if (activeObjectMap.containsKey(id))
  814. objectAlreadyActive();
  815. if (policies.isUniqueIds() &&
  816. activeObjectMap.contains(servant))
  817. servantAlreadyActive();
  818. activate(id, servant);
  819. }
  820. // This method is used by dispatch, where we already check for
  821. // policies before activation
  822. private final void activate(byte[] id, Servant servant)
  823. {
  824. byte[] idClone = (byte[])(id.clone()) ;
  825. setDelegate(servant, idClone );
  826. if (orb.shutdownDebugFlag) {
  827. System.out.println("Activating object " + servant +
  828. " with POA " + this);
  829. }
  830. activeObjectMap.put(idClone, servant);
  831. if (ShutdownUtilDelegate.instance != null) {
  832. ShutdownUtilDelegate.instance.registerPOAForServant(this, servant);
  833. }
  834. }
  835. /**
  836. * <code>deactivate_object</code>
  837. * <b>3.3.8.16</b>
  838. */
  839. public synchronized void deactivate_object(byte[] id)
  840. throws ObjectNotActive, WrongPolicy {
  841. if (!policies.retainServants())
  842. wrongPolicy();
  843. if (policies.useServantManager() && servantManager == null)
  844. objAdapter(MinorCodes.POA_NO_SERVANT_MANAGER,
  845. CompletionStatus.COMPLETED_NO);
  846. Servant s = activeObjectMap.get(id);
  847. if (s == null)
  848. objectNotActive();
  849. if (orb.shutdownDebugFlag) {
  850. System.out.println("Deactivating object " + s + " with POA " + this);
  851. }
  852. // This is to make sure that TransientObjectManager releases all references
  853. //orb.disconnect(createReference(s, id));
  854. activeObjectMap.remove(id);
  855. if (ShutdownUtilDelegate.instance != null) {
  856. ShutdownUtilDelegate.instance.unregisterPOAForServant(this, s);
  857. }
  858. boolean remaining_activations =
  859. activeObjectMap.hasMultipleIDs(s);
  860. if (servantManager != null)
  861. synchronized (servantManager) {
  862. ((ServantActivator)
  863. servantManager).etherealize( id, this, s,
  864. false, remaining_activations);
  865. }
  866. }
  867. public IOR makeTransactionalIOR( String repId, byte[] oid )
  868. {
  869. return null ;
  870. }
  871. protected org.omg.CORBA.Object makeObjectReference(
  872. String repId, byte[] id, IORTemplate iortemp, int scid )
  873. {
  874. ObjectImpl o = new CORBAObjectImpl();
  875. // Create the IOR
  876. ObjectId oid = new ObjectId( id ) ;
  877. IOR ior = new IOR( orb, repId, iortemp, oid ) ;
  878. // Invoke the old proprietary object reference creation interceptor
  879. ior = orb.objectReferenceCreated( ior ) ;
  880. ClientSubcontract csub = orb.getSubcontractRegistry().
  881. getClientSubcontract( scid ) ;
  882. csub.setOrb( orb ) ;
  883. csub.unmarshal( ior ) ;
  884. o._set_delegate( (Delegate)csub );
  885. return o;
  886. }
  887. //Needed to be changed from private to package for DelegateImpl.
  888. protected org.omg.CORBA.Object createReference(String repId, byte[] id)
  889. {
  890. return makeObjectReference( repId, id, iortemp, scid ) ;
  891. }
  892. protected org.omg.CORBA.Object createReference(Servant servant,
  893. byte[] id)
  894. {
  895. String[] reposIds = servant._all_interfaces(this, id);
  896. return makeObjectReference( reposIds[0], id, iortemp, scid ) ;
  897. }
  898. // create a delegate and stick it in the servant.
  899. // this delegate is needed during dispatch for the ObjectImpl._orb()
  900. // method to work.
  901. private void setDelegate(Servant servant, byte[] id)
  902. {
  903. //This new servant delegate no longer needs the id for its initialization.
  904. if ( orb.delegateImpl == null )
  905. throw new org.omg.CORBA.OBJ_ADAPTER("DelegateImpl not initialized.");
  906. servant._set_delegate(orb.delegateImpl);
  907. }
  908. /**
  909. * <code>create_reference</code>
  910. * <b>3.3.8.17</b>
  911. */
  912. public org.omg.CORBA.Object create_reference(String repId)
  913. throws WrongPolicy
  914. {
  915. if (!policies.isSystemAssignedIds())
  916. wrongPolicy();
  917. return createReference(repId, newId());
  918. }
  919. /**
  920. * <code>create_reference_with_id</code>
  921. * <b>3.3.8.18</b>
  922. */
  923. public org.omg.CORBA.Object
  924. create_reference_with_id(byte[] oid, String repId)
  925. {
  926. // First check if a servant exists for this id
  927. if (policies.retainServants()) {
  928. Servant s = activeObjectMap.get(oid);
  929. if (s == null)
  930. return createReference(repId, oid);
  931. String[] reposIds = s._all_interfaces(this,oid);
  932. if (!repId.equals(reposIds[0]))
  933. badParam(MinorCodes.BAD_REPOSITORY_ID,
  934. CompletionStatus.COMPLETED_NO);
  935. return createReference(s, oid);
  936. }
  937. return createReference(repId, oid);
  938. }
  939. /**
  940. * <code>servant_to_id</code>
  941. * <b>3.3.8.19</b>
  942. */
  943. public synchronized byte[] servant_to_id(Servant servant)
  944. throws ServantNotActive, WrongPolicy {
  945. if (! (policies.retainServants() &&
  946. (policies.isUniqueIds() ||
  947. policies.isImplicitlyActivated())) )
  948. wrongPolicy();
  949. if (policies.isUniqueIds() &&
  950. activeObjectMap.contains(servant))
  951. return activeObjectMap.getKey(servant);
  952. if (policies.isImplicitlyActivated() &&
  953. (policies.isMultipleIds() ||
  954. !activeObjectMap.contains(servant)))
  955. try {
  956. return activate_object(servant);
  957. } catch (ServantAlreadyActive s) {
  958. // XXX should not happen
  959. }
  960. servantNotActive();
  961. return null; // to keep javac quiet
  962. }
  963. /**
  964. * <code>servant_to_reference</code>
  965. * <b>3.3.8.20</b>
  966. */
  967. public org.omg.CORBA.Object
  968. servant_to_reference(Servant servant)
  969. throws ServantNotActive, WrongPolicy {
  970. byte[] oid = servant_to_id(servant);
  971. return createReference(servant, oid);
  972. }
  973. /**
  974. * <code>reference_to_servant</code>
  975. * <b>3.3.8.21</b>
  976. */
  977. public synchronized Servant
  978. reference_to_servant(org.omg.CORBA.Object reference)
  979. throws ObjectNotActive, WrongPolicy, WrongAdapter
  980. {
  981. if( destroyed ) {
  982. objectNotExist(MinorCodes.ADAPTER_DESTROYED,
  983. CompletionStatus.COMPLETED_NO);
  984. }
  985. if (!policies.retainServants() &&
  986. !policies.useDefaultServant())
  987. wrongPolicy();
  988. // reference_to_id should throw WrongAdapter
  989. // if the objref was not created by this POA
  990. byte [] id = reference_to_id(reference);
  991. if (policies.retainServants()) {
  992. Servant s = activeObjectMap.get(id);
  993. if (s != null)
  994. return s;
  995. }
  996. if (policies.useDefaultServant() && defaultServant != null)
  997. return defaultServant;
  998. objectNotActive();
  999. return null;
  1000. }
  1001. /**
  1002. * <code>reference_to_id</code>
  1003. * <b>3.3.8.22</b>
  1004. */
  1005. public synchronized byte[] reference_to_id(org.omg.CORBA.Object
  1006. reference)
  1007. throws WrongAdapter, WrongPolicy {
  1008. if( destroyed ) {
  1009. objectNotExist(MinorCodes.ADAPTER_DESTROYED,
  1010. CompletionStatus.COMPLETED_NO);
  1011. }
  1012. // According to 99-10-07.pdf (11.3.8.23), WrongPolicy is for future
  1013. // extensions
  1014. // XXX: we need to be able to see if this POA was the
  1015. // one that created "reference". if not, we need
  1016. // to throw WrongAdapter
  1017. ClientSC clientSC = (ClientSC) ((ObjectImpl) reference)._get_delegate();
  1018. // check if the poaId in the reference matches the Id for this POA
  1019. // if not then WrongAdapter Exception is thrown
  1020. if (!clientSC.getPOAId().equals( poaId ))
  1021. wrongAdapter();
  1022. return clientSC.getObjectId();
  1023. }
  1024. /**
  1025. * <code>id_to_servant</code>
  1026. * <b>3.3.8.23</b>
  1027. */
  1028. public synchronized Servant id_to_servant(byte[] id)
  1029. throws ObjectNotActive, WrongPolicy {
  1030. if( destroyed ) {
  1031. objectNotExist(MinorCodes.ADAPTER_DESTROYED,
  1032. CompletionStatus.COMPLETED_NO);
  1033. }
  1034. if (!policies.retainServants())
  1035. wrongPolicy();
  1036. Servant s = activeObjectMap.get(id);
  1037. if (s == null)
  1038. objectNotActive();
  1039. return s;
  1040. }
  1041. /**
  1042. * <code>id_to_reference</code>
  1043. * <b>3.3.8.24</b>
  1044. */
  1045. public synchronized org.omg.CORBA.Object id_to_reference(byte[] id)
  1046. throws ObjectNotActive, WrongPolicy {
  1047. if( destroyed ) {
  1048. objectNotExist(MinorCodes.ADAPTER_DESTROYED,
  1049. CompletionStatus.COMPLETED_NO);
  1050. }
  1051. if (!policies.retainServants())
  1052. wrongPolicy();
  1053. Servant s = activeObjectMap.get(id);
  1054. if (s == null)
  1055. objectNotActive();
  1056. return createReference(s, id);
  1057. }
  1058. /**
  1059. * <code>id</code>
  1060. * <b>11.3.8.26 in ptc/00-08-06</b>
  1061. */
  1062. public byte[] id() {
  1063. return adapterId ;
  1064. }
  1065. private byte[] newId() {
  1066. byte[] array = new byte[4];
  1067. synchronized (sysIdCounter) {
  1068. int value = sysIdCounter.intValue();
  1069. ORBUtility.intToBytes(value, array, 0);
  1070. sysIdCounter = new Integer(++value);
  1071. }
  1072. return array;
  1073. }
  1074. // Errors
  1075. static final void wrongPolicy() throws WrongPolicy {
  1076. throw new WrongPolicy();
  1077. }
  1078. static final void wrongAdapter() throws WrongAdapter {
  1079. throw new WrongAdapter();
  1080. }
  1081. static final void adapterAlreadyExists()
  1082. throws AdapterAlreadyExists {
  1083. throw new AdapterAlreadyExists();
  1084. }
  1085. static final void adapterNonExistent()
  1086. throws AdapterNonExistent {
  1087. throw new AdapterNonExistent();
  1088. }
  1089. static final void noServant()
  1090. throws NoServant {
  1091. throw new NoServant();
  1092. }
  1093. static final void servantAlreadyActive()
  1094. throws ServantAlreadyActive {
  1095. throw new ServantAlreadyActive();
  1096. }
  1097. static final void servantNotActive()
  1098. throws ServantNotActive {
  1099. throw new ServantNotActive();
  1100. }
  1101. static final void objectAlreadyActive()
  1102. throws ObjectAlreadyActive {
  1103. throw new ObjectAlreadyActive();
  1104. }
  1105. static final void objectNotActive()
  1106. throws ObjectNotActive {
  1107. throw new ObjectNotActive();
  1108. }
  1109. static final void objectNotExist(int minor, CompletionStatus status)
  1110. throws OBJECT_NOT_EXIST {
  1111. throw new OBJECT_NOT_EXIST(minor, status);
  1112. }
  1113. static final void objAdapter(int minor, CompletionStatus status)
  1114. throws OBJ_ADAPTER {
  1115. throw new OBJ_ADAPTER(minor, status);
  1116. }
  1117. static final void badParam(int minor, CompletionStatus status)
  1118. throws BAD_PARAM {
  1119. throw new org.omg.CORBA.BAD_PARAM(MinorCodes.BAD_REPOSITORY_ID,
  1120. CompletionStatus.COMPLETED_NO);
  1121. }
  1122. static final void debug(String s) {
  1123. System.out.println(s);
  1124. }
  1125. public IORTemplate getIORTemplate()
  1126. {
  1127. return iortemp ;
  1128. }
  1129. // Note: This method is made public so it can be accessed by the
  1130. // Portable Interceptors package. This should not be a security risk
  1131. // since any decisions that can be made based on these policies will
  1132. // have been made long before any untrusted code can call this method.
  1133. public Policy get_effective_policy( int type ) {
  1134. return policies.get_effective_policy( type ) ;
  1135. }
  1136. }