PageRenderTime 71ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/jboss-as-7.1.1.Final/jacorb/src/main/java/org/jboss/as/jacorb/naming/CorbaNamingContext.java

#
Java | 662 lines | 410 code | 101 blank | 151 comment | 144 complexity | 650ff63f5008292c4b19f7e2501c5b74 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2011, Red Hat, Inc., and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.as.jacorb.naming;
  23. import java.io.IOException;
  24. import java.io.ObjectInputStream;
  25. import java.io.Serializable;
  26. import java.util.Hashtable;
  27. import java.util.Iterator;
  28. import java.util.Map;
  29. import org.jacorb.naming.BindingIteratorImpl;
  30. import org.jacorb.naming.Name;
  31. import org.jboss.as.jacorb.JacORBLogger;
  32. import org.omg.CORBA.INTERNAL;
  33. import org.omg.CORBA.ORB;
  34. import org.omg.CosNaming.Binding;
  35. import org.omg.CosNaming.BindingIteratorHelper;
  36. import org.omg.CosNaming.BindingIteratorHolder;
  37. import org.omg.CosNaming.BindingListHolder;
  38. import org.omg.CosNaming.BindingType;
  39. import org.omg.CosNaming.NameComponent;
  40. import org.omg.CosNaming.NamingContext;
  41. import org.omg.CosNaming.NamingContextExtHelper;
  42. import org.omg.CosNaming.NamingContextExtPOA;
  43. import org.omg.CosNaming.NamingContextExtPackage.InvalidAddress;
  44. import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
  45. import org.omg.CosNaming.NamingContextPackage.CannotProceed;
  46. import org.omg.CosNaming.NamingContextPackage.InvalidName;
  47. import org.omg.CosNaming.NamingContextPackage.NotEmpty;
  48. import org.omg.CosNaming.NamingContextPackage.NotFound;
  49. import org.omg.CosNaming.NamingContextPackage.NotFoundReason;
  50. import org.omg.PortableServer.POA;
  51. /**
  52. * <p>
  53. * This class implements an in-VM CORBA Naming Server that caches for JBoss to use. All contexts keep a cache of the
  54. * local sub-contexts to avoid unnecessary remote calls when resolving a complex name.
  55. * </p>
  56. *
  57. * @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
  58. */
  59. public class CorbaNamingContext extends NamingContextExtPOA implements Serializable {
  60. private static final long serialVersionUID = 132820915998903191L;
  61. /**
  62. * static references to the running ORB and root POA.
  63. */
  64. private static ORB orb;
  65. private static POA rootPoa;
  66. /**
  67. * the naming service POA - i.e. the POA that activates all naming contexts.
  68. */
  69. private transient POA poa;
  70. /**
  71. * table of all name bindings in this contexts, ie. name -> obj ref.
  72. */
  73. private Map<Name, Object> names = new Hashtable<Name, Object>();
  74. /**
  75. * table of all subordinate naming contexts, ie. name -> obj ref.
  76. */
  77. private Map<Name, Object> contexts = new Hashtable<Name, Object>();
  78. /**
  79. * cache of all active naming context implementations - used when resolving contexts recursively to avoid
  80. * unnecessary remote calls that may lead to thread pool depletion.
  81. */
  82. private static Map<String, CorbaNamingContext> contextImpls = new Hashtable<String, CorbaNamingContext>();
  83. /**
  84. * no tests of bound objects for existence
  85. */
  86. private boolean noPing = false;
  87. /**
  88. * purge?
  89. */
  90. private boolean doPurge = false;
  91. private boolean destroyed = false;
  92. private int childCount = 0;
  93. //======================================= Initialization Methods ==================================//
  94. /**
  95. * <p>
  96. * This method needs to be called once to initialize the static fields orb and rootPoa.
  97. * </p>
  98. *
  99. * @param orb a reference to the running {@code ORB} instance.
  100. * @param rootPoa a reference to the root {@code POA}.
  101. */
  102. public static void init(org.omg.CORBA.ORB orb, org.omg.PortableServer.POA rootPoa) {
  103. CorbaNamingContext.orb = orb;
  104. CorbaNamingContext.rootPoa = rootPoa;
  105. }
  106. /**
  107. * <p>
  108. * This method needs to be called for each newly created or re-read naming context to set its POA.
  109. * </p>
  110. *
  111. * @param poa a reference to the Naming Service {@code POA}.
  112. * @param doPurge a boolean that indicates if dead objects should be purged from the context ({@code true}) upon cleanup
  113. * or not ({@code false}).
  114. * @param noPing a boolean that indicates if the method {@code resolve} should check if the resolved name or context is
  115. * alive before returning it. If {@code false}, the name will be checked (default)
  116. */
  117. public void init(POA poa, boolean doPurge, boolean noPing) {
  118. this.poa = poa;
  119. this.doPurge = doPurge;
  120. this.noPing = noPing;
  121. }
  122. //======================================= NamingContextOperation Methods ==================================//
  123. public void bind(NameComponent[] nc, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, InvalidName,
  124. AlreadyBound {
  125. if (this.destroyed)
  126. throw new CannotProceed();
  127. if (nc == null || nc.length == 0)
  128. throw new InvalidName();
  129. if (obj == null)
  130. throw new org.omg.CORBA.BAD_PARAM();
  131. Name n = new Name(nc);
  132. Name ctx = n.ctxName();
  133. NameComponent nb = n.baseNameComponent();
  134. if (ctx == null) {
  135. if (this.names.containsKey(n)) {
  136. // if the name is still in use, try to ping the object
  137. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.get(n);
  138. if (isDead(ref)) {
  139. rebind(n.components(), obj);
  140. return;
  141. }
  142. throw new AlreadyBound();
  143. } else if (this.contexts.containsKey(n)) {
  144. // if the name is still in use, try to ping the object
  145. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.get(n);
  146. if (isDead(ref))
  147. unbind(n.components());
  148. throw new AlreadyBound();
  149. }
  150. if ((this.names.put(n, obj)) != null)
  151. throw new CannotProceed(_this(), n.components());
  152. JacORBLogger.ROOT_LOGGER.debugBoundName(n.toString());
  153. } else {
  154. NameComponent[] ncx = new NameComponent[]{nb};
  155. org.omg.CORBA.Object context = this.resolve(ctx.components());
  156. // try first to call the context implementation object directly.
  157. String contextOID = this.getObjectOID(context);
  158. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  159. if (jbossContext != null)
  160. jbossContext.bind(ncx, obj);
  161. else
  162. NamingContextExtHelper.narrow(context).bind(ncx, obj);
  163. }
  164. }
  165. public void bind_context(NameComponent[] nc, NamingContext obj) throws NotFound, CannotProceed, InvalidName,
  166. AlreadyBound {
  167. if (this.destroyed)
  168. throw new CannotProceed();
  169. Name n = new Name(nc);
  170. Name ctx = n.ctxName();
  171. NameComponent nb = n.baseNameComponent();
  172. if (ctx == null) {
  173. if (this.names.containsKey(n)) {
  174. // if the name is still in use, try to ping the object
  175. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.get(n);
  176. if (isDead(ref))
  177. unbind(n.components());
  178. else
  179. throw new AlreadyBound();
  180. } else if (this.contexts.containsKey(n)) {
  181. // if the name is still in use, try to ping the object
  182. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.get(n);
  183. if (isDead(ref)) {
  184. rebind_context(n.components(), obj);
  185. return;
  186. }
  187. throw new AlreadyBound();
  188. }
  189. if ((this.contexts.put(n, obj)) != null)
  190. throw new CannotProceed(_this(), n.components());
  191. JacORBLogger.ROOT_LOGGER.debugBoundContext(n.toString());
  192. } else {
  193. NameComponent[] ncx = new NameComponent[]{nb};
  194. org.omg.CORBA.Object context = this.resolve(ctx.components());
  195. // try first to call the context implementation object directly.
  196. String contextOID = this.getObjectOID(context);
  197. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  198. if (jbossContext != null)
  199. jbossContext.bind_context(ncx, obj);
  200. else
  201. NamingContextExtHelper.narrow(context).bind_context(ncx, obj);
  202. }
  203. }
  204. public NamingContext bind_new_context(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName, AlreadyBound {
  205. if (this.destroyed)
  206. throw new CannotProceed();
  207. if (nc == null || nc.length == 0)
  208. throw new InvalidName();
  209. NamingContext context = new_context();
  210. if (context == null)
  211. throw new CannotProceed();
  212. bind_context(nc, context);
  213. return context;
  214. }
  215. public void destroy() throws NotEmpty {
  216. if (this.destroyed)
  217. return;
  218. if (!this.names.isEmpty() || !this.contexts.isEmpty())
  219. throw new NotEmpty();
  220. else {
  221. this.names = null;
  222. this.contexts = null;
  223. this.destroyed = true;
  224. }
  225. }
  226. public void list(int how_many, BindingListHolder bl, BindingIteratorHolder bi) {
  227. if (this.destroyed)
  228. return;
  229. Binding[] result;
  230. this.cleanup();
  231. int size = how_many();
  232. Iterator<Name> names = this.names.keySet().iterator();
  233. Iterator<Name> contexts = this.contexts.keySet().iterator();
  234. if (how_many < size) {
  235. // counter for copies
  236. int how_many_ctr = how_many;
  237. // set up an array with "how_many" bindings
  238. result = new Binding[how_many];
  239. for (; names.hasNext() && how_many_ctr > 0; how_many_ctr--)
  240. result[how_many_ctr - 1] = new Binding((names.next()).components(), BindingType.nobject);
  241. for (; contexts.hasNext() && how_many_ctr > 0; how_many_ctr--)
  242. result[how_many_ctr - 1] = new Binding((contexts.next()).components(), BindingType.ncontext);
  243. // create a new BindingIterator for the remaining arrays
  244. size -= how_many;
  245. Binding[] rest = new Binding[size];
  246. for (; names.hasNext() && size > 0; size--)
  247. rest[size - 1] = new Binding((names.next()).components(), BindingType.nobject);
  248. for (; contexts.hasNext() && size > 0; size--)
  249. rest[size - 1] = new Binding((contexts.next()).components(), BindingType.ncontext);
  250. org.omg.CORBA.Object o;
  251. try {
  252. // Iterators are activated with the RootPOA (transient)
  253. byte[] oid = rootPoa.activate_object(new BindingIteratorImpl(rest));
  254. o = rootPoa.id_to_reference(oid);
  255. } catch (Exception e) {
  256. JacORBLogger.ROOT_LOGGER.logInternalError(e);
  257. throw new INTERNAL(e.toString());
  258. }
  259. bi.value = BindingIteratorHelper.narrow(o);
  260. } else {
  261. result = new Binding[size];
  262. for (; names.hasNext() && size > 0; size--)
  263. result[size - 1] = new Binding((names.next()).components(), BindingType.nobject);
  264. for (; contexts.hasNext() && size > 0; size--)
  265. result[size - 1] = new Binding((contexts.next()).components(), BindingType.ncontext);
  266. }
  267. bl.value = result;
  268. }
  269. public NamingContext new_context() {
  270. try {
  271. // create and initialize a new context.
  272. CorbaNamingContext newContextImpl = new CorbaNamingContext();
  273. newContextImpl.init(this.poa, this.doPurge, this.noPing);
  274. // create the oid for the new context and activate it with the naming service POA.
  275. String oid = new String(this.poa.servant_to_id(this)) + "/ctx" + (++this.childCount);
  276. this.poa.activate_object_with_id(oid.getBytes(), newContextImpl);
  277. // add the newly-created context to the cache.
  278. contextImpls.put(oid, newContextImpl);
  279. return NamingContextExtHelper.narrow(this.poa.create_reference_with_id(oid.getBytes(),
  280. "IDL:omg.org/CosNaming/NamingContextExt:1.0"));
  281. } catch (Exception e) {
  282. JacORBLogger.ROOT_LOGGER.failedToCreateNamingContext(e);
  283. return null;
  284. }
  285. }
  286. public void rebind(NameComponent[] nc, org.omg.CORBA.Object obj) throws NotFound, CannotProceed, InvalidName {
  287. if (this.destroyed)
  288. throw new CannotProceed();
  289. if (nc == null || nc.length == 0)
  290. throw new InvalidName();
  291. if (obj == null)
  292. throw new org.omg.CORBA.BAD_PARAM();
  293. Name n = new Name(nc);
  294. Name ctx = n.ctxName();
  295. NameComponent nb = n.baseNameComponent();
  296. if (ctx == null) {
  297. // the name is bound, but it is bound to a context - the client should have been using rebind_context!
  298. if (this.contexts.containsKey(n))
  299. throw new NotFound(NotFoundReason.not_object, new NameComponent[]{nb});
  300. // try remove an existing binding.
  301. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.remove(n);
  302. if (ref != null)
  303. ref._release();
  304. // do the rebinding in this context
  305. this.names.put(n, obj);
  306. JacORBLogger.ROOT_LOGGER.debugBoundName(n.toString());
  307. } else {
  308. // rebind in the correct context
  309. NameComponent[] ncx = new NameComponent[]{nb};
  310. org.omg.CORBA.Object context = this.resolve(ctx.components());
  311. // try first to call the context implementation object directly.
  312. String contextOID = this.getObjectOID(context);
  313. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  314. if (jbossContext != null)
  315. jbossContext.rebind(ncx, obj);
  316. else
  317. NamingContextExtHelper.narrow(context).rebind(ncx, obj);
  318. }
  319. }
  320. public void rebind_context(NameComponent[] nc, NamingContext obj) throws NotFound, CannotProceed, InvalidName {
  321. if (this.destroyed)
  322. throw new CannotProceed();
  323. if (nc == null || nc.length == 0)
  324. throw new InvalidName();
  325. if (obj == null)
  326. throw new org.omg.CORBA.BAD_PARAM();
  327. Name n = new Name(nc);
  328. Name ctx = n.ctxName();
  329. NameComponent nb = n.baseNameComponent();
  330. if (ctx == null) {
  331. // the name is bound, but it is bound to an object - the client should have been using rebind().
  332. if (this.names.containsKey(n))
  333. throw new NotFound(NotFoundReason.not_context, new NameComponent[]{nb});
  334. // try to remove an existing context binding.
  335. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.remove(n);
  336. if (ref != null) {
  337. ref._release();
  338. // remove the old context from the implementation cache.
  339. String oid = this.getObjectOID(ref);
  340. if (oid != null)
  341. contextImpls.remove(oid);
  342. }
  343. this.contexts.put(n, obj);
  344. JacORBLogger.ROOT_LOGGER.debugBoundContext(n.baseNameComponent().id);
  345. } else {
  346. // rebind in the correct context
  347. NameComponent[] ncx = new NameComponent[]{nb};
  348. org.omg.CORBA.Object context = this.resolve(ctx.components());
  349. // try first to call the context implementation object directly.
  350. String contextOID = this.getObjectOID(context);
  351. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  352. if (jbossContext != null)
  353. jbossContext.rebind_context(ncx, obj);
  354. else
  355. NamingContextExtHelper.narrow(context).rebind_context(ncx, obj);
  356. }
  357. }
  358. public org.omg.CORBA.Object resolve(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName {
  359. if (this.destroyed)
  360. throw new CannotProceed();
  361. if (nc == null || nc.length == 0)
  362. throw new InvalidName();
  363. Name n = new Name(nc[0]);
  364. if (nc.length > 1) {
  365. org.omg.CORBA.Object next_context = (org.omg.CORBA.Object) this.contexts.get(n);
  366. if ((next_context == null) || (isDead(next_context)))
  367. throw new NotFound(NotFoundReason.missing_node, nc);
  368. NameComponent[] nc_prime = new NameComponent[nc.length - 1];
  369. System.arraycopy(nc, 1, nc_prime, 0, nc_prime.length);
  370. // try first to call the context implementation object directly.
  371. String contextOID = this.getObjectOID(next_context);
  372. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  373. if (jbossContext != null)
  374. return jbossContext.resolve(nc_prime);
  375. else
  376. return NamingContextExtHelper.narrow(next_context).resolve(nc_prime);
  377. } else {
  378. org.omg.CORBA.Object result = (org.omg.CORBA.Object) this.contexts.get(n);
  379. if (result == null)
  380. result = (org.omg.CORBA.Object) this.names.get(n);
  381. if (result == null)
  382. throw new NotFound(NotFoundReason.missing_node, n.components());
  383. if (!noPing && isDead(result))
  384. throw new NotFound(NotFoundReason.missing_node, n.components());
  385. return result;
  386. }
  387. }
  388. public void unbind(NameComponent[] nc) throws NotFound, CannotProceed, InvalidName {
  389. if (this.destroyed)
  390. throw new CannotProceed();
  391. if (nc == null || nc.length == 0)
  392. throw new InvalidName();
  393. Name n = new Name(nc);
  394. Name ctx = n.ctxName();
  395. NameComponent nb = n.baseNameComponent();
  396. if (ctx == null) {
  397. if (this.names.containsKey(n)) {
  398. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.names.remove(n);
  399. ref._release();
  400. JacORBLogger.ROOT_LOGGER.debugUnboundObject(n.toString());
  401. } else if (this.contexts.containsKey(n)) {
  402. org.omg.CORBA.Object ref = (org.omg.CORBA.Object) this.contexts.remove(n);
  403. ref._release();
  404. // remove the context from the implementation cache.
  405. String oid = this.getObjectOID(ref);
  406. if (oid != null)
  407. contextImpls.remove(oid);
  408. JacORBLogger.ROOT_LOGGER.debugUnboundObject(n.toString());
  409. } else {
  410. JacORBLogger.ROOT_LOGGER.failedToUnbindObject(n.toString());
  411. throw new NotFound(NotFoundReason.not_context, n.components());
  412. }
  413. } else {
  414. NameComponent[] ncx = new NameComponent[]{nb};
  415. org.omg.CORBA.Object context = this.resolve(ctx.components());
  416. // try first to call the context implementation object directly.
  417. String contextOID = this.getObjectOID(context);
  418. CorbaNamingContext jbossContext = (contextOID == null ? null : contextImpls.get(contextOID));
  419. if (jbossContext != null)
  420. jbossContext.unbind(ncx);
  421. else
  422. NamingContextExtHelper.narrow(context).unbind(ncx);
  423. }
  424. }
  425. //======================================= NamingContextExtOperations Methods ==================================//
  426. public org.omg.CORBA.Object resolve_str(String n) throws NotFound, CannotProceed, InvalidName {
  427. return resolve(to_name(n));
  428. }
  429. public NameComponent[] to_name(String sn) throws InvalidName {
  430. return Name.toName(sn);
  431. }
  432. public String to_string(NameComponent[] n) throws InvalidName {
  433. return Name.toString(n);
  434. }
  435. public String to_url(String addr, String sn) throws InvalidAddress, InvalidName {
  436. org.jacorb.orb.util.CorbaLoc corbaLoc;
  437. try {
  438. corbaLoc = new org.jacorb.orb.util.CorbaLoc((org.jacorb.orb.ORB) orb, addr);
  439. return corbaLoc.toCorbaName(sn);
  440. } catch (IllegalArgumentException ia) {
  441. throw new InvalidAddress();
  442. }
  443. }
  444. //======================================= Private Helper Methods ==================================//
  445. /**
  446. * <p>
  447. * Cleanup bindings, i.e. ping every object and remove bindings to non-existent objects.
  448. * </p>
  449. */
  450. private void cleanup() {
  451. // Check if object purging enabled
  452. if (!this.doPurge)
  453. return;
  454. for (Name key : this.names.keySet()) {
  455. if (isDead(((org.omg.CORBA.Object) this.names.get(key)))) {
  456. this.names.remove(key);
  457. }
  458. }
  459. for (Name key : this.contexts.keySet()) {
  460. org.omg.CORBA.Object object = (org.omg.CORBA.Object) this.contexts.get(key);
  461. if (isDead(object)) {
  462. this.contexts.remove(key);
  463. String oid = this.getObjectOID(object);
  464. if (oid != null)
  465. contextImpls.remove(oid);
  466. }
  467. }
  468. }
  469. /**
  470. * <p>
  471. * Obtains the OID of the specified CORBA object.
  472. * </p>
  473. *
  474. * @param object the CORBA object whose OID is to be extracted.
  475. * @return a {@code String} representing the object OID or null if the method is unable to obtain the object OID.
  476. */
  477. private String getObjectOID(org.omg.CORBA.Object object) {
  478. String oid = null;
  479. try {
  480. byte[] oidBytes = this.poa.reference_to_id(object);
  481. if (oidBytes != null)
  482. oid = new String(oidBytes);
  483. } catch (Exception e) {
  484. JacORBLogger.ROOT_LOGGER.failedToObtainIdFromObject(e);
  485. }
  486. return oid;
  487. }
  488. /**
  489. * <p>
  490. * Obtains the number of bindings in this context.
  491. * </p>
  492. *
  493. * @return the number of bindings in this context
  494. */
  495. private int how_many() {
  496. if (this.destroyed)
  497. return 0;
  498. return this.names.size() + this.contexts.size();
  499. }
  500. /**
  501. * <p>
  502. * Determines if the supplied object is non_existent
  503. * </p>
  504. *
  505. * @param o the CORBA object being verified.
  506. * @return {@code true} if the object is non-existent; {@code false} otherwise.
  507. */
  508. private boolean isDead(org.omg.CORBA.Object o) {
  509. boolean non_exist;
  510. try {
  511. non_exist = o._non_existent();
  512. } catch (org.omg.CORBA.SystemException e) {
  513. non_exist = true;
  514. }
  515. return non_exist;
  516. }
  517. /**
  518. * <p>
  519. * Overrides readObject in Serializable.
  520. * </p>
  521. *
  522. * @param in the {@code InputStream} used to read the objects.
  523. * @throws Exception if an error occurs while reading the objects from the stream.
  524. */
  525. private void readObject(ObjectInputStream in) throws Exception {
  526. in.defaultReadObject();
  527. /**
  528. * Recreate tables. For serialization, object references have been transformed into strings
  529. */
  530. for (Name key : this.contexts.keySet()) {
  531. String ref = (String) this.contexts.remove(key);
  532. this.contexts.put(key, orb.string_to_object(ref));
  533. }
  534. for (Name key : this.names.keySet()) {
  535. String ref = (String) this.names.remove(key);
  536. this.names.put(key, orb.string_to_object(ref));
  537. }
  538. }
  539. /**
  540. * <p>
  541. * Overrides writeObject in Serializable.
  542. * </p>
  543. *
  544. * @param out the {@code OutputStream} where the objects will be written.
  545. * @throws IOException if an error occurs while writing the objects to the stream.
  546. */
  547. private void writeObject(java.io.ObjectOutputStream out) throws IOException {
  548. /*
  549. * For serialization, object references are transformed into strings
  550. */
  551. for (Name key : this.contexts.keySet()) {
  552. org.omg.CORBA.Object o = (org.omg.CORBA.Object) this.contexts.remove(key);
  553. this.contexts.put(key, orb.object_to_string(o));
  554. }
  555. for (Name key : this.names.keySet()) {
  556. org.omg.CORBA.Object o = (org.omg.CORBA.Object) this.names.remove(key);
  557. this.names.put(key, orb.object_to_string(o));
  558. }
  559. out.defaultWriteObject();
  560. }
  561. }