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
1057:    * Object 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,
1069:                                       WrongAdapter
1070:   {
1071:     if (applies(ServantRetentionPolicyValue.RETAIN))
1072:       {
1073:         AOM.Obj ref = aom.findObject(the_Object);
1074:         if (ref == null)
1075:           throw new WrongAdapter();
1076:         else if (ref.isDeactiveted() || ref.servant == null)
1077:           {
1078:             if (default_servant != null)
1079:               return default_servant;
1080:             else
1081:               throw new ObjectNotActive();
1082:           }
1083:         else
1084:           return ref.servant;
1085:       }
1086:     else if (default_servant != null)
1087:       {
1088:         return default_servant;
1089:       }
1090:     else
1091:       throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required.");
1092:   }
1093: 
1094:   /**
1095:   * Returns the id of the object, served by the given servant
1096:   * (assuming that the servant serves only one object).
1097:   * The id is found in one of the following ways.
1098:   * <ul>
1099:   * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and
1100:   * the specified servant is active, the method return the Object Id associated
1101:   * with that servant.
1102:   * </li><li>
1103:   * If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and
1104:   * either the POA has the MULTIPLE_ID policy or the specified servant is
1105:   * inactive, the method activates the servant using a POA-generated Object Id
1106:   * and the Interface Id associated with the servant, and returns that
1107:   * Object Id.
1108:   * </li>
1109:   * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified
1110:   * is the default servant, and the method is being invoked in the context of
1111:   * executing a request on the default servant, the method returns the
1112:   * ObjectId associated with the current invocation.
1113:   * </li>
1114:   * </ul>
1115:   * @throws ServantNotActive in all cases, not listed in the list above.
1116:   * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or
1117:   * a combination of the RETAIN policy and either the UNIQUE_ID or
1118:   * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions
1119:   * are not satisfied.
1120:   */
1121:   public byte[] servant_to_id(Servant the_Servant)
1122:                        throws ServantNotActive, WrongPolicy
1123:   {
1124:     if (applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) ||
1125:         applies(ServantRetentionPolicyValue.RETAIN) &&
1126:         (
1127:           applies(IdUniquenessPolicyValue.UNIQUE_ID) ||
1128:           applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)
1129:         )
1130:        )
1131:       {
1132:         AOM.Obj ref = null;
1133:         if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID))
1134:           ref = aom.findServant(the_Servant);
1135:         if (ref == null &&
1136:             applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)
1137:            )
1138:           {
1139:             // Try to activate.
1140:             try
1141:               {
1142:                 return activate_object(the_Servant);
1143:               }
1144:             catch (ServantAlreadyActive ex)
1145:               {
1146:                 // Either it shuld not be or the policy allows multiple ids.
1147:                 throw new InternalError();
1148:               }
1149:           }
1150:         if (ref == null)
1151:           throw new ServantNotActive();
1152:         else
1153:           return ref.key;
1154:       }
1155:     else
1156:       throw new WrongPolicy("(RETAIN and UNIQUE ID) " +
1157:                             "or USE_DEFAULT_SERVANT required."
1158:                            );
1159:   }
1160: 
1161:   /**
1162:    * <p>
1163:    * Converts the given servant to the object reference. The servant will serve
1164:    * all methods, invoked on the returned object. The returned object reference
1165:    * can be passed to the remote client, enabling remote invocations.
1166:    * </p>
1167:    * <p>
1168:    * If the specified servant is active, it is returned. Otherwise, if the POA
1169:    * has the IMPLICIT_ACTIVATION policy the method activates the servant. In
1170:    * this case, if the servant activator is set, the
1171:    * {@link ServantActivatorOperations#incarnate} method will be called.
1172:    * </p>
1173:    * 
1174:    * @throws ServantNotActive if the servant is inactive and no
1175:    * IMPLICIT_ACTIVATION policy applies.
1176:    * @throws WrongPolicy This method needs the RETAIN policy and either the
1177:    * UNIQUE_ID or IMPLICIT_ACTIVATION policies.
1178:    * 
1179:    * @return the object, exposing the given servant in the context of this POA.
1180:    */
1181:   public org.omg.CORBA.Object servant_to_reference(Servant the_Servant)
1182:     throws ServantNotActive, WrongPolicy
1183:   {
1184:     required(ServantRetentionPolicyValue.RETAIN);
1185: 
1186:     AOM.Obj exists = null;
1187: 
1188:     if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID))
1189:       exists = aom.findServant(the_Servant);
1190: 
1191:     if (exists != null)
1192:       {
1193:         if (exists.isDeactiveted())
1194:           {
1195:             if (applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION))
1196:               {
1197:                 checkDiscarding();
1198:                 exists.setDeactivated(false);
1199:                 incarnate(exists, exists.key, the_Servant, false);
1200:               }
1201:             else
1202:               throw new ServantNotActive();
1203:           }
1204:         else
1205:           return exists.object;
1206:       }
1207:     if (exists == null
1208:       && applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION))
1209:       {
1210:         checkDiscarding();
1211: 
1212:         byte[] object_key = AOM.getFreeId();
1213: 
1214:         ServantDelegateImpl delegate = new ServantDelegateImpl(the_Servant,
1215:           this, object_key);
1216:         create_and_connect(object_key, the_Servant._all_interfaces(this,
1217:           object_key)[0], delegate);
1218: 
1219:         return delegate.object;
1220:       }
1221:     else
1222:       throw new ServantNotActive();
1223:   }
1224: 
1225:   /**
1226:    * Incarnate in cases when request forwarding is not expected because the
1227:    * servant must be provided by the servant activator.
1228:    * 
1229:    * @param x the aom entry, where the object is replaced by value, returned by
1230:    * servant activator (if not null).
1231:    * 
1232:    * @param key the object key.
1233:    * 
1234:    * @param a_servant the servant that was passed as a parameter in the
1235:    * activation method.
1236:    * 
1237:    * @param use_forwarding if true, the gnuForwardRequest is throw under the
1238:    * forwarding exception (for remote client). Otherwise, the request is
1239:    * internally redirected (for local invocation).
1240:    */
1241:   private Servant incarnate(AOM.Obj x, byte[] object_key,
1242:                             Servant a_servant, boolean use_forwarding
1243:                            )
1244:   {
1245:     if (servant_activator != null)
1246:       {
1247:         Servant servant;
1248:         try
1249:           {
1250:             servant = servant_activator.incarnate(object_key, this);
1251:           }
1252:         catch (ForwardRequest ex)
1253:           {
1254:             if (use_forwarding)
1255:               throw new gnuForwardRequest(ex.forward_reference);
1256:             else
1257:               servant =
1258:                 ForwardedServant.create((ObjectImpl) ex.forward_reference);
1259:           }
1260:         if (servant != null && x != null)
1261:           x.setServant(servant);
1262:         if (servant == null && x != null)
1263:           servant = x.servant;
1264:         return servant;
1265:       }
1266:     else if (a_servant != null)
1267:       {
1268:         x.setServant(a_servant);
1269:         return a_servant;
1270:       }
1271:     else if (x.servant != null)
1272:       {
1273:         return x.servant;
1274:       }
1275:     else if (default_servant != null)
1276:       {
1277:         x.setServant(default_servant);
1278:         return x.servant;
1279:       }
1280:     else
1281:       throw new BAD_INV_ORDER("No servant given and the servant activator not set");
1282:   }
1283: 
1284:   /**
1285:    * Return the POA manager, associated with this POA.
1286:    *
1287:    * @return the associated POA manager (always available).
1288:    */
1289:   public POAManager the_POAManager()
1290:   {
1291:     return m_manager;
1292:   }
1293: 
1294:   /**
1295:    * Returns the adapter activator, associated with this POA.
1296:    * The newly created POA has no activator (null would be
1297:    * returned). The ORB root POA also initially has no activator.
1298:    *
1299:    * @return tha adapter activator or null if this POA has no
1300:    * associated adapter activator.
1301:    */
1302:   public AdapterActivator the_activator()
1303:   {
1304:     return m_activator;
1305:   }
1306: 
1307:   /**
1308:   * Set the adapter activator for this POA.
1309:   *
1310:   * @param the activator being set.
1311:   */
1312:   public void the_activator(AdapterActivator an_activator)
1313:   {
1314:     m_activator = an_activator;
1315:   }
1316: 
1317:   /**
1318:   * The children of this POA.
1319:   *
1320:   * @return the array of all childs for this POA.
1321:   */
1322:   public POA[] the_children()
1323:   {
1324:     POA[] poas = new POA[ children.size() ];
1325:     for (int i = 0; i < poas.length; i++)
1326:       {
1327:         poas [ i ] = (POA) children.get(i);
1328:       }
1329:     return poas;
1330:   }
1331: 
1332:   /**
1333:    * Return the name of this POA.
1334:    *
1335:    * @return the name of POA, relative to its parent.
1336:    */
1337:   public String the_name()
1338:   {
1339:     return name;
1340:   }
1341:   ;
1342: 
1343:   /**
1344:    * Return the parent of this POA.
1345:    *
1346:    * @return the parent POA or <code>null</code> if this is a root POA.
1347:    */
1348:   public POA the_parent()
1349:   {
1350:     return parent;
1351:   }
1352: 
1353:   /** {@inheritDoc} */
1354:   public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue a_value)
1355:   {
1356:     return new gnuIdAssignmentPolicy(a_value);
1357:   }
1358: 
1359:   /** {@inheritDoc} */
1360:   public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue a_value)
1361:   {
1362:     return new gnuIdUniquenessPolicy(a_value);
1363:   }
1364: 
1365:   /** {@inheritDoc} */
1366:   public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue a_value)
1367:   {
1368:     return new gnuImplicitActivationPolicy(a_value);
1369:   }
1370: 
1371:   /** {@inheritDoc} */
1372:   public LifespanPolicy create_lifespan_policy(LifespanPolicyValue a_value)
1373:   {
1374:     return new gnuLifespanPolicy(a_value);
1375:   }
1376: 
1377:   /** {@inheritDoc} */
1378:   public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue a_value)
1379:   {
1380:     return new gnuRequestProcessingPolicy(a_value);
1381:   }
1382: 
1383:   /** {@inheritDoc} */
1384:   public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue a_value)
1385:   {
1386:     return new gnuServantRetentionPolicy(a_value);
1387:   }
1388: 
1389:   /** {@inheritDoc} */
1390:   public ThreadPolicy create_thread_policy(ThreadPolicyValue a_value)
1391:   {
1392:     return new gnuThreadPolicy(a_value);
1393:   }
1394: 
1395:   /**
1396:    * <p>
1397:    * Destroy this POA and all descendant POAs. The destroyed POAs can be later
1398:    * re-created via {@link AdapterActivator} or by invoking {@link #create_POA}.
1399:    * This differs from {@link PoaManagerOperations#deactivate} that does not
1400:    * allow recreation of the deactivated POAs. After deactivation, recreation is
1401:    * only possible if the POAs were later destroyed.
1402:    * </p>
1403:    * <p>
1404:    * The remote invocation on the target, belonging to the POA that is currently
1405:    * destroyed return the remote exception ({@link TRANSIENT}, minor code 4).
1406:    * </p>
1407:    * 
1408:    * @param etherealize_objects if true, and POA has RETAIN policy, and the
1409:    * servant manager is available, the servant manager method
1410:    * {@link ServantActivatorOperations#etherealize} is called for each <i>active</i>
1411:    * object in the Active Object Map. This method should not try to access POA
1412:    * being destroyed. If <code>destroy</code> is called multiple times before
1413:    * the destruction completes, the etherialization should be invoked only once.
1414:    * 
1415:    * @param wait_for_completion if true, the method waits till the POA being
1416:    * destroyed completes all current requests and etherialization. If false, the
1417:    * method returns immediately.
1418:    */
1419:   public void destroy(boolean etherealize_objects, boolean wait_for_completion)
1420:   {
1421:     // Notify the IOR interceptors about that the POA is destroyed.
1422:     if (m_orb.iIor != null)
1423:       m_orb.iIor.adapter_state_changed(
1424:         new ObjectReferenceTemplate[] { getReferenceTemplate() },
1425:         NON_EXISTENT.value);
1426: 
1427:     if (wait_for_completion)
1428:       waitWhileRunning();
1429: 
1430:     // Nofify the IOR interceptors that the POA is destroyed.
1431:     if (m_manager instanceof gnuPOAManager)
1432:       {
1433:         ((gnuPOAManager) m_manager).poaDestroyed(this);
1434:       }
1435: 
1436:     // Put the brake instead of manager, preventing the subsequent
1437:     // requests.
1438:     gnuPOAManager g = new gnuPOAManager();
1439:     g.state = State.INACTIVE;
1440:     m_manager = g;
1441: 
1442:     // Disconnect from parent.
1443:     if (parent instanceof gnuPOA)
1444:       {
1445:         ((gnuPOA) parent).children.remove(this);
1446:       }
1447: 
1448:     unregisterFromManager();
1449: 
1450:     // Disconnect from the ORB all objects, registered with this POA.
1451:     ArrayList keys = new ArrayList();
1452:     keys.addAll(aom.keySet());
1453: 
1454:     byte[] key;
1455:     AOM.Obj obj;
1456:     for (int i = 0; i < keys.size(); i++)
1457:       {
1458:         key = (byte[]) keys.get(i);
1459:         obj = aom.get(key);
1460:         if (obj.poa == this)
1461:           m_orb.disconnect(obj.object);
1462:       }
1463: 
1464:     m_orb.identityDestroyed(this);
1465: 
1466:     if (etherealize_objects && servant_activator != null && !m_inDestruction)
1467:       {
1468:         etherealizeAll();
1469:       }
1470:     m_inDestruction = true;
1471: 
1472:     POA[] ch = the_children();
1473:     for (int i = 0; i < ch.length; i++)
1474:       {
1475:         ch[i].destroy(etherealize_objects, wait_for_completion);
1476:       }
1477:   }
1478: 
1479:   /**
1480:    * Destroy this POA if it has not been destroyed, destroys it.
1481:    */
1482:   protected void finalize()
1483:                    throws java.lang.Throwable
1484:   {
1485:     if (!m_inDestruction)
1486:       destroy(false, false);
1487:   }
1488: 
1489:   /**
1490:    * Remove self from the manager list.
1491:    */
1492:   private void unregisterFromManager()
1493:   {
1494:     if (m_manager instanceof gnuPOAManager)
1495:       {
1496:         gnuPOAManager p = (gnuPOAManager) m_manager;
1497:         p.removePOA(this);
1498:       }
1499:   }
1500: 
1501:   /**
1502:    * Get the policy of the given type, associated with this POA.
1503:    *
1504:    * @param a_policy_type a type of the requested policy.
1505:    * @return a policy of the given type, applyting to this POA.
1506:    *
1507:    * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not
1508:    * been specified for this POA.
1509:    */
1510:   public Policy _get_policy(int a_policy_type)
1511:                      throws org.omg.CORBA.BAD_PARAM
1512:   {
1513:     for (int i = 0; i < s_policies.length; i++)
1514:       {
1515:         if (s_policies [ i ].policy_type() == a_policy_type)
1516:           return s_policies [ i ].copy();
1517:       }
1518:     throw new BAD_PARAM("No policy type " + a_policy_type);
1519:   }
1520: 
1521:   /**
1522:    * Get the copy of the policy array.
1523:    */
1524:   public Policy[] getPolicyArray()
1525:   {
1526:     Policy[] r = new Policy[ s_policies.length ];
1527:     for (int i = 0; i < s_policies.length; i++)
1528:       {
1529:         r [ i ] = s_policies [ i ].copy();
1530:       }
1531:     return r;
1532:   }
1533: 
1534:   /**
1535:    * The POAs cannot be created by this method.
1536:    *
1537:    * @specnote this is also not possible in Suns jdk at least till 1.4.
1538:    *
1539:    * @throws NO_IMPLEMENT always.
1540:    */
1541:   public org.omg.CORBA.Object _set_policy_override(Policy[] policies,
1542:                                                    SetOverrideType how
1543:                                                   )
1544:   {
1545:     throw new NO_IMPLEMENT("Use createPOA instead.");
1546:   }
1547: 
1548:   /**
1549:    * Get the ORB, where this POA is connected.
1550:    */
1551:   public ORB orb()
1552:   {
1553:     return m_orb;
1554:   }
1555: 
1556:   /**
1557:    * Connect the given delegate under the given key, also calling incarnate.
1558:    */
1559:   private void create_and_connect(byte[] object_key, String repository_id,
1560:     ServantDelegateImpl delegate)
1561:   {
1562:     aom.add(delegate);
1563:     connect_to_orb(object_key, getReferenceFactory().make_object(repository_id,
1564:       object_key));
1565:     if (servant_activator != null)
1566:       incarnate(null, object_key, delegate.servant, false);
1567:   }
1568: 
1569:   /**
1570:    * Check if the POA is not in a discarding mode. The activation
1571:    * operations are forbidded in discarding mode.
1572:    *
1573:    * @throws TRANSIENT if the POA is in discarding mode.
1574:    */
1575:   private void checkDiscarding()
1576:                         throws TRANSIENT
1577:   {
1578:     if (m_manager.get_state() == State.DISCARDING)
1579:       throw new TRANSIENT("Discarding mode", 1, CompletionStatus.COMPLETED_MAYBE);
1580:   }
1581: 
1582:   /**
1583:    * Connect the given delegate object to orb.
1584:    */
1585:   protected void connect_to_orb(byte[] an_Object_Id, org.omg.CORBA.Object object)
1586:   {
1587:     if (applies(ThreadPolicyValue.SINGLE_THREAD_MODEL))
1588:       m_orb.connect_1_thread(object, toIORKey(an_Object_Id), this);
1589:     else
1590:       m_orb.connect(object, toIORKey(an_Object_Id));
1591:   }
1592: 
1593:   /**
1594:    * Returns the representation of this POA tree.
1595:    */
1596:   public String toString()
1597:   {
1598:     StringBuffer b = new StringBuffer(name);
1599: 
1600:     if (children.size() != 0)
1601:       {
1602:         b.append(" (");
1603: 
1604:         for (int i = 0; i < children.size(); i++)
1605:           {
1606:             b.append(children.get(i));
1607:             if (i < children.size() - 2)
1608:               b.append(", ");
1609:           }
1610:         b.append(")");
1611:       }
1612:     return b.toString();
1613:   }
1614: 
1615:   /**
1616:    * Check if the policy set is valid.
1617:    */
1618:   protected boolean validatePolicies(Policy[] a)
1619:                               throws InvalidPolicy
1620:   {
1621:     if (applies(ServantRetentionPolicyValue.NON_RETAIN))
1622:       {
1623:         if (!applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) &&
1624:             !applies(RequestProcessingPolicyValue.USE_SERVANT_MANAGER)
1625:            )
1626:           {
1627:             short p = 0;
1628:             for (short i = 0; i < a.length; i++)
1629:               {
1630:                 if (a [ i ].policy_type() == SERVANT_RETENTION_POLICY_ID.value)
1631:                   p = i;
1632:               }
1633:             throw new InvalidPolicy("NON_RETAIN requires either " +
1634:                                     "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER",
1635:                                     p
1636:                                    );
1637:           }
1638:       }
1639:     return true;
1640:   }
1641: 
1642:   /**
1643:    * Recursively searches for the given object in the POA tree.
1644:    */
1645:   public AOM.Obj findObject(org.omg.CORBA.Object object)
1646:   {
1647:     AOM.Obj h = aom.findObject(object);
1648:     if (h != null)
1649:       return h;
1650:     else
1651:       {
1652:         for (int i = 0; i < children.size(); i++)
1653:           {
1654:             h = ((gnuPOA) children.get(i)).findObject(object);
1655:             if (h != null)
1656:               return h;
1657:           }
1658:       }
1659:     return h;
1660:   }
1661:   
1662:   /**
1663:    * Recursively searches for the given key in the POA tree.
1664:    * @param ior_key the key, ecapsulating both object
1665:    * and poa ids.
1666:    * @return
1667:    */
1668:   public AOM.Obj findKey(byte[] object_id, byte[] poa_id)
1669:   {
1670:     AOM.Obj h = null;
1671:     if (Arrays.equals(poa_id, id()))
1672:       h = aom.get(object_id);
1673:     if (h != null)
1674:       return h;
1675:     else
1676:       {
1677:         for (int i = 0; i < children.size(); i++)
1678:           {
1679:             h = ((gnuPOA) children.get(i)).findKey(object_id, poa_id);
1680:             if (h != null)
1681:               return h;
1682:           }
1683:       }
1684:     return h;
1685:   }
1686: 
1687:   /**
1688:    * Parses the given key, extracts poa and object id and searches
1689:    * for such reference.
1690:    */
1691:   public AOM.Obj findIorKey(byte[] ior_key)
1692:   {
1693:     BufferredCdrInput in = new BufferredCdrInput(ior_key);
1694:     int signature = in.read_long();
1695:     if (signature != SIGNATURE)
1696:       return null;
1697: 
1698:     byte[] id = in.read_sequence();
1699:     byte[] poa = in.read_sequence();
1700:     return findKey(id, poa);
1701:   }
1702: 
1703:   /**
1704:    * Converts the object Id into the IOR key. IOR key must be
1705:    * unique in the scope of the ORB, and Ids only in the scope of POA.
1706:    * Hence the IOR key includes the POA identifiers.
1707:    */
1708:   public byte[] toIORKey(byte[] object_id)
1709:   {
1710:     BufferedCdrOutput buffer = new BufferedCdrOutput();
1711:     buffer.write_long(SIGNATURE);
1712:     buffer.write_sequence(object_id);
1713:     buffer.write_sequence(id());
1714:     return buffer.buffer.toByteArray();
1715:   }
1716: 
1717:   /**
1718:    * Extracts the object id from the ior key.
1719:    *
1720:    * @param ior_key
1721:    *
1722:    * @return the encapsulated object ior key or null if
1723:    * this ior key either refers a different POA or encoding signature
1724:    * mismatch.
1725:    */
1726:   public byte[] idFormIor(byte[] ior_key)
1727:   {
1728:     BufferredCdrInput in = new BufferredCdrInput(ior_key);
1729:     int signature = in.read_long();
1730:     if (signature != SIGNATURE)
1731:       return null;
1732: 
1733:     byte[] object_id = in.read_sequence();
1734:     byte[] poa_id = in.read_sequence();
1735:     if (Arrays.equals(poa_id, id()))
1736:       return object_id;
1737:     else
1738:       return null;
1739:   }
1740:   
1741:   /**
1742:    * Recursively searches for the given servant in the POA tree.
1743:    */
1744:   public AOM.Obj findServant(Servant servant)
1745:   {
1746:     AOM.Obj h = aom.findServant(servant);
1747:     if (h != null)
1748:       return h;
1749:     else
1750:       {
1751:         for (int i = 0; i < children.size(); i++)
1752:           {
1753:             h = ((gnuPOA) children.get(i)).findServant(servant);
1754:             if (h != null)
1755:               return h;
1756:           }
1757:       }
1758:     return h;
1759:   }
1760:   
1761:   /**
1762:    * Get the object reference template of this POA.
1763:    * Instantiate a singleton instance, if required.
1764:    */
1765:   public ObjectReferenceTemplate getReferenceTemplate()
1766:   {
1767:     if (refTemplate == null)
1768:       refTemplate = new RefTemplate();
1769:     
1770:     return refTemplate;
1771:   }
1772:   
1773:   public ObjectReferenceFactory getReferenceFactory()
1774:   {
1775:     return m_object_factory;
1776:   }
1777:   
1778:   public void setReferenceFactory(ObjectReferenceFactory factory)
1779:   {
1780:     m_object_factory = factory;
1781:   }
1782: 
1783:   /**
1784:    * Create the object (needed by the factory interface).
1785:    */
1786:   public Object make_object(String a_repository_id, byte[] an_object_id)
1787:   {
1788:     AOM.Obj existing = aom.get(an_object_id);
1789:     // The object may already exist. In this case, it is just returned.
1790:     if (existing != null && existing.object != null)
1791:       return existing.object;
1792:     else
1793:       {
1794:         return new gnuServantObject(new String[] { a_repository_id },
1795:           an_object_id, this, m_orb);
1796:       }
1797:   }
1798: 
1799:   /**
1800:    * Required by object reference factory ops.
1801:    */
1802:   public String[] _truncatable_ids()
1803:   {
1804:     return ref_template_ids;
1805:   }