Source for gnu.CORBA.Poa.gnuPOA

   1: /* gnuAbstractPOA.java --
   2:    Copyright (C) 2005 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: 
  39: package gnu.CORBA.Poa;
  40: 
  41: import gnu.java.lang.CPStringBuilder;
  42: 
  43: import java.util.ArrayList;
  44: import java.util.Arrays;
  45: import java.util.HashSet;
  46: 
  47: import org.omg.CORBA.BAD_INV_ORDER;
  48: import org.omg.CORBA.BAD_PARAM;
  49: import org.omg.CORBA.CompletionStatus;
  50: import org.omg.CORBA.LocalObject;
  51: import org.omg.CORBA.NO_IMPLEMENT;
  52: import org.omg.CORBA.OBJ_ADAPTER;
  53: import org.omg.CORBA.ORB;
  54: import org.omg.CORBA.Object;
  55: import org.omg.CORBA.Policy;
  56: import org.omg.CORBA.SetOverrideType;
  57: import org.omg.CORBA.TRANSIENT;
  58: import org.omg.CORBA.portable.ObjectImpl;
  59: import org.omg.PortableInterceptor.NON_EXISTENT;
  60: import org.omg.PortableInterceptor.ObjectReferenceFactory;
  61: import org.omg.PortableInterceptor.ObjectReferenceTemplate;
  62: import org.omg.PortableInterceptor.ObjectReferenceTemplateHelper;
  63: import org.omg.PortableServer.AdapterActivator;
  64: import org.omg.PortableServer.ForwardRequest;
  65: import org.omg.PortableServer.IdAssignmentPolicy;
  66: import org.omg.PortableServer.IdAssignmentPolicyValue;
  67: import org.omg.PortableServer.IdUniquenessPolicy;
  68: import org.omg.PortableServer.IdUniquenessPolicyValue;
  69: import org.omg.PortableServer.ImplicitActivationPolicy;
  70: import org.omg.PortableServer.ImplicitActivationPolicyValue;
  71: import org.omg.PortableServer.LifespanPolicy;
  72: import org.omg.PortableServer.LifespanPolicyValue;
  73: import org.omg.PortableServer.POA;
  74: import org.omg.PortableServer.POAManager;
  75: import org.omg.PortableServer.RequestProcessingPolicy;
  76: import org.omg.PortableServer.RequestProcessingPolicyValue;
  77: import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID;
  78: import org.omg.PortableServer.Servant;
  79: import org.omg.PortableServer.ServantActivator;
  80: import org.omg.PortableServer.ServantLocator;
  81: import org.omg.PortableServer.ServantManager;
  82: import org.omg.PortableServer.ServantRetentionPolicy;
  83: import org.omg.PortableServer.ServantRetentionPolicyValue;
  84: import org.omg.PortableServer.ThreadPolicy;
  85: import org.omg.PortableServer.ThreadPolicyValue;
  86: import org.omg.PortableServer.POAManagerPackage.State;
  87: import org.omg.PortableServer.POAPackage.AdapterAlreadyExists;
  88: import org.omg.PortableServer.POAPackage.AdapterNonExistent;
  89: import org.omg.PortableServer.POAPackage.InvalidPolicy;
  90: import org.omg.PortableServer.POAPackage.NoServant;
  91: import org.omg.PortableServer.POAPackage.ObjectAlreadyActive;
  92: import org.omg.PortableServer.POAPackage.ObjectNotActive;
  93: import org.omg.PortableServer.POAPackage.ServantAlreadyActive;
  94: import org.omg.PortableServer.POAPackage.ServantNotActive;
  95: import org.omg.PortableServer.POAPackage.WrongAdapter;
  96: import org.omg.PortableServer.POAPackage.WrongPolicy;
  97: 
  98: import gnu.CORBA.OrbFunctional;
  99: import gnu.CORBA.CDR.BufferredCdrInput;
 100: import gnu.CORBA.CDR.BufferedCdrOutput;
 101: 
 102: /**
 103:  * Our POA implementation.
 104:  *
 105:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
 106:  */
 107: public class gnuPOA
 108:   extends LocalObject
 109:   implements POA, ObjectReferenceFactory
 110: {
 111:   /**
 112:    * The object reference template, associated with this POA.
 113:    *
 114:    * @since 1.5
 115:    */
 116:   class RefTemplate implements ObjectReferenceTemplate
 117:   {
 118:     /**
 119:      * Use serialVersionUID for interoperability.
 120:      */
 121:     private static final long serialVersionUID = 1;
 122: 
 123:     RefTemplate()
 124:     {
 125:       // The adapter name is computed once.
 126:       ArrayList names = new ArrayList();
 127:       names.add(the_name());
 128: 
 129:       POA poa = the_parent();
 130:       while (poa != null)
 131:         {
 132:           names.add(poa.the_name());
 133:           poa = poa.the_parent();
 134:         }
 135: 
 136:       // Fill in the string array in reverse (more natural) order,
 137:       // root POA first.
 138:       m_adapter_name = new String[names.size()];
 139: 
 140:       for (int i = 0; i < m_adapter_name.length; i++)
 141:         m_adapter_name[i] = (String) names.get(m_adapter_name.length - i - 1);
 142:     }
 143: 
 144:     /**
 145:      * The adapter name
 146:      */
 147:     final String[] m_adapter_name;
 148: 
 149:     /**
 150:      * Get the name of this POA.
 151:      */
 152:     public String[] adapter_name()
 153:     {
 154:       return (String[]) m_adapter_name.clone();
 155:     }
 156: 
 157:     /**
 158:      * Get the ORB id.
 159:      */
 160:     public String orb_id()
 161:     {
 162:       return m_orb.orb_id;
 163:     }
 164: 
 165:     /**
 166:      * Get the server id.
 167:      */
 168:     public String server_id()
 169:     {
 170:       return OrbFunctional.server_id;
 171:     }
 172: 
 173:     /**
 174:      * Create the object.
 175:      */
 176:     public Object make_object(String repositoryId, byte[] objectId)
 177:     {
 178:       return create_reference_with_id(objectId, repositoryId);
 179:     }
 180: 
 181:     /**
 182:      * Get the array of truncatible repository ids.
 183:      */
 184:     public String[] _truncatable_ids()
 185:     {
 186:       return ref_template_ids;
 187:     }
 188:   }
 189: 
 190:   /**
 191:    * Use serialVersionUID for interoperability.
 192:    */
 193:   private static final long serialVersionUID = 1;
 194: 
 195:   /**
 196:    * The adapter reference template.
 197:    */
 198:   ObjectReferenceTemplate refTemplate;
 199: 
 200:   /**
 201:    * The reference template repository ids. Defined outside the class as it
 202:    * cannot have static members.
 203:    */
 204:   final static String[] ref_template_ids =
 205:     new String[] { ObjectReferenceTemplateHelper.id() };
 206: 
 207:   /**
 208:    * The active object map, mapping between object keys, objects and servants.
 209:    */
 210:   public final AOM aom = new AOM();
 211: 
 212:   /**
 213:    * The children of this POA.
 214:    */
 215:   final ArrayList children = new ArrayList();
 216: 
 217:   /**
 218:    * The name of this POA.
 219:    */
 220:   final String name;
 221: 
 222:   /**
 223:    * The parent of this POA (null for the root POA).
 224:    */
 225:   final POA parent;
 226: 
 227:   /**
 228:    * The ior key signature, indicating, that the ior key is encoded using
 229:    * internal agreements of this implementation (0x'free').
 230:    */
 231:   static final int SIGNATURE = 0x66726565;
 232: 
 233:   /**
 234:    * The adapter activator for this POA, null if no activator is set.
 235:    */
 236:   AdapterActivator m_activator;
 237: 
 238:   /**
 239:    * The POA manager for this POA.
 240:    */
 241:   POAManager m_manager;
 242: 
 243:   /**
 244:    * The servant manager (servant activator) for this POA.
 245:    */
 246:   ServantActivator servant_activator;
 247: 
 248:   /**
 249:    * The servant manager (servant locator) for this POA.
 250:    */
 251:   ServantLocator servant_locator;
 252: 
 253:   /**
 254:    * The default servant, if on is in use.
 255:    */
 256:   Servant default_servant;
 257: 
 258:   /**
 259:    * The cached poa id value, computed once.
 260:    */
 261:   private byte[] m_poa_id;
 262: 
 263:   /**
 264:    * The all policy values that apply to this POA.
 265:    * The used policy values are singletons, unique between policies.
 266:    */
 267:   private final HashSet m_policies;
 268: 
 269:   /**
 270:    * An array of the set policies.
 271:    */
 272:   Policy[] s_policies;
 273: 
 274:   /**
 275:    * The ORB, where the POA is connected.
 276:    */
 277:   final ORB_1_4 m_orb;
 278: 
 279:   /**
 280:    * When true, the POA is being destroyed or is destroyed.
 281:    */
 282:   boolean m_inDestruction;
 283: 
 284:   /**
 285:    * True if the active object map is used by this POA.
 286:    * The value is moved into separate boolean value due
 287:    * necessity of the frequent checks.
 288:    */
 289:   public final boolean retain_servant;
 290: 
 291:   /**
 292:    * The object reference factory, used to create the new object
 293:    * references.
 294:    */
 295:   ObjectReferenceFactory m_object_factory = this;
 296: 
 297:   /**
 298:    * Create a new abstract POA.
 299:    *
 300:    * @param a_parent the parent of this POA.
 301:    * @param a_name a name for this POA.
 302:    * @param a_manager a manager for this POA. If null, a new
 303:    * {@link gnuPOAManager} will be instantiated.
 304:    * @param a_policies an array of policies that apply to this POA.
 305:    * @param an_orb an ORB for this POA.
 306:    */
 307:   public gnuPOA(gnuPOA a_parent, String a_name, POAManager a_manager,
 308:                 Policy[] a_policies, ORB_1_4 an_orb
 309:                )
 310:          throws InvalidPolicy
 311:   {
 312:     // Add default policies.
 313:     Policy[] all_policies = StandardPolicies.withDefault(a_policies);
 314: 
 315:     name = a_name;
 316:     parent = a_parent;
 317:     m_orb = an_orb;
 318: 
 319:     if (a_manager != null)
 320:       m_manager = a_manager;
 321:     else
 322:       m_manager = new gnuPOAManager();
 323: 
 324:     if (m_manager instanceof gnuPOAManager)
 325:       {
 326:         gnuPOAManager g = (gnuPOAManager) m_manager;
 327:         g.addPoa(this);
 328:       }
 329: 
 330:     m_policies = new HashSet(all_policies.length);
 331: 
 332:     s_policies = new Policy[ all_policies.length ];
 333:     for (int i = 0; i < s_policies.length; i++)
 334:       {
 335:         s_policies [ i ] = all_policies [ i ].copy();
 336:         m_policies.add(((AccessiblePolicy) s_policies [ i ]).getValue());
 337:       }
 338: 
 339:     retain_servant = applies(ServantRetentionPolicyValue.RETAIN);
 340: 
 341:     validatePolicies(a_policies);
 342: 
 343:     refTemplate = new RefTemplate();
 344:   }
 345: 
 346:   /**
 347:    * Wait while at least one of the threads in this POA is actively
 348:    * processing one of requests.
 349:    */
 350:   public void waitWhileRunning()
 351:   {
 352:     // First pause.
 353:     long time = 1;
 354: 
 355:     // Maximal duration between checks.
 356:     long max = 500;
 357: 
 358:     boolean runs;
 359: 
 360:     do
 361:       {
 362:         runs = m_orb.currents.has(this);
 363: 
 364:         if (runs)
 365:           {
 366:             // Avoid taking CPU resources
 367:             // from the thread that is running.
 368:             try
 369:               {
 370:                 Thread.sleep(time);
 371:                 time = time * 2;
 372:                 if (time > max)
 373:                   time = max;
 374:               }
 375:             catch (InterruptedException ex)
 376:               {
 377:               }
 378:           }
 379:       }
 380:     while (runs);
 381:   }
 382: 
 383:   /**
 384:    * Etherealize all objects, associated with this POA. Invoked from the
 385:    * {@link gnuPOAManager} only if it is known that the servant_activator
 386:    * holds non-null value.
 387:    */
 388:   protected void etherealizeAll()
 389:   {
 390:     if (servant_activator == null)
 391:       return;
 392: 
 393:     ArrayList keys = new ArrayList();
 394:     keys.addAll(aom.keySet());
 395: 
 396:     byte[] key;
 397:     AOM.Obj obj;
 398:     boolean last;
 399:     for (int i = 0; i < keys.size(); i++)
 400:       {
 401:         key = (byte[]) keys.get(i);
 402:         obj = aom.get(key);
 403: 
 404:         if (obj.poa == this)
 405:           {
 406:             aom.remove(key);
 407: 
 408:             if (!obj.isDeactiveted())
 409:               {
 410:                 // Check if the servant still stays under the other key.
 411:                 last = aom.findServant(obj.servant) == null;
 412:                 servant_activator.etherealize(obj.key, this, obj.servant, true,
 413:                                               last
 414:                                              );
 415:               }
 416:           }
 417:       }
 418:   }
 419: 
 420:   /**
 421:    * Create an instance of the POA with the given features.
 422:    * This method is not responsible for duplicate checking
 423:    * or adding the returned instance to any possible table.
 424:    *
 425:    * @param child_name the name of the poa being created.
 426:    * @param a_manager the poa manager (never null).
 427:    * @param policies the array of policies.
 428:    * @param an_orb the ORB for this POA.
 429:    *
 430:    * @return the created POA.
 431:    *
 432:    * @throws InvalidPolicy for conflicting or otherwise invalid policies.|
 433:    */
 434:   protected POA createPoaInstance(String child_name, POAManager a_manager,
 435:                                   Policy[] policies, ORB_1_4 an_orb
 436:                                  )
 437:                            throws InvalidPolicy
 438:   {
 439:     POAManager some_manager =
 440:       a_manager == null ? new gnuPOAManager() : a_manager;
 441: 
 442:     if (some_manager instanceof gnuPOAManager)
 443:       {
 444:         ((gnuPOAManager) some_manager).addPoa(this);
 445:       }
 446: 
 447:     return new gnuPOA(this, child_name, some_manager, policies, an_orb);
 448:   }
 449: 
 450:   /**
 451:    * Check if the given policy value applies to this POA.
 452:    *
 453:    * @param policy_value a policy value to check. The policy values are
 454:    * singletons and unique between the different policies, so the policy
 455:    * type is not passed.
 456:    *
 457:    * @return true if the policy value applies, false otherwise.
 458:    */
 459:   public final boolean applies(java.lang.Object policy_value)
 460:   {
 461:     return m_policies.contains(policy_value);
 462:   }
 463: 
 464:   /**
 465:    * Check for the presence of the required policy.
 466:    *
 467:    * @param policy_value a policy value to check.
 468:    *
 469:    * @throws WrongPolicy if the required policy value is not applicable.
 470:    */
 471:   public final void required(java.lang.Object policy_value)
 472:                       throws WrongPolicy
 473:   {
 474:     if (!applies(policy_value))
 475:       throw new WrongPolicy(policy_value + " policy required.");
 476:   }
 477: 
 478:   /**
 479:    * Check for the absence of the given policy.
 480:    *
 481:    * @param policy_value a policy value to check.
 482:    *
 483:    * @throws WrongPolicy if the passed policy value is applicable.
 484:    */
 485:   public final void excluding(java.lang.Object policy_value)
 486:                        throws WrongPolicy
 487:   {
 488:     if (applies(policy_value))
 489:       throw new WrongPolicy(policy_value + " policy applies.");
 490:   }
 491: 
 492:   /**
 493:   * Find and optionally activate the child POA with the given name.
 494:   *
 495:   * @param poa_name the name of the POA to find.
 496:   * @param activate_it if the child with the specified name is not found
 497:   * or inactive and this parameter is true, the target POA activator is
 498:   * invoked to activate that child. If this succeeds, that child POA
 499:   * is returned.
 500:   *
 501:   * @throws AdapterNonExistent if no active child with the given name
 502:   * is found and one of the following is true:
 503:   * a) the target POA has no associated
 504:   * {@link AdapterActivator}. b) that activator fails to activate the
 505:   * child POA. c) <code>activate_id</code> = false.
 506:   */
 507:   public POA find_POA(String poa_name, boolean activate_it)
 508:                throws AdapterNonExistent
 509:   {
 510:     POA child;
 511:     for (int i = 0; i < children.size(); i++)
 512:       {
 513:         child = (POA) children.get(i);
 514:         if (child.the_name().equals(poa_name))
 515:           return child;
 516:       }
 517: 
 518:     if (activate_it && m_activator != null)
 519:       {
 520:         boolean activated = m_activator.unknown_adapter(this, poa_name);
 521:         if (!activated)
 522:           throw new AdapterNonExistent(poa_name + " activation failed.");
 523: 
 524:         // Tha activator should add the child to the childrent table.
 525:         for (int i = 0; i < children.size(); i++)
 526:           {
 527:             child = (POA) children.get(i);
 528:             if (child.the_name().equals(poa_name))
 529:               return child;
 530:           }
 531:         throw new AdapterNonExistent(poa_name + " not created. ");
 532:       }
 533:     else
 534:       throw new AdapterNonExistent(poa_name);
 535:   }
 536: 
 537:   /**
 538:    * Generate the Object Id for the given servant and add the servant to the
 539:    * Active Object Map using this Id a a key. If the servant activator is set,
 540:    * its incarnate method will be called.
 541:    *
 542:    * @param a_servant a servant that would serve the object with the returned
 543:    * Object Id. If null is passed, under apporoprate policies the servant
 544:    * activator is invoked.
 545:    *
 546:    * @return the generated objert Id for the given servant.
 547:    *
 548:    * @throws ServantAlreadyActive if this servant is already in the Active
 549:    * Object Map and the UNIQUE_ID policy applies.
 550:    *
 551:    * @throws WrongPolicy if the required policies SYSTEM_ID and RETAIN do not
 552:    * apply to this POA.
 553:    */
 554:   public byte[] activate_object(Servant a_servant)
 555:     throws ServantAlreadyActive, WrongPolicy
 556:   {
 557:     checkDiscarding();
 558:     required(ServantRetentionPolicyValue.RETAIN);
 559:     required(IdAssignmentPolicyValue.SYSTEM_ID);
 560: 
 561:     AOM.Obj exists = aom.findServant(a_servant);
 562: 
 563:     if (exists != null)
 564:       {
 565:         if (exists.isDeactiveted())
 566:           {
 567:             // If exists but deactivated, activate and return
 568:             // the existing key.
 569:             exists.setDeactivated(false);
 570:             incarnate(exists, exists.key, a_servant, false);
 571:             return exists.key;
 572:           }
 573:         else if (applies(IdUniquenessPolicyValue.UNIQUE_ID))
 574:           throw new ServantAlreadyActive();
 575: 
 576:         // It multiple ids are allowed, exit block allowing repetetive
 577:         // activations.
 578:       }
 579: 
 580:     byte[] object_key = AOM.getFreeId();
 581:     ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this,
 582:       object_key);
 583:     create_and_connect(object_key,
 584:       a_servant._all_interfaces(this, object_key)[0], delegate);
 585:     return object_key;
 586:   }
 587: 
 588:   /**
 589:    * Add the given servant to the Active Object Map as a servant for the object
 590:    * with the provided Object Id. If the servant activator is set, its incarnate
 591:    * method will be called.
 592:    *
 593:    * @param an_Object_Id an object id for the given object.
 594:    * @param a_servant a servant that will serve the object with the given Object
 595:    * Id. If null is passed, under apporoprate policies the servant activator is
 596:    * invoked.
 597:    *
 598:    * @throws ObjectAlreadyActive if the given object id is already in the Active
 599:    * Object Map.
 600:    * @throws ServantAlreadyActive if the UNIQUE_ID policy applies and this
 601:    * servant is already in use.
 602:    * @throws WrongPolicy if the required RETAIN policy does not apply to this
 603:    * POA.
 604:    * @throws BAD_PARAM if the passed object id is invalid due any reason.
 605:    */
 606:   public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant)
 607:                                throws ServantAlreadyActive, ObjectAlreadyActive,
 608:                                       WrongPolicy
 609:   {
 610:     activate_object_with_id(an_Object_Id, a_servant, false);
 611:   }
 612: 
 613:   /**
 614:    * Same as activate_object_with_id, but permits gnuForwardRequest forwarding
 615:    * exception. This is used when the activation is called from the remote
 616:    * invocation context and we have possibility to return the forwarding
 617:    * message.
 618:    */
 619:   public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant,
 620:     boolean use_forwarding)
 621:     throws ServantAlreadyActive, ObjectAlreadyActive, WrongPolicy
 622:   {
 623:     checkDiscarding();
 624:     required(ServantRetentionPolicyValue.RETAIN);
 625: 
 626:     // If the UNIQUE_ID applies, the servant being passed must not be
 627:     // already active.
 628:     if (applies(IdUniquenessPolicyValue.UNIQUE_ID))
 629:       {
 630:         AOM.Obj sx = aom.findServant(a_servant, false);
 631:         if (sx != null)
 632:           throw new ServantAlreadyActive();
 633:       }
 634: 
 635:     AOM.Obj exists = aom.get(an_Object_Id);
 636:     if (exists != null)
 637:       {
 638:         if (exists.servant == null)
 639:           {
 640:             locateServant(an_Object_Id, a_servant, exists, use_forwarding);
 641:             exists.setDeactivated(false);
 642:           }
 643:         else if (exists.isDeactiveted())
 644:           {
 645:             exists.setDeactivated(false);
 646:             incarnate(exists, an_Object_Id, a_servant, use_forwarding);
 647:           }
 648:         else
 649:           throw new ObjectAlreadyActive();
 650:       }
 651:     else
 652:       {
 653:         ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this,
 654:           an_Object_Id);
 655:         create_and_connect(an_Object_Id, a_servant._all_interfaces(this,
 656:           an_Object_Id)[0], delegate);
 657:       }
 658:   }
 659: 
 660:   /**
 661:    * Locate the servant for this object Id and connect it to ORB.
 662:    *
 663:    * @param an_Object_Id the object id.
 664:    * @param a_servant the servant (may be null).
 665:    * @param exists an existing active object map entry.
 666:    * @param use_forwarding allow to throw the gnuForwardRequest if the activator
 667:    * throws ForwardRequest.
 668:    *
 669:    * @throws OBJ_ADAPTER minor 4 if the servant cannot be located (the required
 670:    * servant manager may be missing).
 671:    */
 672:   private void locateServant(byte[] an_Object_Id, Servant a_servant,
 673:                              AOM.Obj exists, boolean use_forwarding
 674:                             )
 675:                       throws InternalError
 676:   {
 677:     // An object was created with create_reference.
 678:     gnuServantObject object = (gnuServantObject) exists.object;
 679:     if (servant_activator != null)
 680:       {
 681:         exists.setServant(incarnate(exists, an_Object_Id, a_servant,
 682:                                     use_forwarding
 683:                                    )
 684:                          );
 685:       }
 686:     else if (default_servant != null)
 687:       {
 688:         exists.setServant(default_servant);
 689:       }
 690:     if (exists.servant == null)
 691:       {
 692:         exists.setServant(a_servant);
 693:       }
 694:     if (exists.servant == null)
 695:       {
 696:         throw new OBJ_ADAPTER("no servant", 4, CompletionStatus.COMPLETED_NO);
 697:       }
 698: 
 699:     ServantDelegateImpl delegate =
 700:       new ServantDelegateImpl(exists.servant, this, an_Object_Id);
 701:     exists.servant._set_delegate(delegate);
 702:     object.setServant(exists.servant);
 703:     connect_to_orb(an_Object_Id, delegate.object);
 704:   }
 705: 
 706:   /**
 707:    * Deactivate object with the given id.
 708:    *
 709:    * The deactivated object will continue to process requests that arrived
 710:    * before decativation. If this POA has the associated
 711:    * servant manager, a {@link ServantActivatorOperations#etherealize} is
 712:    * immediately invoked on the passed id.
 713:    *
 714:    * @throws WrongPolicy if the required RETAIN policy does not apply to
 715:    * this POA.
 716:    */
 717:   public void deactivate_object(byte[] the_Object_Id)
 718:                          throws ObjectNotActive, WrongPolicy
 719:   {
 720:     required(ServantRetentionPolicyValue.RETAIN);
 721: 
 722:     AOM.Obj exists = aom.get(the_Object_Id);
 723: 
 724:     if (exists == null || exists.isDeactiveted())
 725:       throw new ObjectNotActive();
 726: 
 727:     exists.setDeactivated(true);
 728: 
 729:     // Check if this servant is serving something else.
 730:     aom.remove(the_Object_Id);
 731: 
 732:     AOM.Obj other = aom.findServant(exists.servant, false);
 733: 
 734:     boolean remaining = other != null;
 735: 
 736:     aom.put(exists);
 737: 
 738:     if (servant_activator != null)
 739:       servant_activator.etherealize(the_Object_Id, this, exists.servant, false,
 740:                                     remaining
 741:                                    );
 742:   }
 743: 
 744:   /**
 745:   * Create the object reference, encapsulating the given repository Id and
 746:   * the Object Id, generated by this POA. The returned object will not be
 747:   * activated by default and may be activated on the first invocation by
 748:   * the servant manager (if it is set and if policies are applicable).
 749:   *
 750:   * @param a_repository_id the repository id for the given object, can
 751:   * be null if to be requested from the servant later.
 752:   *
 753:   * @throws WrongPolicy if the required SYSTEM_ID policy does not apply to
 754:   * this POA.
 755:   */
 756:   public org.omg.CORBA.Object create_reference(String a_repository_id)
 757:                                         throws WrongPolicy
 758:   {
 759:     required(IdAssignmentPolicyValue.SYSTEM_ID);
 760:     return create_reference_with_id(AOM.getFreeId(), a_repository_id);
 761:   }
 762: 
 763:   /**
 764:    * <p>
 765:    * Create the object reference, encapsulating the given repository Id and
 766:    * the given Object Id. The returned object will <i>not</i> be
 767:    * activated by default and may be activated on the first invocation by
 768:    * the servant manager (if the IMPLICIT_ACTIVATION policy applies).
 769:    *
 770:    * @param an_object_id the object id for the object being created. If this
 771:    * POA uses the SYSTEM_ID policy, the portable application should only
 772:    * pass the ids, generated by this POA.
 773:    *
 774:    * @param a_repository_id the repository id for the object being created,
 775:    * can be null if this information should be later requested from the
 776:    * servant.
 777:    */
 778:   public org.omg.CORBA.Object create_reference_with_id(byte[] an_object_id,
 779:     String a_repository_id
 780:    )
 781:   {
 782:     String[] ids;
 783:     if (a_repository_id == null)
 784:       ids = null;
 785:     else
 786:       ids = new String[] { a_repository_id };
 787: 
 788:     // Check maybe such object is already activated.
 789:     AOM.Obj e = aom.get(an_object_id);
 790: 
 791:     Servant servant;
 792:     if (e == null)
 793:       {
 794:         servant = null;
 795:       }
 796:     else
 797:       {
 798:         servant = e.servant;
 799:         e.setDeactivated(false);
 800:       }
 801: 
 802:     gnuServantObject object =
 803:       new gnuServantObject(ids, an_object_id, this, m_orb);
 804:     object._set_delegate(new LocalDelegate(object, this, an_object_id));
 805:     aom.add(object.Id, object, servant, this);
 806:     connect_to_orb(an_object_id, object);
 807: 
 808:     return object;
 809:   }
 810: 
 811:   /**
 812:    * Creates a new POA as a child of the target POA.
 813:    *
 814:    * @param child_name the name of the child POA being created.
 815:    * @param manager the manager that will control the new POA. If this parameter
 816:    * is null, a new POA manager is created and associated with the new POA.
 817:    *
 818:    * @param policies the policies, applicable for the parent POA. Policies
 819:    * are <i>not</i> inherited from the parent POA.
 820:    *
 821:    * @return an newly created POA. The POA will be intially in the holding
 822:    * state and must be activated to start processing requests.
 823:    *
 824:    * @throws AdapterAlreadyExists if the child with the given child_name
 825:    * already exists for the current POA.
 826:    * @throws InvalidPolicy if the policies conflict with each other or are
 827:    * otherwise inappropriate.
 828:    *
 829:    * @see #the_children()
 830:    */
 831:   public POA create_POA(String child_name, POAManager manager, Policy[] policies)
 832:                  throws AdapterAlreadyExists, InvalidPolicy
 833:   {
 834:     POA child;
 835:     for (int i = 0; i < children.size(); i++)
 836:       {
 837:         child = (POA) children.get(i);
 838:         if (child.the_name().equals(child_name))
 839:           throw new AdapterAlreadyExists(name + "/" + child_name);
 840:       }
 841: 
 842:     POA poa = createPoaInstance(child_name, manager, policies, m_orb);
 843:     children.add(poa);
 844:     return poa;
 845:   }
 846: 
 847:   /**
 848:    * Returns a default servant for this POA.
 849:    *
 850:    * @return a servant that will be used for requests for
 851:    * which no servant is found in the Active Object Map.
 852:    *
 853:    * @throws NoServant if there is no default servant associated with this POA.
 854:    * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active.
 855:    */
 856:   public Servant get_servant()
 857:                       throws NoServant, WrongPolicy
 858:   {
 859:     required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT);
 860:     if (default_servant == null)
 861:       throw new NoServant();
 862:     return default_servant;
 863:   }
 864: 
 865:   /**
 866:    * Sets the default servant for this POA.
 867:    *
 868:    * @param a_servant a servant that will be used for requests for
 869:    * which no servant is found in the Active Object Map.
 870:    *
 871:    * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active.
 872:    */
 873:   public void set_servant(Servant a_servant)
 874:                    throws WrongPolicy
 875:   {
 876:     required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT);
 877:     default_servant = a_servant;
 878:   }
 879: 
 880:   /**
 881:    * Set a servant manager for this POA.
 882:    *
 883:    * @param a servant manager being set. If the RETAIN policy applies, the
 884:    * manager must implement a {@link ServantActivator}. If the NON_RETAIN
 885:    * policy applies, the manager must implement a {@link ServantLocator}.
 886:    *
 887:    * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not
 888:    * apply to this POA.
 889:    *
 890:    * @throws OBJ_ADAPTER minor code 4 if the passed manager does not
 891:    * implement the required interface ({@link ServantActivator},
 892:    * {@link ServantLocator}). The POA, that has the RETAIN policy uses
 893:    * servant managers that are ServantActivators. When the POA has the
 894:    * NON_RETAIN policy it uses servant managers that are ServantLoacators.
 895:    *
 896:    * @throws BAD_INV_ORDER minor code 6 if the method is called more than once
 897:    * on the same POA. The manager can be set only once.
 898:    */
 899:   public void set_servant_manager(ServantManager a_manager)
 900:                            throws WrongPolicy
 901:   {
 902:     required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER);
 903:     if (servant_activator != null || servant_locator != null)
 904:       throw new BAD_INV_ORDER("Setting manager twice for " + name, 6,
 905:                               CompletionStatus.COMPLETED_NO
 906:                              );
 907: 
 908:     if (applies(ServantRetentionPolicyValue.RETAIN))
 909:       {
 910:         if (a_manager instanceof ServantActivator)
 911:           servant_activator = (ServantActivator) a_manager;
 912:         else
 913:           throw new OBJ_ADAPTER("RETAIN requires ServantActivator", 4,
 914:                                 CompletionStatus.COMPLETED_NO
 915:                                );
 916:       }
 917:     else if (applies(ServantRetentionPolicyValue.NON_RETAIN))
 918:       {
 919:         if (a_manager instanceof ServantLocator)
 920:           servant_locator = (ServantLocator) a_manager;
 921:         else
 922:           throw new OBJ_ADAPTER("NON_RETAIN requires ServantLocator", 4,
 923:                                 CompletionStatus.COMPLETED_NO
 924:                                );
 925:       }
 926:     else
 927:       throw new WrongPolicy("No servant retention policy is specified.");
 928:   }
 929: 
 930:   /**
 931:    * Get the servant manager, associated with this POA.
 932:    *
 933:    * @return the associated servant manager or null if it has
 934:    * been previously set.
 935:    *
 936:    * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not
 937:    * apply to this POA.
 938:    */
 939:   public ServantManager get_servant_manager()
 940:                                      throws WrongPolicy
 941:   {
 942:     required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER);
 943: 
 944:     if (servant_activator != null)
 945:       return servant_activator;
 946:     else
 947:       return servant_locator;
 948:   }
 949: 
 950:   /**
 951:    * Get the unique Id of the POA in the process in which it is created.
 952:    * This Id is needed by portable interceptors. The id is unique
 953:    * for the life span of the POA in the process. For persistent
 954:    * POAs, if a POA is created in the same path with the same name as
 955:    * another POA, these POAs are identical have the same id. All transient
 956:    * POAs are assumed unique.
 957:    */
 958:   public byte[] id()
 959:   {
 960:     if (m_poa_id != null)
 961:       return m_poa_id;
 962:     else
 963:       {
 964:         BufferedCdrOutput buffer = new BufferedCdrOutput();
 965:         POA p = this;
 966:         while (p != null)
 967:           {
 968:             buffer.write_string(p.the_name());
 969:             p = p.the_parent();
 970:           }
 971:         m_poa_id = buffer.buffer.toByteArray();
 972:         return m_poa_id;
 973:       }
 974:   }
 975: 
 976:   /**
 977:    * Returns the reference to the active object with the given Id.
 978:    *
 979:    * @param the_Object_Id the object id.
 980:    *
 981:    * @throws ObjectNotActive if there is no active object with such Id
 982:    * in the scope of this POA.
 983:    * @throws WrongPolicy if the required RETAIN policy does not apply to
 984:    * this POA.
 985:    */
 986:   public org.omg.CORBA.Object id_to_reference(byte[] the_Object_Id)
 987:                                        throws ObjectNotActive, WrongPolicy
 988:   {
 989:     required(ServantRetentionPolicyValue.RETAIN);
 990: 
 991:     AOM.Obj ref = aom.get(the_Object_Id);
 992:     if (ref == null)
 993:       throw new ObjectNotActive();
 994:     else
 995:       return ref.object;
 996:   }
 997: 
 998:   /**
 999:    * Returns the servant that serves the active object with the given Id.
1000:    *
1001:    * @param the_Object_Id the object id.
1002:    *
1003:    * @throws ObjectNotActive if there is no active object with such Id or
1004:    * it is not currently active.
1005:    * @throws WrongPolicy. This method requires either RETAIN or
1006:    * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them
1007:    * apply to this POA.
1008:    */
1009:   public Servant id_to_servant(byte[] the_Object_Id)
1010:                         throws ObjectNotActive, WrongPolicy
1011:   {
1012:     if (applies(ServantRetentionPolicyValue.RETAIN))
1013:       {
1014:         AOM.Obj ref = aom.get(the_Object_Id);
1015:         if (ref == null || ref.isDeactiveted())
1016:           {
1017:             if (default_servant != null)
1018:               return default_servant;
1019:             else
1020:               throw new ObjectNotActive();
1021:           }
1022:         else if (ref.servant != null)
1023:           return ref.servant;
1024:         else if (default_servant != null)
1025:           return default_servant;
1026:         else
1027:           throw new ObjectNotActive();
1028:       }
1029:     else if (default_servant != null)
1030:       {
1031:         return default_servant;
1032:       }
1033:     else
1034:       throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required.");
1035:   }
1036: 
1037:   /**
1038:    * Returns the Object Id, encapsulated in the given object reference.
1039:    *
1040:    * @param the_Object the object that has been previously created with this
1041:    * POA. It need not be active.
1042:    *
1043:    * @throws WrongAdapter if the passed object is not known for this POA.
1044:    * @throws WrongPolicy never (declared for the future extensions only).
1045:    */
1046:   public byte[] reference_to_id(org.omg.CORBA.Object the_Object)
1047:                          throws WrongAdapter, WrongPolicy
1048:   {
1049:     AOM.Obj ref = aom.findObject(the_Object);
1050:     if (ref == null)
1051:       throw new WrongAdapter();
1052:     return ref.key;
1053:   }
1054: 
1055:   /**
1056:    * Returns the servant that is serving this object.
1057:    *
1058:    * @return if the RETAIN policy applies and the object is in the Active Object
1059:    * Map, the method returns the servant, associated with this object.
1060:    * Otherwise, if the USE_DEFAULT_SERVANT policy applies, the method returns
1061:    * the default servant (if one was set).
1062:    *
1063:    * @throws ObjectNotActive if none of the conditions above are satisfied.
1064:    * @throws WrongAdapter if the object reference was not created with this POA.
1065:    * @throws WrongPolicy. This method requires either RETAIN or
1066:    * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them
1067:    * apply to this POA.
1068:    */
1069:   public Servant reference_to_servant(org.omg.CORBA.Object the_Object)
1070:     throws ObjectNotActive, WrongPolicy, WrongAdapter
1071:   {
1072:     if (applies(ServantRetentionPolicyValue.RETAIN))
1073:       {
1074:         AOM.Obj ref = aom.findObject(the_Object);
1075:         if (ref == null)
1076:           {
1077:             String object;
1078:             if (the_Object == null)
1079:               object = "null passed";
1080:             else if (the_Object instanceof gnuServantObject)
1081:               {
1082:                 gnuServantObject gs = (gnuServantObject) the_Object;
1083:                 object = "Wrong owner POA " + gs.poa.the_name();
1084:               }
1085:             else
1086:               object = "Unknown " + the_Object.getClass().getName();
1087: 
1088:             throw new WrongAdapter(object + " for '" + the_name() + "'");
1089:           }
1090:         else if (ref.isDeactiveted() || ref.servant == null)
1091:           {
1092:             if (default_servant != null)
1093:               return default_servant;
1094:             else
1095:               throw new ObjectNotActive();
1096:           }
1097:         else
1098:           return ref.servant;
1099:       }
1100:     else if (default_servant != null)
1101:       {
1102:         return default_servant;
1103:       }
1104:     else
1105:       throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required.");
1106:   }
1107: 
1108:   /**
1109:    * Returns the id of the object, served by the given servant (assuming that
1110:    * the servant serves only one object). The id is found in one of the
1111:    * following ways.
1112:    * <ul>
1113:    * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and the
1114:    * specified servant is active, the method return the Object Id associated
1115:    * with that servant. </li>
1116:    * <li> If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and
1117:    * either the POA has the MULTIPLE_ID policy or the specified servant is
1118:    * inactive, the method activates the servant using a POA-generated Object Id
1119:    * and the Interface Id associated with the servant, and returns that Object
1120:    * Id. </li>
1121:    * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified
1122:    * is the default servant, and the method is being invoked in the context of
1123:    * executing a request on the default servant, the method returns the ObjectId
1124:    * associated with the current invocation. </li>
1125:    * </ul>
1126:    *
1127:    * @throws ServantNotActive in all cases, not listed in the list above.
1128:    * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or a
1129:    * combination of the RETAIN policy and either the UNIQUE_ID or
1130:    * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions
1131:    * are not satisfied.
1132:    */
1133:   public byte[] servant_to_id(Servant the_Servant)
1134:                        throws ServantNotActive, WrongPolicy
1135:   {
1136:     if (applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) ||
1137:         applies(ServantRetentionPolicyValue.RETAIN) &&
1138:         (
1139:           applies(IdUniquenessPolicyValue.UNIQUE_ID) ||
1140:           applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)
1141:         )
1142:        )
1143:       {
1144:         AOM.Obj ref = null;
1145:         if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID))
1146:           ref = aom.findServant(the_Servant);
1147:         if (ref == null &&
1148:             applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)
1149:            )
1150:           {
1151:             // Try to activate.
1152:             try
1153:               {
1154:                 return activate_object(the_Servant);
1155:               }
1156:             catch (ServantAlreadyActive ex)
1157:               {
1158:                 // Either it shuld not be or the policy allows multiple ids.
1159:                 throw new InternalError();
1160:               }
1161:           }
1162:         if (ref == null)
1163:           throw new ServantNotActive();
1164:         else
1165:           return ref.key;
1166:       }
1167:     else
1168:       throw new WrongPolicy("(RETAIN and UNIQUE ID) " +
1169:                             "or USE_DEFAULT_SERVANT required."
1170:                            );
1171:   }
1172: 
1173:   /**
1174:    * <p>
1175:    * Converts the given servant to the object reference. The servant will serve
1176:    * all methods, invoked on the returned object. The returned object reference
1177:    * can be passed to the remote client, enabling remote invocations.
1178:    * </p>
1179:    * <p>
1180:    * If the specified servant is active, it is returned. Otherwise, if the POA
1181:    * has the IMPLICIT_ACTIVATION policy the method activates the servant. In
1182:    * this case, if the servant activator is set, the
1183:    * {@link ServantActivatorOperations#incarnate} method will be called.
1184:    * </p>
1185:    *
1186:    * @throws ServantNotActive if the servant is inactive and no
1187:    * IMPLICIT_ACTIVATION policy applies.
1188:    * @throws WrongPolicy This method needs the RETAIN policy and either the
1189:    * UNIQUE_ID or IMPLICIT_ACTIVATION policies.
1190:    *
1191:    * @return the object, exposing the given servant in the context of this POA.
1192:    */
1193:   public org.omg.CORBA.Object servant_to_reference(Servant the_Servant)
1194:     throws ServantNotActive, WrongPolicy
1195:   {
1196:     required(ServantRetentionPolicyValue.RETAIN);
1197: 
1198:     AOM.Obj exists = null;
1199: 
1200:     if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID))
1201:       exists = aom.findServant(the_Servant);
1202: 
1203:     if (exists != null)
1204:       {
1205:         if (exists.isDeactiveted())
1206:           {
1207:             if (applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION))
1208:               {
1209:                 checkDiscarding();
1210:                 exists.setDeactivated(false);
1211:                 incarnate(exists, exists.key, the_Servant, false);
1212:               }
1213:             else
1214:               throw new ServantNotActive();
1215:           }
1216:         else
1217:           return exists.object;
1218:       }
1219:     if (exists == null
1220:       && applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION))
1221:       {
1222:         checkDiscarding();
1223: 
1224:         byte[] object_key = AOM.getFreeId();
1225: 
1226:         ServantDelegateImpl delegate = new ServantDelegateImpl(the_Servant,
1227:           this, object_key);
1228:         create_and_connect(object_key, the_Servant._all_interfaces(this,
1229:           object_key)[0], delegate);
1230: 
1231:         return delegate.object;
1232:       }
1233:     else
1234:       throw new ServantNotActive();
1235:   }
1236: 
1237:   /**
1238:    * Incarnate in cases when request forwarding is not expected because the
1239:    * servant must be provided by the servant activator.
1240:    *
1241:    * @param x the aom entry, where the object is replaced by value, returned by
1242:    * servant activator (if not null).
1243:    *
1244:    * @param object_key the object key.
1245:    *
1246:    * @param a_servant the servant that was passed as a parameter in the
1247:    * activation method.
1248:    *
1249:    * @param use_forwarding if true, the gnuForwardRequest is throw under the
1250:    * forwarding exception (for remote client). Otherwise, the request is
1251:    * internally redirected (for local invocation).
1252:    */
1253:   private Servant incarnate(AOM.Obj x, byte[] object_key,
1254:                             Servant a_servant, boolean use_forwarding
1255:                            )
1256:   {
1257:     if (servant_activator != null)
1258:       {
1259:         Servant servant;
1260:         try
1261:           {
1262:             servant = servant_activator.incarnate(object_key, this);
1263:           }
1264:         catch (ForwardRequest ex)
1265:           {
1266:             if (use_forwarding)
1267:               throw new gnuForwardRequest(ex.forward_reference);
1268:             else
1269:               servant =
1270:                 ForwardedServant.create((ObjectImpl) ex.forward_reference);
1271:           }
1272:         if (servant != null && x != null)
1273:           x.setServant(servant);
1274:         if (servant == null && x != null)
1275:           servant = x.servant;
1276:         return servant;
1277:       }
1278:     else if (a_servant != null)
1279:       {
1280:         x.setServant(a_servant);
1281:         return a_servant;
1282:       }
1283:     else if (x.servant != null)
1284:       {
1285:         return x.servant;
1286:       }
1287:     else if (default_servant != null)
1288:       {
1289:         x.setServant(default_servant);
1290:         return x.servant;
1291:       }
1292:     else
1293:       throw new BAD_INV_ORDER("No servant given and the servant activator not set");
1294:   }
1295: 
1296:   /**
1297:    * Return the POA manager, associated with this POA.
1298:    *
1299:    * @return the associated POA manager (always available).
1300:    */
1301:   public POAManager the_POAManager()
1302:   {
1303:     return m_manager;
1304:   }
1305: 
1306:   /**
1307:    * Returns the adapter activator, associated with this POA.
1308:    * The newly created POA has no activator (null would be
1309:    * returned). The ORB root POA also initially has no activator.
1310:    *
1311:    * @return tha adapter activator or null if this POA has no
1312:    * associated adapter activator.
1313:    */
1314:   public AdapterActivator the_activator()
1315:   {
1316:     return m_activator;
1317:   }
1318: 
1319:   /**
1320:   * Set the adapter activator for this POA.
1321:   *
1322:   * @param an_activator the activator being set.
1323:   */
1324:   public void the_activator(AdapterActivator an_activator)
1325:   {
1326:     m_activator = an_activator;
1327:   }
1328: 
1329:   /**
1330:   * The children of this POA.
1331:   *
1332:   * @return the array of all childs for this POA.
1333:   */
1334:   public POA[] the_children()
1335:   {
1336:     POA[] poas = new POA[ children.size() ];
1337:     for (int i = 0; i < poas.length; i++)
1338:       {
1339:         poas [ i ] = (POA) children.get(i);
1340:       }
1341:     return poas;
1342:   }
1343: 
1344:   /**
1345:    * Return the name of this POA.
1346:    *
1347:    * @return the name of POA, relative to its parent.
1348:    */
1349:   public String the_name()
1350:   {
1351:     return name;
1352:   }
1353: 
1354:   /**
1355:    * Return the parent of this POA.
1356:    *
1357:    * @return the parent POA or <code>null</code> if this is a root POA.
1358:    */
1359:   public POA the_parent()
1360:   {
1361:     return parent;
1362:   }
1363: 
1364:   /** {@inheritDoc} */
1365:   public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue a_value)
1366:   {
1367:     return new gnuIdAssignmentPolicy(a_value);
1368:   }
1369: 
1370:   /** {@inheritDoc} */
1371:   public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue a_value)
1372:   {
1373:     return new gnuIdUniquenessPolicy(a_value);
1374:   }
1375: 
1376:   /** {@inheritDoc} */
1377:   public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue a_value)
1378:   {
1379:     return new gnuImplicitActivationPolicy(a_value);
1380:   }
1381: 
1382:   /** {@inheritDoc} */
1383:   public LifespanPolicy create_lifespan_policy(LifespanPolicyValue a_value)
1384:   {
1385:     return new gnuLifespanPolicy(a_value);
1386:   }
1387: 
1388:   /** {@inheritDoc} */
1389:   public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue a_value)
1390:   {
1391:     return new gnuRequestProcessingPolicy(a_value);
1392:   }
1393: 
1394:   /** {@inheritDoc} */
1395:   public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue a_value)
1396:   {
1397:     return new gnuServantRetentionPolicy(a_value);
1398:   }
1399: 
1400:   /** {@inheritDoc} */
1401:   public ThreadPolicy create_thread_policy(ThreadPolicyValue a_value)
1402:   {
1403:     return new gnuThreadPolicy(a_value);
1404:   }
1405: 
1406:   /**
1407:    * <p>
1408:    * Destroy this POA and all descendant POAs. The destroyed POAs can be later
1409:    * re-created via {@link AdapterActivator} or by invoking {@link #create_POA}.
1410:    * This differs from {@link PoaManagerOperations#deactivate} that does not
1411:    * allow recreation of the deactivated POAs. After deactivation, recreation is
1412:    * only possible if the POAs were later destroyed.
1413:    * </p>
1414:    * <p>
1415:    * The remote invocation on the target, belonging to the POA that is currently
1416:    * destroyed return the remote exception ({@link TRANSIENT}, minor code 4).
1417:    * </p>
1418:    *
1419:    * @param etherealize_objects if true, and POA has RETAIN policy, and the
1420:    * servant manager is available, the servant manager method
1421:    * {@link ServantActivatorOperations#etherealize} is called for each <i>active</i>
1422:    * object in the Active Object Map. This method should not try to access POA
1423:    * being destroyed. If <code>destroy</code> is called multiple times before
1424:    * the destruction completes, the etherialization should be invoked only once.
1425:    *
1426:    * @param wait_for_completion if true, the method waits till the POA being
1427:    * destroyed completes all current requests and etherialization. If false, the
1428:    * method returns immediately.
1429:    */
1430:   public void destroy(boolean etherealize_objects, boolean wait_for_completion)
1431:   {
1432:     // Notify the IOR interceptors about that the POA is destroyed.
1433:     if (m_orb.iIor != null)
1434:       m_orb.iIor.adapter_state_changed(
1435:         new ObjectReferenceTemplate[] { getReferenceTemplate() },
1436:         NON_EXISTENT.value);
1437: 
1438:     if (wait_for_completion)
1439:       waitWhileRunning();
1440: 
1441:     // Nofify the IOR interceptors that the POA is destroyed.
1442:     if (m_manager instanceof gnuPOAManager)
1443:       {
1444:         ((gnuPOAManager) m_manager).poaDestroyed(this);
1445:       }
1446: 
1447:     // Put the brake instead of manager, preventing the subsequent
1448:     // requests.
1449:     gnuPOAManager g = new gnuPOAManager();
1450:     g.state = State.INACTIVE;
1451:     m_manager = g;
1452: 
1453:     // Disconnect from parent.
1454:     if (parent instanceof gnuPOA)
1455:       {
1456:         ((gnuPOA) parent).children.remove(this);
1457:       }
1458: 
1459:     unregisterFromManager();
1460: 
1461:     // Disconnect from the ORB all objects, registered with this POA.
1462:     ArrayList keys = new ArrayList();
1463:     keys.addAll(aom.keySet());
1464: 
1465:     byte[] key;
1466:     AOM.Obj obj;
1467:     for (int i = 0; i < keys.size(); i++)
1468:       {
1469:         key = (byte[]) keys.get(i);
1470:         obj = aom.get(key);
1471:         if (obj.poa == this)
1472:           m_orb.disconnect(obj.object);
1473:       }
1474: 
1475:     m_orb.identityDestroyed(this);
1476: 
1477:     if (etherealize_objects && servant_activator != null && !m_inDestruction)
1478:       {
1479:         etherealizeAll();
1480:       }
1481:     m_inDestruction = true;
1482: 
1483:     POA[] ch = the_children();
1484:     for (int i = 0; i < ch.length; i++)
1485:       {
1486:         ch[i].destroy(etherealize_objects, wait_for_completion);
1487:       }
1488:   }
1489: 
1490:   /**
1491:    * Destroy this POA if it has not been destroyed, destroys it.
1492:    */
1493:   protected void finalize()
1494:                    throws java.lang.Throwable
1495:   {
1496:     if (!m_inDestruction)
1497:       destroy(false, false);
1498:   }
1499: 
1500:   /**
1501:    * Remove self from the manager list.
1502:    */
1503:   private void unregisterFromManager()
1504:   {
1505:     if (m_manager instanceof gnuPOAManager)
1506:       {
1507:         gnuPOAManager p = (gnuPOAManager) m_manager;
1508:         p.removePOA(this);
1509:       }
1510:   }
1511: 
1512:   /**
1513:    * Get the policy of the given type, associated with this POA.
1514:    *
1515:    * @param a_policy_type a type of the requested policy.
1516:    * @return a policy of the given type, applyting to this POA.
1517:    *
1518:    * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not
1519:    * been specified for this POA.
1520:    */
1521:   public Policy _get_policy(int a_policy_type)
1522:                      throws org.omg.CORBA.BAD_PARAM
1523:   {
1524:     for (int i = 0; i < s_policies.length; i++)
1525:       {
1526:         if (s_policies [ i ].policy_type() == a_policy_type)
1527:           return s_policies [ i ].copy();
1528:       }
1529:     throw new BAD_PARAM("No policy type " + a_policy_type);
1530:   }
1531: 
1532:   /**
1533:    * Get the copy of the policy array.
1534:    */
1535:   public Policy[] getPolicyArray()
1536:   {
1537:     Policy[] r = new Policy[ s_policies.length ];
1538:     for (int i = 0; i < s_policies.length; i++)
1539:       {
1540:         r [ i ] = s_policies [ i ].copy();
1541:       }
1542:     return r;
1543:   }
1544: 
1545:   /**
1546:    * The POAs cannot be created by this method.
1547:    *
1548:    * @specnote this is also not possible in Suns jdk at least till 1.4.
1549:    *
1550:    * @throws NO_IMPLEMENT always.
1551:    */
1552:   public org.omg.CORBA.Object _set_policy_override(Policy[] policies,
1553:                                                    SetOverrideType how
1554:                                                   )
1555:   {
1556:     throw new NO_IMPLEMENT("Use createPOA instead.");
1557:   }
1558: 
1559:   /**
1560:    * Get the ORB, where this POA is connected.
1561:    */
1562:   public ORB orb()
1563:   {
1564:     return m_orb;
1565:   }
1566: 
1567:   /**
1568:    * Connect the given delegate under the given key, also calling incarnate.
1569:    */
1570:   private void create_and_connect(byte[] object_key, String repository_id,
1571:     ServantDelegateImpl delegate)
1572:   {
1573:     aom.add(delegate);
1574:     connect_to_orb(object_key, getReferenceFactory().make_object(repository_id,
1575:       object_key));
1576:     if (servant_activator != null)
1577:       incarnate(null, object_key, delegate.servant, false);
1578:   }
1579: 
1580:   /**
1581:    * Check if the POA is not in a discarding mode. The activation
1582:    * operations are forbidded in discarding mode.
1583:    *
1584:    * @throws TRANSIENT if the POA is in discarding mode.
1585:    */
1586:   void checkDiscarding()
1587:                         throws TRANSIENT
1588:   {
1589:     if (m_manager.get_state() == State.DISCARDING)
1590:       throw new TRANSIENT("Discarding mode", 1, CompletionStatus.COMPLETED_MAYBE);
1591:   }
1592: 
1593:   /**
1594:    * Connect the given delegate object to orb.
1595:    */
1596:   protected void connect_to_orb(byte[] an_Object_Id, org.omg.CORBA.Object object)
1597:   {
1598:     if (applies(ThreadPolicyValue.SINGLE_THREAD_MODEL))
1599:       m_orb.connect_1_thread(object, toIORKey(an_Object_Id), this);
1600:     else
1601:       m_orb.connect(object, toIORKey(an_Object_Id));
1602:   }
1603: 
1604:   /**
1605:    * Returns the representation of this POA tree.
1606:    */
1607:   public String toString()
1608:   {
1609:     CPStringBuilder b = new CPStringBuilder(name);
1610: 
1611:     if (children.size() != 0)
1612:       {
1613:         b.append(" (");
1614: 
1615:         for (int i = 0; i < children.size(); i++)
1616:           {
1617:             b.append(children.get(i));
1618:             if (i < children.size() - 2)
1619:               b.append(", ");
1620:           }
1621:         b.append(")");
1622:       }
1623:     return b.toString();
1624:   }
1625: 
1626:   /**
1627:    * Check if the policy set is valid.
1628:    */
1629:   protected boolean validatePolicies(Policy[] a)
1630:                               throws InvalidPolicy
1631:   {
1632:     if (applies(ServantRetentionPolicyValue.NON_RETAIN))
1633:       {
1634:         if (!applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) &&
1635:             !applies(RequestProcessingPolicyValue.USE_SERVANT_MANAGER)
1636:            )
1637:           {
1638:             short p = 0;
1639:             for (short i = 0; i < a.length; i++)
1640:               {
1641:                 if (a [ i ].policy_type() == SERVANT_RETENTION_POLICY_ID.value)
1642:                   p = i;
1643:               }
1644:             throw new InvalidPolicy("NON_RETAIN requires either " +
1645:                                     "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER",
1646:                                     p
1647:                                    );
1648:           }
1649:       }
1650:     return true;
1651:   }
1652: 
1653:   /**
1654:    * Recursively searches for the given object in the POA tree.
1655:    */
1656:   public AOM.Obj findObject(org.omg.CORBA.Object object)
1657:   {
1658:     AOM.Obj h = aom.findObject(object);
1659:     if (h != null)
1660:       return h;
1661:     else
1662:       {
1663:         for (int i = 0; i < children.size(); i++)
1664:           {
1665:             h = ((gnuPOA) children.get(i)).findObject(object);
1666:             if (h != null)
1667:               return h;
1668:           }
1669:       }
1670:     return h;
1671:   }
1672: 
1673:   /**
1674:    * Recursively searches for the given key in the POA tree.
1675:    * @param ior_key the key, ecapsulating both object
1676:    * and poa ids.
1677:    * @return
1678:    */
1679:   public AOM.Obj findKey(byte[] object_id, byte[] poa_id)
1680:   {
1681:     AOM.Obj h = null;
1682:     if (Arrays.equals(poa_id, id()))
1683:       h = aom.get(object_id);
1684:     if (h != null)
1685:       return h;
1686:     else
1687:       {
1688:         for (int i = 0; i < children.size(); i++)
1689:           {
1690:             h = ((gnuPOA) children.get(i)).findKey(object_id, poa_id);
1691:             if (h != null)
1692:               return h;
1693:           }
1694:       }
1695:     return h;
1696:   }
1697: 
1698:   /**
1699:    * Parses the given key, extracts poa and object id and searches
1700:    * for such reference.
1701:    */
1702:   public AOM.Obj findIorKey(byte[] ior_key)
1703:   {
1704:     BufferredCdrInput in = new BufferredCdrInput(ior_key);
1705:     int signature = in.read_long();
1706:     if (signature != SIGNATURE)
1707:       return null;
1708: 
1709:     byte[] id = in.read_sequence();
1710:     byte[] poa = in.read_sequence();
1711:     return findKey(id, poa);
1712:   }
1713: 
1714:   /**
1715:    * Converts the object Id into the IOR key. IOR key must be
1716:    * unique in the scope of the ORB, and Ids only in the scope of POA.
1717:    * Hence the IOR key includes the POA identifiers.
1718:    */
1719:   public byte[] toIORKey(byte[] object_id)
1720:   {
1721:     BufferedCdrOutput buffer = new BufferedCdrOutput();
1722:     buffer.write_long(SIGNATURE);
1723:     buffer.write_sequence(object_id);
1724:     buffer.write_sequence(id());
1725:     return buffer.buffer.toByteArray();
1726:   }
1727: 
1728:   /**
1729:    * Extracts the object id from the ior key.
1730:    *
1731:    * @param ior_key
1732:    *
1733:    * @return the encapsulated object ior key or null if
1734:    * this ior key either refers a different POA or encoding signature
1735:    * mismatch.
1736:    */
1737:   public byte[] idFormIor(byte[] ior_key)
1738:   {
1739:     BufferredCdrInput in = new BufferredCdrInput(ior_key);
1740:     int signature = in.read_long();
1741:     if (signature != SIGNATURE)
1742:       return null;
1743: 
1744:     byte[] object_id = in.read_sequence();
1745:     byte[] poa_id = in.read_sequence();
1746:     if (Arrays.equals(poa_id, id()))
1747:       return object_id;
1748:     else
1749:       return null;
1750:   }
1751: 
1752:   /**
1753:    * Recursively searches for the given servant in the POA tree.
1754:    */
1755:   public AOM.Obj findServant(Servant servant)
1756:   {
1757:     AOM.Obj h = aom.findServant(servant);
1758:     if (h != null)
1759:       return h;
1760:     else
1761:       {
1762:         for (int i = 0; i < children.size(); i++)
1763:           {
1764:             h = ((gnuPOA) children.get(i)).findServant(servant);
1765:             if (h != null)
1766:               return h;
1767:           }
1768:       }
1769:     return h;
1770:   }
1771: 
1772:   /**
1773:    * Get the object reference template of this POA.
1774:    * Instantiate a singleton instance, if required.
1775:    */
1776:   public ObjectReferenceTemplate getReferenceTemplate()
1777:   {
1778:     if (refTemplate == null)
1779:       refTemplate = new RefTemplate();
1780: 
1781:     return refTemplate;
1782:   }
1783: 
1784:   public ObjectReferenceFactory getReferenceFactory()
1785:   {
1786:     return m_object_factory;
1787:   }
1788: 
1789:   public void setReferenceFactory(ObjectReferenceFactory factory)
1790:   {
1791:     m_object_factory = factory;
1792:   }
1793: 
1794:   /**
1795:    * Create the object (needed by the factory interface).
1796:    */
1797:   public Object make_object(String a_repository_id, byte[] an_object_id)
1798:   {
1799:     AOM.Obj existing = aom.get(an_object_id);
1800:     // The object may already exist. In this case, it is just returned.
1801:     if (existing != null && existing.object != null)
1802:       return existing.object;
1803:     else
1804:       {
1805:         return new gnuServantObject(new String[] { a_repository_id },
1806:           an_object_id, this, m_orb);
1807:       }
1808:   }
1809: 
1810:   /**
1811:    * Required by object reference factory ops.
1812:    */
1813:   public String[] _truncatable_ids()
1814:   {
1815:     return ref_template_ids;
1816:   }
1817: }