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