Source for gnu.javax.naming.giop.ContextContinuation

   1: /* ContextContinuation.java -- handles corbaname: urls
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package gnu.javax.naming.giop;
  39: 
  40: import gnu.CORBA.NamingService.Ext;
  41: import gnu.CORBA.NamingService.NameTransformer;
  42: 
  43: import java.util.Hashtable;
  44: 
  45: import javax.naming.Binding;
  46: import javax.naming.Context;
  47: import javax.naming.ContextNotEmptyException;
  48: import javax.naming.InvalidNameException;
  49: import javax.naming.Name;
  50: import javax.naming.NameAlreadyBoundException;
  51: import javax.naming.NameClassPair;
  52: import javax.naming.NameNotFoundException;
  53: import javax.naming.NameParser;
  54: import javax.naming.NamingEnumeration;
  55: import javax.naming.NamingException;
  56: import javax.naming.OperationNotSupportedException;
  57: import javax.naming.directory.InvalidAttributesException;
  58: 
  59: import org.omg.CORBA.ORB;
  60: import org.omg.CORBA.portable.Delegate;
  61: import org.omg.CORBA.portable.ObjectImpl;
  62: import org.omg.CosNaming.BindingIteratorHolder;
  63: import org.omg.CosNaming.BindingListHolder;
  64: import org.omg.CosNaming.NameComponent;
  65: import org.omg.CosNaming.NamingContext;
  66: import org.omg.CosNaming.NamingContextExt;
  67: import org.omg.CosNaming.NamingContextExtHelper;
  68: import org.omg.CosNaming.NamingContextHelper;
  69: import org.omg.CosNaming._NamingContextExtStub;
  70: import org.omg.CosNaming._NamingContextStub;
  71: import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
  72: import org.omg.CosNaming.NamingContextPackage.CannotProceed;
  73: import org.omg.CosNaming.NamingContextPackage.InvalidName;
  74: import org.omg.CosNaming.NamingContextPackage.NotFound;
  75: 
  76: /**
  77:  * The context to represent the corba naming service. Being the naming service,
  78:  * the returned context supports creating the subcontexts, forwarding this task
  79:  * to the existing naming service. When listing bindings, it uses the
  80:  * {@link Context#BATCHSIZE} property to determine, how many bindings should
  81:  * be returned at once (the process is transparend)
  82:  *
  83:  * @author Audrius Meskauskas (audriusa@Bioinformatics.org)
  84:  */
  85: public class ContextContinuation implements Context
  86: {
  87:   /**
  88:    * This number of bindings will be requested from the naming server at once,
  89:    * while the subsequent bindings will be requested via binding iterator one by
  90:    * one. Use {@link Context#BATCHSIZE} to override the value of this constant.
  91:    */
  92:   public int DEFAULT_BATCH_SIZE = 20;
  93: 
  94:   /**
  95:    * The actual CORBA naming service.
  96:    */
  97:   NamingContextExt service;
  98: 
  99:   /**
 100:    * The object request broker, used to access the naming service. This field
 101:    * is only initialised when the context is constructed from the URL.
 102:    */
 103:   ORB orb;
 104: 
 105:   /**
 106:    * The properties.
 107:    */
 108:   Hashtable properties;
 109: 
 110:   /**
 111:    * The parent factory.
 112:    */
 113:   GiopNamingServiceFactory factory;
 114: 
 115:   /**
 116:    * The name transformer to obtain the name from its string representation. The
 117:    * to_name method of the naming service is avoided as it may be remote and
 118:    * hence expensive. The conversion rules are standard and cannot be service
 119:    * specific.
 120:    */
 121:   static NameTransformer transformer = new NameTransformer();
 122: 
 123:   /**
 124:    * The batch size for list operations - how many to return at once.
 125:    */
 126:   public final int howMany;
 127: 
 128:   /**
 129:    * Creates a new naming context that uses naming service, represented by the
 130:    * given CORBA object.
 131:    *
 132:    * @param nsObject
 133:    *          the naming service object. It must be possible to narrow it into
 134:    *          the NamingContextExt.
 135:    * @param props
 136:    *          the environment table.
 137:    * @param anOrb
 138:    *          the associated ORB. This reference is used during cleanup.
 139:    * @param aFactory
 140:    *          parent factory. This reference is used during cleanup.
 141:    */
 142:   public ContextContinuation(org.omg.CORBA.Object nsObject,
 143:                                      Hashtable props, ORB anOrb,
 144:                                      GiopNamingServiceFactory aFactory)
 145:   {
 146:     factory = aFactory;
 147:     orb = anOrb;
 148: 
 149:     Delegate delegate = ((ObjectImpl) nsObject)._get_delegate();
 150: 
 151:     // If the IOR provides the IDL ID, we can check if our name
 152:     // service is old NamingContext or new NamingContextExt.
 153:     // Not all forms of the URL always provide the IDL id.
 154:     if (!nsObject._is_a(NamingContextExtHelper.id())
 155:         && nsObject._is_a(NamingContextHelper.id()))
 156:       {
 157:         // We are surely working with the old version.
 158:         _NamingContextStub stub = new _NamingContextStub();
 159:         stub._set_delegate(delegate);
 160:         // The Ext object will add the necessary extensions.
 161:         service = new Ext(stub);
 162:       }
 163:     else
 164:       {
 165:         // We expecte the service to be the NamingContextExt (this is true
 166:         // for both Sun's and our implementations). There is no easy way
 167:         // to check the version.
 168:         _NamingContextExtStub stub = new _NamingContextExtStub();
 169:         stub._set_delegate(delegate);
 170:         service = stub;
 171:       }
 172:     properties = props;
 173:     howMany = getBatchSize();
 174:   }
 175: 
 176:   /**
 177:    * Give the specified name for the specified object. The passed name must not
 178:    * be already bound to some other object. The components of the name are
 179:    * mapped into the components of the CORBA name.
 180:    *
 181:    * @param name
 182:    *          the name that will be given to the object (in the scope of this
 183:    *          context).
 184:    * @param obj
 185:    *          the object being named.
 186:    * @throws NameAlreadyBoundException
 187:    *           if this name is already used to name some object.
 188:    * @throws InvalidAttributesException
 189:    *           if the object does not supply all required attributes.
 190:    * @throws NamingException
 191:    *           if the naming operation has failed due other reasons.
 192:    */
 193:   public void bind(Name name, Object obj) throws NamingException
 194:   {
 195:     try
 196:       {
 197:         org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
 198:         service.bind(toGiop(name), object);
 199:       }
 200:     catch (ClassCastException e)
 201:       {
 202:         throw new NamingException(org.omg.CORBA.Object.class + " required ");
 203:       }
 204:     catch (InvalidName e)
 205:       {
 206:         throw new InvalidNameException();
 207:       }
 208:     catch (AlreadyBound e)
 209:       {
 210:         throw new NameAlreadyBoundException();
 211:       }
 212:     catch (Exception e)
 213:       {
 214:         throw new NamingException(e.toString());
 215:       }
 216:   }
 217: 
 218:   /**
 219:    * Give the specified name for the specified object. The passed name must not
 220:    * be already bound to some other object.
 221:    *
 222:    * @param name
 223:    *          the name that will be given to the object (in the scope of this
 224:    *          context).
 225:    * @param obj
 226:    *          the object being named.
 227:    * @throws NameAlreadyBoundException
 228:    *           if this name is already used to name some object.
 229:    * @throws InvalidAttributesException
 230:    *           if the object does not supply all required attributes.
 231:    * @throws NamingException
 232:    *           if the naming operation has failed due other reasons.
 233:    */
 234:   public void bind(String name, Object obj) throws NamingException
 235:   {
 236:     try
 237:       {
 238:         org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
 239:         service.bind(transformer.toName(name), object);
 240:       }
 241:     catch (ClassCastException e)
 242:       {
 243:         throw new NamingException(org.omg.CORBA.Object.class + " required ");
 244:       }
 245:     catch (InvalidName e)
 246:       {
 247:         throw new InvalidNameException();
 248:       }
 249:     catch (AlreadyBound e)
 250:       {
 251:         throw new NameAlreadyBoundException();
 252:       }
 253:     catch (Exception e)
 254:       {
 255:         throw new NamingException(e.toString());
 256:       }
 257:   }
 258: 
 259:   /**
 260:    * Releases all resources, associated with this context. The close() method
 261:    * can be called several times, but after it has been once invoked, it is not
 262:    * allowed to call any other method of this context. This method destroys
 263:    * the ORB, if we have one.
 264:    *
 265:    * @throws NamingException
 266:    */
 267:   public void close() throws NamingException
 268:   {
 269:     if (orb != null && factory !=null)
 270:       {
 271:         factory.checkIfReferenced(orb);
 272:       }
 273:   }
 274: 
 275:   /**
 276:    * Not supported.
 277:    */
 278:   public Name composeName(Name name, Name prefix) throws NamingException
 279:   {
 280:     throw new OperationNotSupportedException();
 281:   }
 282: 
 283:   /**
 284:    * Not supported
 285:    */
 286:   public String composeName(String name1, String name2) throws NamingException
 287:   {
 288:     throw new OperationNotSupportedException();
 289:   }
 290: 
 291:   /**
 292:    * Creates the new naming subcontext and binds it to the current (this)
 293:    * context. The returned object will wrap around the newly created CORBA
 294:    * subcontext
 295:    *
 296:    * @param subContext
 297:    *          the name of the new context being created
 298:    * @return the newly created context, bound to the instance of the context on
 299:    *         that the method has been called
 300:    * @throws NameAlreadyBoundException
 301:    *           if this name is already bound
 302:    * @throws InvalidAttributesException
 303:    *           if the creation of the new context requires the missing mandatory
 304:    *           attributes
 305:    * @throws NamingException
 306:    */
 307:   public Context createSubcontext(Name subContext) throws NamingException
 308:   {
 309:     try
 310:       {
 311:         org.omg.CORBA.Object subcontext = service.bind_new_context(
 312:           toGiop(subContext));
 313:         Hashtable clonedProps = new Hashtable();
 314:         clonedProps.putAll(properties);
 315: 
 316:         // Nulls are passed both for orb and factory, as the child contexts
 317:         // need not to do any cleanup.
 318:         return new ContextContinuation(subcontext, clonedProps, null, null);
 319:       }
 320:     catch (AlreadyBound e)
 321:       {
 322:         throw new NameAlreadyBoundException();
 323:       }
 324:     catch (InvalidName e)
 325:       {
 326:         throw new InvalidNameException();
 327:       }
 328:     catch (Exception ex)
 329:       {
 330:         throw new NamingException(ex.toString());
 331:       }
 332:   }
 333: 
 334:   /**
 335:    * Creates the new naming subcontext and binds it to the current (this)
 336:    * context. The returned object will wrap around the newly created CORBA
 337:    * subcontext
 338:    *
 339:    * @param subContext
 340:    *          the name of the new context being created
 341:    * @return the newly created context, bound to the instance of the context on
 342:    *         that the method has been called
 343:    * @throws NameAlreadyBoundException
 344:    *           if this name is already bound
 345:    * @throws InvalidAttributesException
 346:    *           if the creation of the new context requires the missing mandatory
 347:    *           attributes
 348:    * @throws NamingException
 349:    */
 350:   public Context createSubcontext(String subContext) throws NamingException
 351:   {
 352:     try
 353:       {
 354:         org.omg.CORBA.Object subcontext =
 355:           service.bind_new_context(transformer.toName(subContext));
 356:         Hashtable clonedProps = new Hashtable();
 357:         clonedProps.putAll(properties);
 358: 
 359:         // Nulls are passed both for orb and factory, as the child contexts
 360:         // need not to do any cleanup.
 361:         return new ContextContinuation(subcontext, clonedProps, null,
 362:                                                null);
 363:       }
 364:     catch (AlreadyBound e)
 365:       {
 366:         throw new NameAlreadyBoundException(subContext);
 367:       }
 368:     catch (InvalidName e)
 369:       {
 370:         throw new InvalidNameException(subContext);
 371:       }
 372:     catch (Exception ex)
 373:       {
 374:         throw new NamingException(ex.toString());
 375:       }
 376:   }
 377: 
 378:   /**
 379:    * Removes the naming subcontext from this naming context. Returns without
 380:    * action if such subcontext does not exist. The context being destroyed must
 381:    * be empty.
 382:    *
 383:    * @param subContext
 384:    *          the name of the subcontext beig removed.
 385:    * @throws ContextNotEmptyException
 386:    *           if the named context is not empty.
 387:    * @throws NamingException
 388:    */
 389:   public void destroySubcontext(Name subContext) throws NamingException
 390:   {
 391:     unbind(subContext);
 392:   }
 393: 
 394:   /**
 395:    * Removes the naming subcontext from this naming context. Returns without
 396:    * action if such subcontext does not exist. The context being destroyed must
 397:    * be empty.
 398:    *
 399:    * @param subContext
 400:    *          the name of the subcontext beig removed.
 401:    * @throws ContextNotEmptyException
 402:    *           if the named context is not empty.
 403:    * @throws NamingException
 404:    */
 405:   public void destroySubcontext(String subContext) throws NamingException
 406:   {
 407:     unbind(subContext);
 408:   }
 409: 
 410:   /**
 411:    * Returs the full name of this naming context. The returned string is not a
 412:    * JNDI composite name and should not be passed directly to the methods of the
 413:    * naming context. This implementation returns the IOR.
 414:    *
 415:    * @return the full name of this naming context, in its own namespace.
 416:    * @throws OperationNotSupportedException
 417:    *           if the naming system, represented by this context, does not
 418:    *           support the notation of the full name.
 419:    * @throws NamingException
 420:    */
 421:   public String getNameInNamespace() throws NamingException
 422:   {
 423:     if (orb != null)
 424:       return orb.object_to_string(service);
 425:     else
 426:       {
 427:         try
 428:           {
 429:             ObjectImpl impl = (ObjectImpl) service;
 430:             return impl._orb().object_to_string(impl);
 431:           }
 432:         catch (ClassCastException e)
 433:           {
 434:             throw new UnsupportedOperationException();
 435:           }
 436:       }
 437:   }
 438: 
 439:   /**
 440:    * Not supported.
 441:    */
 442:   public NameParser getNameParser(Name name) throws NamingException
 443:   {
 444:     throw new UnsupportedOperationException();
 445:   }
 446: 
 447:   /**
 448:    * Not supported.
 449:    */
 450:   public NameParser getNameParser(String name) throws NamingException
 451:   {
 452:     throw new UnsupportedOperationException();
 453:   }
 454: 
 455:   /**
 456:    * Creates and returns the enumeration over the name bindings that are present
 457:    * the given subcontext. The enumeration elements have the type of
 458:    * {@link NameClassPair}, providing also information about the class of the
 459:    * bound object. The behaviour in the case if the bindings are added or
 460:    * removed later is not defined. The contents of the subcontexts are not
 461:    * included.
 462:    *
 463:    * @param name
 464:    *          the name of the subcontext
 465:    * @return the enumeration over the names, known for the given subcontext.
 466:    * @throws NamingException
 467:    */
 468:   public NamingEnumeration list(Name name) throws NamingException
 469:   {
 470:     BindingIteratorHolder bi = new BindingIteratorHolder();
 471:     BindingListHolder bl = new BindingListHolder();
 472: 
 473:     NamingContext subcontext;
 474: 
 475:     if (name.size() == 0)
 476:       subcontext = service;
 477:     else
 478:       {
 479:         try
 480:           {
 481:             subcontext = (NamingContextHelper.narrow(service.resolve(toGiop(name))));
 482:           }
 483:         catch (Exception e)
 484:           {
 485:             throw new NamingException(e.toString());
 486:           }
 487: 
 488:       }
 489: 
 490:     subcontext.list(howMany, bl, bi);
 491: 
 492:     return new ListEnumeration(bl, bi, howMany);
 493:   }
 494: 
 495:   /**
 496:    * Creates and returns the enumeration over the name bindings that are present
 497:    * the given subcontext. The enumeration elements have the type of
 498:    * {@link NameClassPair}, providing also information about the class of the
 499:    * bound object. The behaviour in the case if the bindings are added or
 500:    * removed later is not defined. The contents of the subcontexts are not
 501:    * included.
 502:    *
 503:    * @param name
 504:    *          the name of the subcontext
 505:    * @return the enumeration over the names, known for the given subcontext.
 506:    * @throws NamingException
 507:    */
 508:   public NamingEnumeration list(String name) throws NamingException
 509:   {
 510:     BindingIteratorHolder bi = new BindingIteratorHolder();
 511:     BindingListHolder bl = new BindingListHolder();
 512: 
 513:     NamingContext subcontext;
 514: 
 515:     if (name.length() == 0)
 516:       subcontext = service;
 517:     else
 518:       {
 519:         try
 520:           {
 521:             subcontext = (NamingContextHelper.narrow(service.resolve_str(name)));
 522:           }
 523:         catch (Exception e)
 524:           {
 525:             throw new NamingException(e.toString());
 526:           }
 527: 
 528:       }
 529: 
 530:     subcontext.list(howMany, bl, bi);
 531: 
 532:     return new ListEnumeration(bl, bi, howMany);
 533:   }
 534: 
 535:   /**
 536:    * Creates and returns the enumeration over the name - object bindings that
 537:    * are present the given subcontext. The enumeration elements have the type of
 538:    * {@link Binding}, providing also information about the class of the bound
 539:    * object. The behaviour in the case if the bindings are added or removed
 540:    * later is not defined. The contents of the subcontexts are not included.
 541:    *
 542:    * @param name
 543:    *          the name of the subcontext
 544:    * @return the enumeration over the names, known for the given subcontext.
 545:    * @throws NamingException
 546:    */
 547:   public NamingEnumeration listBindings(Name name) throws NamingException
 548:   {
 549:     BindingIteratorHolder bi = new BindingIteratorHolder();
 550:     BindingListHolder bl = new BindingListHolder();
 551: 
 552:     NamingContext subcontext;
 553: 
 554:     if (name.size() == 0)
 555:       subcontext = service;
 556:     else
 557:       {
 558:         try
 559:           {
 560:             subcontext = (NamingContextHelper.narrow(service.resolve(toGiop(name))));
 561:           }
 562:         catch (Exception e)
 563:           {
 564:             throw new NamingException(e.toString());
 565:           }
 566:       }
 567: 
 568:     subcontext.list(howMany, bl, bi);
 569: 
 570:     return new ListBindingsEnumeration(bl, bi, howMany, subcontext);
 571:   }
 572: 
 573:   /**
 574:    * Creates and returns the enumeration over the name - object bindings that
 575:    * are present the given subcontext. The enumeration elements have the type of
 576:    * {@link Binding}, providing also information about the class of the bound
 577:    * object. The behaviour in the case if the bindings are added or removed
 578:    * later is not defined. The contents of the subcontexts are not included.
 579:    *
 580:    * @param name
 581:    *          the name of the subcontext
 582:    * @return the enumeration over the names, known for the given subcontext.
 583:    * @throws NamingException
 584:    */
 585:   public NamingEnumeration listBindings(String name) throws NamingException
 586:   {
 587:     BindingIteratorHolder bi = new BindingIteratorHolder();
 588:     BindingListHolder bl = new BindingListHolder();
 589: 
 590:     NamingContext subcontext;
 591: 
 592:     if (name.length() == 0)
 593:       subcontext = service;
 594:     else
 595:       {
 596:         try
 597:           {
 598:             subcontext = (NamingContextHelper.narrow(service.resolve_str(name)));
 599:           }
 600:         catch (Exception e)
 601:           {
 602:             throw new NamingException(e.toString());
 603:           }
 604: 
 605:       }
 606: 
 607:     subcontext.list(howMany, bl, bi);
 608: 
 609:     return new ListBindingsEnumeration(bl, bi, howMany, subcontext);
 610:   }
 611: 
 612:   /**
 613:    * Gets the previously named object by name. If the passed name is empty, the
 614:    * method should return a cloned instance of this naming context.
 615:    *
 616:    * @param name
 617:    *          the name of the object being searched in this context
 618:    * @return the named object
 619:    * @throws NameNotFountException
 620:    *           if the name is not found
 621:    */
 622:   public Object lookup(Name name) throws NamingException
 623:   {
 624:     try
 625:       {
 626:         return service.resolve(toGiop(name));
 627:       }
 628:     catch (NotFound e)
 629:       {
 630:         throw new NameNotFoundException();
 631:       }
 632:     catch (InvalidName e)
 633:       {
 634:         throw new InvalidNameException();
 635:       }
 636:     catch (Exception e)
 637:       {
 638:         throw new NamingException(e.toString());
 639:       }
 640:   }
 641: 
 642:   /**
 643:    * Gets the previously named object by name. If the passed name is empty, the
 644:    * method should return a cloned instance of this naming context.
 645:    *
 646:    * @param name
 647:    *          the name of the object being searched in this context
 648:    * @return the named object
 649:    * @throws NamingException
 650:    *           if the naming fails.
 651:    */
 652:   public Object lookup(String name) throws NamingException
 653:   {
 654:     try
 655:       {
 656:         return service.resolve_str(name);
 657:       }
 658:     catch (NotFound e)
 659:       {
 660:         throw new NameNotFoundException();
 661:       }
 662:     catch (InvalidName e)
 663:       {
 664:         throw new InvalidNameException();
 665:       }
 666:     catch (Exception e)
 667:       {
 668:         throw new NamingException(e.toString());
 669:       }
 670:   }
 671: 
 672:   /**
 673:    * Not supported.
 674:    */
 675:   public Object lookupLink(Name name) throws NamingException
 676:   {
 677:     throw new OperationNotSupportedException();
 678:   }
 679: 
 680:   /**
 681:    * Not supported.
 682:    */
 683:   public Object lookupLink(String name) throws NamingException
 684:   {
 685:     throw new OperationNotSupportedException();
 686:   }
 687: 
 688:   /**
 689:    * Give the specified name for the specified object. Unlike bind, this method
 690:    * silently replaces the existing binding for this name, if one exists.
 691:    *
 692:    * @param name
 693:    *          the name that will be given to the object (in the scope of this
 694:    *          context).
 695:    * @param obj
 696:    *          the object being named.
 697:    * @throws InvalidAttributesException
 698:    *           if the object does not supply all required attributes.
 699:    * @throws NamingException
 700:    *           if the naming operation has failed due other reasons.
 701:    */
 702:   public void rebind(Name name, Object obj) throws NamingException
 703:   {
 704:     try
 705:       {
 706:         org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
 707:         service.rebind(toGiop(name), object);
 708:       }
 709:     catch (ClassCastException e)
 710:       {
 711:         throw new NamingException(org.omg.CORBA.Object.class + " required ");
 712:       }
 713:     catch (InvalidName e)
 714:       {
 715:         throw new InvalidNameException();
 716:       }
 717:     catch (Exception e)
 718:       {
 719:         throw new NamingException(e.toString());
 720:       }
 721:   }
 722: 
 723:   /**
 724:    * Give the specified name for the specified object. Unlike bind, this method
 725:    * silently replaces the existing binding for this name, if one exists.
 726:    *
 727:    * @param name
 728:    *          the name that will be given to the object (in the scope of this
 729:    *          context).
 730:    * @param obj
 731:    *          the object being named.
 732:    * @throws InvalidAttributesException
 733:    *           if the object does not supply all required attributes.
 734:    * @throws NamingException
 735:    *           if the naming operation has failed due other reasons.
 736:    */
 737:   public void rebind(String name, Object obj) throws NamingException
 738:   {
 739:     try
 740:       {
 741:         org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
 742:         service.rebind(transformer.toName(name), object);
 743:       }
 744:     catch (ClassCastException e)
 745:       {
 746:         throw new NamingException(org.omg.CORBA.Object.class + " required ");
 747:       }
 748:     catch (InvalidName e)
 749:       {
 750:         throw new InvalidNameException();
 751:       }
 752:     catch (Exception e)
 753:       {
 754:         throw new NamingException(e.toString());
 755:       }
 756:   }
 757: 
 758:   /**
 759:    * Renames the existing binding, removing the existing and giving the new name
 760:    * for the same object.
 761:    *
 762:    * @param oldName
 763:    *          the existing name of the known object
 764:    * @param newName
 765:    *          the new name of the same object
 766:    * @throws NameNotFoundException
 767:    *           if the oldName is unknown for this context
 768:    * @throws NamingException
 769:    *           if the naming operation has failed due other reasons.
 770:    */
 771:   public void rename(Name oldName, Name newName) throws NamingException
 772:   {
 773:     Object object = lookup(oldName);
 774:     unbind(oldName);
 775:     bind(newName, object);
 776:   }
 777: 
 778:   /**
 779:    * Renames the existing binding, removing the existing and giving the new name
 780:    * for the same object.
 781:    *
 782:    * @param oldName
 783:    *          the existing name of the known object
 784:    * @param newName
 785:    *          the new name of the same object
 786:    * @throws NameNotFoundException
 787:    *           if the oldName is unknown for this context
 788:    * @throws NamingException
 789:    *           if the naming operation has failed due other reasons.
 790:    */
 791:   public void rename(String oldName, String newName) throws NamingException
 792:   {
 793:     Object object = lookup(oldName);
 794:     unbind(oldName);
 795:     bind(newName, object);
 796:   }
 797: 
 798:   /**
 799:    * Removes the name - object mapping from the current context. This method
 800:    * returns without action if the name is not bound to an object in the
 801:    * terminal context, but throws {@link NameNotFoundException} if one of the
 802:    * intermadiate contexts does not exist.
 803:    *
 804:    * @param name
 805:    *          the name to be removed
 806:    * @throws NameNotFoundException
 807:    *           if one of the intermediate naming contexts does not exist. Will
 808:    *           not be thrown if just the terminal binding is missing.
 809:    * @throws NamingException
 810:    *           if the naming operation has failed due other reasons.
 811:    */
 812:   public void unbind(Name name) throws NamingException
 813:   {
 814:     try
 815:       {
 816:         service.unbind(toGiop(name));
 817:       }
 818:     catch (NotFound e)
 819:       {
 820:         throw new NameNotFoundException();
 821:       }
 822:     catch (CannotProceed e)
 823:       {
 824:         throw new ContextNotEmptyException();
 825:       }
 826:     catch (InvalidName e)
 827:       {
 828:         throw new InvalidNameException();
 829:       }
 830:   }
 831: 
 832:   /**
 833:    * Removes the name - object mapping from the current context. This method
 834:    * returns without action if the name is not bound to an object in the
 835:    * terminal context, but throws {@link NameNotFoundException} if one of the
 836:    * intermadiate contexts does not exist.
 837:    *
 838:    * @param name
 839:    *          the name to be removed
 840:    * @throws NameNotFoundException
 841:    *           if one of the intermediate naming contexts does not exist. Will
 842:    *           not be thrown if just the terminal binding is missing.
 843:    * @throws NamingException
 844:    *           if the naming operation has failed due other reasons.
 845:    */
 846:   public void unbind(String name) throws NamingException
 847:   {
 848:     try
 849:       {
 850:         service.unbind(transformer.toName(name));
 851:       }
 852:     catch (NotFound e)
 853:       {
 854:         throw new NameNotFoundException(name);
 855:       }
 856:     catch (CannotProceed e)
 857:       {
 858:         throw new ContextNotEmptyException(name);
 859:       }
 860:     catch (InvalidName e)
 861:       {
 862:         throw new InvalidNameException(name);
 863:       }
 864:   }
 865: 
 866:  /**
 867:    * Add new environment property to the environment of this context. Both name
 868:    * and value of the new property must not be null. If the property is already
 869:    * defined, is current value is replaced by the propVal.
 870:    *
 871:    * @param key
 872:    *          the name of the new property
 873:    * @param value
 874:    *          the value of the new property
 875:    * @return the previous value of this property or null if the property has not
 876:    *         been previously defined
 877:    * @throws NamingException
 878:    */
 879:   public Object addToEnvironment(String key, Object value)
 880:       throws NamingException
 881:   {
 882:     if (key == null || value == null)
 883:       throw new NullPointerException();
 884:     return properties.put(key, value);
 885:   }
 886: 
 887:   /**
 888:    * Returns the environment, associated with this naming context. The returned
 889:    * table should never be modified by the caller. Use {@link #addToEnvironment}
 890:    * and {@link #removeFromEnvironment} to modify the environement, if needed.
 891:    *
 892:    * @return the table, representing the environment of this context
 893:    * @throws NamingException
 894:    */
 895:   public Hashtable getEnvironment() throws NamingException
 896:   {
 897:     return properties;
 898:   }
 899: 
 900:   /**
 901:    * Removes the property with the given name from the environment. Returns
 902:    * without action if this property is not defined.
 903:    *
 904:    * @param propName
 905:    *          the name of the property being removed.
 906:    * @return the value of the property that has been removed or null if the
 907:    *         property was not defined.
 908:    * @throws NamingException
 909:    */
 910:   public Object removeFromEnvironment(String propName) throws NamingException
 911:   {
 912:     return properties.remove(propName);
 913:   }
 914: 
 915:   /**
 916:    * Convert the {@link Name} into array of the name components, required to the
 917:    * CORBA naming service. First the string representation is obtained, then
 918:    * it is converted using parsing rules of the CORBA name.
 919:    *
 920:    * @param name
 921:    *          then name to convert
 922:    * @return the converted array of components.
 923:    */
 924:   public NameComponent[] toGiop(Name name) throws InvalidName
 925:   {
 926:     return transformer.toName(name.toString());
 927:   }
 928: 
 929:   /**
 930:    * Get the batch size from the environment properties. The batch size is used
 931:    * for listing operations.
 932:    *
 933:    * @return the batch size, or some default value if not specified.
 934:    */
 935:   public int getBatchSize()
 936:   {
 937:     int batchSize = DEFAULT_BATCH_SIZE;
 938:     Object bs = properties.get(Context.BATCHSIZE);
 939:     if (bs != null)
 940:       {
 941:         try
 942:           {
 943:             int b = Integer.parseInt(bs.toString());
 944:             if (b >= 0)
 945:               batchSize = b;
 946:           }
 947:         catch (NumberFormatException e)
 948:           {
 949:             // OK, use default value.
 950:           }
 951:       }
 952:     return batchSize;
 953:   }
 954: 
 955: 
 956: }