1 /* gnuAbstractPOA.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package gnu
.CORBA
.Poa
;
41 import gnu
.java
.lang
.CPStringBuilder
;
43 import java
.util
.ArrayList
;
44 import java
.util
.Arrays
;
45 import java
.util
.HashSet
;
47 import org
.omg
.CORBA
.BAD_INV_ORDER
;
48 import org
.omg
.CORBA
.BAD_PARAM
;
49 import org
.omg
.CORBA
.CompletionStatus
;
50 import org
.omg
.CORBA
.LocalObject
;
51 import org
.omg
.CORBA
.NO_IMPLEMENT
;
52 import org
.omg
.CORBA
.OBJ_ADAPTER
;
53 import org
.omg
.CORBA
.ORB
;
54 import org
.omg
.CORBA
.Object
;
55 import org
.omg
.CORBA
.Policy
;
56 import org
.omg
.CORBA
.SetOverrideType
;
57 import org
.omg
.CORBA
.TRANSIENT
;
58 import org
.omg
.CORBA
.portable
.ObjectImpl
;
59 import org
.omg
.PortableInterceptor
.NON_EXISTENT
;
60 import org
.omg
.PortableInterceptor
.ObjectReferenceFactory
;
61 import org
.omg
.PortableInterceptor
.ObjectReferenceTemplate
;
62 import org
.omg
.PortableInterceptor
.ObjectReferenceTemplateHelper
;
63 import org
.omg
.PortableServer
.AdapterActivator
;
64 import org
.omg
.PortableServer
.ForwardRequest
;
65 import org
.omg
.PortableServer
.IdAssignmentPolicy
;
66 import org
.omg
.PortableServer
.IdAssignmentPolicyValue
;
67 import org
.omg
.PortableServer
.IdUniquenessPolicy
;
68 import org
.omg
.PortableServer
.IdUniquenessPolicyValue
;
69 import org
.omg
.PortableServer
.ImplicitActivationPolicy
;
70 import org
.omg
.PortableServer
.ImplicitActivationPolicyValue
;
71 import org
.omg
.PortableServer
.LifespanPolicy
;
72 import org
.omg
.PortableServer
.LifespanPolicyValue
;
73 import org
.omg
.PortableServer
.POA
;
74 import org
.omg
.PortableServer
.POAManager
;
75 import org
.omg
.PortableServer
.RequestProcessingPolicy
;
76 import org
.omg
.PortableServer
.RequestProcessingPolicyValue
;
77 import org
.omg
.PortableServer
.SERVANT_RETENTION_POLICY_ID
;
78 import org
.omg
.PortableServer
.Servant
;
79 import org
.omg
.PortableServer
.ServantActivator
;
80 import org
.omg
.PortableServer
.ServantLocator
;
81 import org
.omg
.PortableServer
.ServantManager
;
82 import org
.omg
.PortableServer
.ServantRetentionPolicy
;
83 import org
.omg
.PortableServer
.ServantRetentionPolicyValue
;
84 import org
.omg
.PortableServer
.ThreadPolicy
;
85 import org
.omg
.PortableServer
.ThreadPolicyValue
;
86 import org
.omg
.PortableServer
.POAManagerPackage
.State
;
87 import org
.omg
.PortableServer
.POAPackage
.AdapterAlreadyExists
;
88 import org
.omg
.PortableServer
.POAPackage
.AdapterNonExistent
;
89 import org
.omg
.PortableServer
.POAPackage
.InvalidPolicy
;
90 import org
.omg
.PortableServer
.POAPackage
.NoServant
;
91 import org
.omg
.PortableServer
.POAPackage
.ObjectAlreadyActive
;
92 import org
.omg
.PortableServer
.POAPackage
.ObjectNotActive
;
93 import org
.omg
.PortableServer
.POAPackage
.ServantAlreadyActive
;
94 import org
.omg
.PortableServer
.POAPackage
.ServantNotActive
;
95 import org
.omg
.PortableServer
.POAPackage
.WrongAdapter
;
96 import org
.omg
.PortableServer
.POAPackage
.WrongPolicy
;
98 import gnu
.CORBA
.OrbFunctional
;
99 import gnu
.CORBA
.CDR
.BufferredCdrInput
;
100 import gnu
.CORBA
.CDR
.BufferedCdrOutput
;
103 * Our POA implementation.
105 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
109 implements POA
, ObjectReferenceFactory
112 * The object reference template, associated with this POA.
116 class RefTemplate
implements ObjectReferenceTemplate
119 * Use serialVersionUID for interoperability.
121 private static final long serialVersionUID
= 1;
125 // The adapter name is computed once.
126 ArrayList names
= new ArrayList();
127 names
.add(the_name());
129 POA poa
= the_parent();
132 names
.add(poa
.the_name());
133 poa
= poa
.the_parent();
136 // Fill in the string array in reverse (more natural) order,
138 m_adapter_name
= new String
[names
.size()];
140 for (int i
= 0; i
< m_adapter_name
.length
; i
++)
141 m_adapter_name
[i
] = (String
) names
.get(m_adapter_name
.length
- i
- 1);
147 final String
[] m_adapter_name
;
150 * Get the name of this POA.
152 public String
[] adapter_name()
154 return (String
[]) m_adapter_name
.clone();
160 public String
orb_id()
168 public String
server_id()
170 return OrbFunctional
.server_id
;
176 public Object
make_object(String repositoryId
, byte[] objectId
)
178 return create_reference_with_id(objectId
, repositoryId
);
182 * Get the array of truncatible repository ids.
184 public String
[] _truncatable_ids()
186 return ref_template_ids
;
191 * Use serialVersionUID for interoperability.
193 private static final long serialVersionUID
= 1;
196 * The adapter reference template.
198 ObjectReferenceTemplate refTemplate
;
201 * The reference template repository ids. Defined outside the class as it
202 * cannot have static members.
204 final static String
[] ref_template_ids
=
205 new String
[] { ObjectReferenceTemplateHelper
.id() };
208 * The active object map, mapping between object keys, objects and servants.
210 public final AOM aom
= new AOM();
213 * The children of this POA.
215 final ArrayList children
= new ArrayList();
218 * The name of this POA.
223 * The parent of this POA (null for the root POA).
228 * The ior key signature, indicating, that the ior key is encoded using
229 * internal agreements of this implementation (0x'free').
231 static final int SIGNATURE
= 0x66726565;
234 * The adapter activator for this POA, null if no activator is set.
236 AdapterActivator m_activator
;
239 * The POA manager for this POA.
241 POAManager m_manager
;
244 * The servant manager (servant activator) for this POA.
246 ServantActivator servant_activator
;
249 * The servant manager (servant locator) for this POA.
251 ServantLocator servant_locator
;
254 * The default servant, if on is in use.
256 Servant default_servant
;
259 * The cached poa id value, computed once.
261 private byte[] m_poa_id
;
264 * The all policy values that apply to this POA.
265 * The used policy values are singletons, unique between policies.
267 private final HashSet m_policies
;
270 * An array of the set policies.
275 * The ORB, where the POA is connected.
280 * When true, the POA is being destroyed or is destroyed.
282 boolean m_inDestruction
;
285 * True if the active object map is used by this POA.
286 * The value is moved into separate boolean value due
287 * necessity of the frequent checks.
289 public final boolean retain_servant
;
292 * The object reference factory, used to create the new object
295 ObjectReferenceFactory m_object_factory
= this;
298 * Create a new abstract POA.
300 * @param a_parent the parent of this POA.
301 * @param a_name a name for this POA.
302 * @param a_manager a manager for this POA. If null, a new
303 * {@link gnuPOAManager} will be instantiated.
304 * @param a_policies an array of policies that apply to this POA.
305 * @param an_orb an ORB for this POA.
307 public gnuPOA(gnuPOA a_parent
, String a_name
, POAManager a_manager
,
308 Policy
[] a_policies
, ORB_1_4 an_orb
312 // Add default policies.
313 Policy
[] all_policies
= StandardPolicies
.withDefault(a_policies
);
319 if (a_manager
!= null)
320 m_manager
= a_manager
;
322 m_manager
= new gnuPOAManager();
324 if (m_manager
instanceof gnuPOAManager
)
326 gnuPOAManager g
= (gnuPOAManager
) m_manager
;
330 m_policies
= new HashSet(all_policies
.length
);
332 s_policies
= new Policy
[ all_policies
.length
];
333 for (int i
= 0; i
< s_policies
.length
; i
++)
335 s_policies
[ i
] = all_policies
[ i
].copy();
336 m_policies
.add(((AccessiblePolicy
) s_policies
[ i
]).getValue());
339 retain_servant
= applies(ServantRetentionPolicyValue
.RETAIN
);
341 validatePolicies(a_policies
);
343 refTemplate
= new RefTemplate();
347 * Wait while at least one of the threads in this POA is actively
348 * processing one of requests.
350 public void waitWhileRunning()
355 // Maximal duration between checks.
362 runs
= m_orb
.currents
.has(this);
366 // Avoid taking CPU resources
367 // from the thread that is running.
375 catch (InterruptedException ex
)
384 * Etherealize all objects, associated with this POA. Invoked from the
385 * {@link gnuPOAManager} only if it is known that the servant_activator
386 * holds non-null value.
388 protected void etherealizeAll()
390 if (servant_activator
== null)
393 ArrayList keys
= new ArrayList();
394 keys
.addAll(aom
.keySet());
399 for (int i
= 0; i
< keys
.size(); i
++)
401 key
= (byte[]) keys
.get(i
);
408 if (!obj
.isDeactiveted())
410 // Check if the servant still stays under the other key.
411 last
= aom
.findServant(obj
.servant
) == null;
412 servant_activator
.etherealize(obj
.key
, this, obj
.servant
, true,
421 * Create an instance of the POA with the given features.
422 * This method is not responsible for duplicate checking
423 * or adding the returned instance to any possible table.
425 * @param child_name the name of the poa being created.
426 * @param a_manager the poa manager (never null).
427 * @param policies the array of policies.
428 * @param an_orb the ORB for this POA.
430 * @return the created POA.
432 * @throws InvalidPolicy for conflicting or otherwise invalid policies.|
434 protected POA
createPoaInstance(String child_name
, POAManager a_manager
,
435 Policy
[] policies
, ORB_1_4 an_orb
439 POAManager some_manager
=
440 a_manager
== null ?
new gnuPOAManager() : a_manager
;
442 if (some_manager
instanceof gnuPOAManager
)
444 ((gnuPOAManager
) some_manager
).addPoa(this);
447 return new gnuPOA(this, child_name
, some_manager
, policies
, an_orb
);
451 * Check if the given policy value applies to this POA.
453 * @param policy_value a policy value to check. The policy values are
454 * singletons and unique between the different policies, so the policy
455 * type is not passed.
457 * @return true if the policy value applies, false otherwise.
459 public final boolean applies(java
.lang
.Object policy_value
)
461 return m_policies
.contains(policy_value
);
465 * Check for the presence of the required policy.
467 * @param policy_value a policy value to check.
469 * @throws WrongPolicy if the required policy value is not applicable.
471 public final void required(java
.lang
.Object policy_value
)
474 if (!applies(policy_value
))
475 throw new WrongPolicy(policy_value
+ " policy required.");
479 * Check for the absence of the given policy.
481 * @param policy_value a policy value to check.
483 * @throws WrongPolicy if the passed policy value is applicable.
485 public final void excluding(java
.lang
.Object policy_value
)
488 if (applies(policy_value
))
489 throw new WrongPolicy(policy_value
+ " policy applies.");
493 * Find and optionally activate the child POA with the given name.
495 * @param poa_name the name of the POA to find.
496 * @param activate_it if the child with the specified name is not found
497 * or inactive and this parameter is true, the target POA activator is
498 * invoked to activate that child. If this succeeds, that child POA
501 * @throws AdapterNonExistent if no active child with the given name
502 * is found and one of the following is true:
503 * a) the target POA has no associated
504 * {@link AdapterActivator}. b) that activator fails to activate the
505 * child POA. c) <code>activate_id</code> = false.
507 public POA
find_POA(String poa_name
, boolean activate_it
)
508 throws AdapterNonExistent
511 for (int i
= 0; i
< children
.size(); i
++)
513 child
= (POA
) children
.get(i
);
514 if (child
.the_name().equals(poa_name
))
518 if (activate_it
&& m_activator
!= null)
520 boolean activated
= m_activator
.unknown_adapter(this, poa_name
);
522 throw new AdapterNonExistent(poa_name
+ " activation failed.");
524 // Tha activator should add the child to the childrent table.
525 for (int i
= 0; i
< children
.size(); i
++)
527 child
= (POA
) children
.get(i
);
528 if (child
.the_name().equals(poa_name
))
531 throw new AdapterNonExistent(poa_name
+ " not created. ");
534 throw new AdapterNonExistent(poa_name
);
538 * Generate the Object Id for the given servant and add the servant to the
539 * Active Object Map using this Id a a key. If the servant activator is set,
540 * its incarnate method will be called.
542 * @param a_servant a servant that would serve the object with the returned
543 * Object Id. If null is passed, under apporoprate policies the servant
544 * activator is invoked.
546 * @return the generated objert Id for the given servant.
548 * @throws ServantAlreadyActive if this servant is already in the Active
549 * Object Map and the UNIQUE_ID policy applies.
551 * @throws WrongPolicy if the required policies SYSTEM_ID and RETAIN do not
554 public byte[] activate_object(Servant a_servant
)
555 throws ServantAlreadyActive
, WrongPolicy
558 required(ServantRetentionPolicyValue
.RETAIN
);
559 required(IdAssignmentPolicyValue
.SYSTEM_ID
);
561 AOM
.Obj exists
= aom
.findServant(a_servant
);
565 if (exists
.isDeactiveted())
567 // If exists but deactivated, activate and return
569 exists
.setDeactivated(false);
570 incarnate(exists
, exists
.key
, a_servant
, false);
573 else if (applies(IdUniquenessPolicyValue
.UNIQUE_ID
))
574 throw new ServantAlreadyActive();
576 // It multiple ids are allowed, exit block allowing repetetive
580 byte[] object_key
= AOM
.getFreeId();
581 ServantDelegateImpl delegate
= new ServantDelegateImpl(a_servant
, this,
583 create_and_connect(object_key
,
584 a_servant
._all_interfaces(this, object_key
)[0], delegate
);
589 * Add the given servant to the Active Object Map as a servant for the object
590 * with the provided Object Id. If the servant activator is set, its incarnate
591 * method will be called.
593 * @param an_Object_Id an object id for the given object.
594 * @param a_servant a servant that will serve the object with the given Object
595 * Id. If null is passed, under apporoprate policies the servant activator is
598 * @throws ObjectAlreadyActive if the given object id is already in the Active
600 * @throws ServantAlreadyActive if the UNIQUE_ID policy applies and this
601 * servant is already in use.
602 * @throws WrongPolicy if the required RETAIN policy does not apply to this
604 * @throws BAD_PARAM if the passed object id is invalid due any reason.
606 public void activate_object_with_id(byte[] an_Object_Id
, Servant a_servant
)
607 throws ServantAlreadyActive
, ObjectAlreadyActive
,
610 activate_object_with_id(an_Object_Id
, a_servant
, false);
614 * Same as activate_object_with_id, but permits gnuForwardRequest forwarding
615 * exception. This is used when the activation is called from the remote
616 * invocation context and we have possibility to return the forwarding
619 public void activate_object_with_id(byte[] an_Object_Id
, Servant a_servant
,
620 boolean use_forwarding
)
621 throws ServantAlreadyActive
, ObjectAlreadyActive
, WrongPolicy
624 required(ServantRetentionPolicyValue
.RETAIN
);
626 // If the UNIQUE_ID applies, the servant being passed must not be
628 if (applies(IdUniquenessPolicyValue
.UNIQUE_ID
))
630 AOM
.Obj sx
= aom
.findServant(a_servant
, false);
632 throw new ServantAlreadyActive();
635 AOM
.Obj exists
= aom
.get(an_Object_Id
);
638 if (exists
.servant
== null)
640 locateServant(an_Object_Id
, a_servant
, exists
, use_forwarding
);
641 exists
.setDeactivated(false);
643 else if (exists
.isDeactiveted())
645 exists
.setDeactivated(false);
646 incarnate(exists
, an_Object_Id
, a_servant
, use_forwarding
);
649 throw new ObjectAlreadyActive();
653 ServantDelegateImpl delegate
= new ServantDelegateImpl(a_servant
, this,
655 create_and_connect(an_Object_Id
, a_servant
._all_interfaces(this,
656 an_Object_Id
)[0], delegate
);
661 * Locate the servant for this object Id and connect it to ORB.
663 * @param an_Object_Id the object id.
664 * @param a_servant the servant (may be null).
665 * @param exists an existing active object map entry.
666 * @param use_forwarding allow to throw the gnuForwardRequest if the activator
667 * throws ForwardRequest.
669 * @throws OBJ_ADAPTER minor 4 if the servant cannot be located (the required
670 * servant manager may be missing).
672 private void locateServant(byte[] an_Object_Id
, Servant a_servant
,
673 AOM
.Obj exists
, boolean use_forwarding
677 // An object was created with create_reference.
678 gnuServantObject object
= (gnuServantObject
) exists
.object
;
679 if (servant_activator
!= null)
681 exists
.setServant(incarnate(exists
, an_Object_Id
, a_servant
,
686 else if (default_servant
!= null)
688 exists
.setServant(default_servant
);
690 if (exists
.servant
== null)
692 exists
.setServant(a_servant
);
694 if (exists
.servant
== null)
696 throw new OBJ_ADAPTER("no servant", 4, CompletionStatus
.COMPLETED_NO
);
699 ServantDelegateImpl delegate
=
700 new ServantDelegateImpl(exists
.servant
, this, an_Object_Id
);
701 exists
.servant
._set_delegate(delegate
);
702 object
.setServant(exists
.servant
);
703 connect_to_orb(an_Object_Id
, delegate
.object
);
707 * Deactivate object with the given id.
709 * The deactivated object will continue to process requests that arrived
710 * before decativation. If this POA has the associated
711 * servant manager, a {@link ServantActivatorOperations#etherealize} is
712 * immediately invoked on the passed id.
714 * @throws WrongPolicy if the required RETAIN policy does not apply to
717 public void deactivate_object(byte[] the_Object_Id
)
718 throws ObjectNotActive
, WrongPolicy
720 required(ServantRetentionPolicyValue
.RETAIN
);
722 AOM
.Obj exists
= aom
.get(the_Object_Id
);
724 if (exists
== null || exists
.isDeactiveted())
725 throw new ObjectNotActive();
727 exists
.setDeactivated(true);
729 // Check if this servant is serving something else.
730 aom
.remove(the_Object_Id
);
732 AOM
.Obj other
= aom
.findServant(exists
.servant
, false);
734 boolean remaining
= other
!= null;
738 if (servant_activator
!= null)
739 servant_activator
.etherealize(the_Object_Id
, this, exists
.servant
, false,
745 * Create the object reference, encapsulating the given repository Id and
746 * the Object Id, generated by this POA. The returned object will not be
747 * activated by default and may be activated on the first invocation by
748 * the servant manager (if it is set and if policies are applicable).
750 * @param a_repository_id the repository id for the given object, can
751 * be null if to be requested from the servant later.
753 * @throws WrongPolicy if the required SYSTEM_ID policy does not apply to
756 public org
.omg
.CORBA
.Object
create_reference(String a_repository_id
)
759 required(IdAssignmentPolicyValue
.SYSTEM_ID
);
760 return create_reference_with_id(AOM
.getFreeId(), a_repository_id
);
765 * Create the object reference, encapsulating the given repository Id and
766 * the given Object Id. The returned object will <i>not</i> be
767 * activated by default and may be activated on the first invocation by
768 * the servant manager (if the IMPLICIT_ACTIVATION policy applies).
770 * @param an_object_id the object id for the object being created. If this
771 * POA uses the SYSTEM_ID policy, the portable application should only
772 * pass the ids, generated by this POA.
774 * @param a_repository_id the repository id for the object being created,
775 * can be null if this information should be later requested from the
778 public org
.omg
.CORBA
.Object
create_reference_with_id(byte[] an_object_id
,
779 String a_repository_id
783 if (a_repository_id
== null)
786 ids
= new String
[] { a_repository_id
};
788 // Check maybe such object is already activated.
789 AOM
.Obj e
= aom
.get(an_object_id
);
799 e
.setDeactivated(false);
802 gnuServantObject object
=
803 new gnuServantObject(ids
, an_object_id
, this, m_orb
);
804 object
._set_delegate(new LocalDelegate(object
, this, an_object_id
));
805 aom
.add(object
.Id
, object
, servant
, this);
806 connect_to_orb(an_object_id
, object
);
812 * Creates a new POA as a child of the target POA.
814 * @param child_name the name of the child POA being created.
815 * @param manager the manager that will control the new POA. If this parameter
816 * is null, a new POA manager is created and associated with the new POA.
818 * @param policies the policies, applicable for the parent POA. Policies
819 * are <i>not</i> inherited from the parent POA.
821 * @return an newly created POA. The POA will be intially in the holding
822 * state and must be activated to start processing requests.
824 * @throws AdapterAlreadyExists if the child with the given child_name
825 * already exists for the current POA.
826 * @throws InvalidPolicy if the policies conflict with each other or are
827 * otherwise inappropriate.
829 * @see #the_children()
831 public POA
create_POA(String child_name
, POAManager manager
, Policy
[] policies
)
832 throws AdapterAlreadyExists
, InvalidPolicy
835 for (int i
= 0; i
< children
.size(); i
++)
837 child
= (POA
) children
.get(i
);
838 if (child
.the_name().equals(child_name
))
839 throw new AdapterAlreadyExists(name
+ "/" + child_name
);
842 POA poa
= createPoaInstance(child_name
, manager
, policies
, m_orb
);
848 * Returns a default servant for this POA.
850 * @return a servant that will be used for requests for
851 * which no servant is found in the Active Object Map.
853 * @throws NoServant if there is no default servant associated with this POA.
854 * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active.
856 public Servant
get_servant()
857 throws NoServant
, WrongPolicy
859 required(RequestProcessingPolicyValue
.USE_DEFAULT_SERVANT
);
860 if (default_servant
== null)
861 throw new NoServant();
862 return default_servant
;
866 * Sets the default servant for this POA.
868 * @param a_servant a servant that will be used for requests for
869 * which no servant is found in the Active Object Map.
871 * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active.
873 public void set_servant(Servant a_servant
)
876 required(RequestProcessingPolicyValue
.USE_DEFAULT_SERVANT
);
877 default_servant
= a_servant
;
881 * Set a servant manager for this POA.
883 * @param a servant manager being set. If the RETAIN policy applies, the
884 * manager must implement a {@link ServantActivator}. If the NON_RETAIN
885 * policy applies, the manager must implement a {@link ServantLocator}.
887 * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not
890 * @throws OBJ_ADAPTER minor code 4 if the passed manager does not
891 * implement the required interface ({@link ServantActivator},
892 * {@link ServantLocator}). The POA, that has the RETAIN policy uses
893 * servant managers that are ServantActivators. When the POA has the
894 * NON_RETAIN policy it uses servant managers that are ServantLoacators.
896 * @throws BAD_INV_ORDER minor code 6 if the method is called more than once
897 * on the same POA. The manager can be set only once.
899 public void set_servant_manager(ServantManager a_manager
)
902 required(RequestProcessingPolicyValue
.USE_SERVANT_MANAGER
);
903 if (servant_activator
!= null || servant_locator
!= null)
904 throw new BAD_INV_ORDER("Setting manager twice for " + name
, 6,
905 CompletionStatus
.COMPLETED_NO
908 if (applies(ServantRetentionPolicyValue
.RETAIN
))
910 if (a_manager
instanceof ServantActivator
)
911 servant_activator
= (ServantActivator
) a_manager
;
913 throw new OBJ_ADAPTER("RETAIN requires ServantActivator", 4,
914 CompletionStatus
.COMPLETED_NO
917 else if (applies(ServantRetentionPolicyValue
.NON_RETAIN
))
919 if (a_manager
instanceof ServantLocator
)
920 servant_locator
= (ServantLocator
) a_manager
;
922 throw new OBJ_ADAPTER("NON_RETAIN requires ServantLocator", 4,
923 CompletionStatus
.COMPLETED_NO
927 throw new WrongPolicy("No servant retention policy is specified.");
931 * Get the servant manager, associated with this POA.
933 * @return the associated servant manager or null if it has
934 * been previously set.
936 * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not
939 public ServantManager
get_servant_manager()
942 required(RequestProcessingPolicyValue
.USE_SERVANT_MANAGER
);
944 if (servant_activator
!= null)
945 return servant_activator
;
947 return servant_locator
;
951 * Get the unique Id of the POA in the process in which it is created.
952 * This Id is needed by portable interceptors. The id is unique
953 * for the life span of the POA in the process. For persistent
954 * POAs, if a POA is created in the same path with the same name as
955 * another POA, these POAs are identical have the same id. All transient
956 * POAs are assumed unique.
960 if (m_poa_id
!= null)
964 BufferedCdrOutput buffer
= new BufferedCdrOutput();
968 buffer
.write_string(p
.the_name());
971 m_poa_id
= buffer
.buffer
.toByteArray();
977 * Returns the reference to the active object with the given Id.
979 * @param the_Object_Id the object id.
981 * @throws ObjectNotActive if there is no active object with such Id
982 * in the scope of this POA.
983 * @throws WrongPolicy if the required RETAIN policy does not apply to
986 public org
.omg
.CORBA
.Object
id_to_reference(byte[] the_Object_Id
)
987 throws ObjectNotActive
, WrongPolicy
989 required(ServantRetentionPolicyValue
.RETAIN
);
991 AOM
.Obj ref
= aom
.get(the_Object_Id
);
993 throw new ObjectNotActive();
999 * Returns the servant that serves the active object with the given Id.
1001 * @param the_Object_Id the object id.
1003 * @throws ObjectNotActive if there is no active object with such Id or
1004 * it is not currently active.
1005 * @throws WrongPolicy. This method requires either RETAIN or
1006 * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them
1007 * apply to this POA.
1009 public Servant
id_to_servant(byte[] the_Object_Id
)
1010 throws ObjectNotActive
, WrongPolicy
1012 if (applies(ServantRetentionPolicyValue
.RETAIN
))
1014 AOM
.Obj ref
= aom
.get(the_Object_Id
);
1015 if (ref
== null || ref
.isDeactiveted())
1017 if (default_servant
!= null)
1018 return default_servant
;
1020 throw new ObjectNotActive();
1022 else if (ref
.servant
!= null)
1024 else if (default_servant
!= null)
1025 return default_servant
;
1027 throw new ObjectNotActive();
1029 else if (default_servant
!= null)
1031 return default_servant
;
1034 throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required.");
1038 * Returns the Object Id, encapsulated in the given object reference.
1040 * @param the_Object the object that has been previously created with this
1041 * POA. It need not be active.
1043 * @throws WrongAdapter if the passed object is not known for this POA.
1044 * @throws WrongPolicy never (declared for the future extensions only).
1046 public byte[] reference_to_id(org
.omg
.CORBA
.Object the_Object
)
1047 throws WrongAdapter
, WrongPolicy
1049 AOM
.Obj ref
= aom
.findObject(the_Object
);
1051 throw new WrongAdapter();
1056 * Returns the servant that is serving this object.
1058 * @return if the RETAIN policy applies and the object is in the Active Object
1059 * Map, the method returns the servant, associated with this object.
1060 * Otherwise, if the USE_DEFAULT_SERVANT policy applies, the method returns
1061 * the default servant (if one was set).
1063 * @throws ObjectNotActive if none of the conditions above are satisfied.
1064 * @throws WrongAdapter if the object reference was not created with this POA.
1065 * @throws WrongPolicy. This method requires either RETAIN or
1066 * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them
1067 * apply to this POA.
1069 public Servant
reference_to_servant(org
.omg
.CORBA
.Object the_Object
)
1070 throws ObjectNotActive
, WrongPolicy
, WrongAdapter
1072 if (applies(ServantRetentionPolicyValue
.RETAIN
))
1074 AOM
.Obj ref
= aom
.findObject(the_Object
);
1078 if (the_Object
== null)
1079 object
= "null passed";
1080 else if (the_Object
instanceof gnuServantObject
)
1082 gnuServantObject gs
= (gnuServantObject
) the_Object
;
1083 object
= "Wrong owner POA " + gs
.poa
.the_name();
1086 object
= "Unknown " + the_Object
.getClass().getName();
1088 throw new WrongAdapter(object
+ " for '" + the_name() + "'");
1090 else if (ref
.isDeactiveted() || ref
.servant
== null)
1092 if (default_servant
!= null)
1093 return default_servant
;
1095 throw new ObjectNotActive();
1100 else if (default_servant
!= null)
1102 return default_servant
;
1105 throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required.");
1109 * Returns the id of the object, served by the given servant (assuming that
1110 * the servant serves only one object). The id is found in one of the
1113 * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and the
1114 * specified servant is active, the method return the Object Id associated
1115 * with that servant. </li>
1116 * <li> If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and
1117 * either the POA has the MULTIPLE_ID policy or the specified servant is
1118 * inactive, the method activates the servant using a POA-generated Object Id
1119 * and the Interface Id associated with the servant, and returns that Object
1121 * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified
1122 * is the default servant, and the method is being invoked in the context of
1123 * executing a request on the default servant, the method returns the ObjectId
1124 * associated with the current invocation. </li>
1127 * @throws ServantNotActive in all cases, not listed in the list above.
1128 * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or a
1129 * combination of the RETAIN policy and either the UNIQUE_ID or
1130 * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions
1131 * are not satisfied.
1133 public byte[] servant_to_id(Servant the_Servant
)
1134 throws ServantNotActive
, WrongPolicy
1136 if (applies(RequestProcessingPolicyValue
.USE_DEFAULT_SERVANT
) ||
1137 applies(ServantRetentionPolicyValue
.RETAIN
) &&
1139 applies(IdUniquenessPolicyValue
.UNIQUE_ID
) ||
1140 applies(ImplicitActivationPolicyValue
.IMPLICIT_ACTIVATION
)
1145 if (!applies(IdUniquenessPolicyValue
.MULTIPLE_ID
))
1146 ref
= aom
.findServant(the_Servant
);
1148 applies(ImplicitActivationPolicyValue
.IMPLICIT_ACTIVATION
)
1154 return activate_object(the_Servant
);
1156 catch (ServantAlreadyActive ex
)
1158 // Either it shuld not be or the policy allows multiple ids.
1159 throw new InternalError();
1163 throw new ServantNotActive();
1168 throw new WrongPolicy("(RETAIN and UNIQUE ID) " +
1169 "or USE_DEFAULT_SERVANT required."
1175 * Converts the given servant to the object reference. The servant will serve
1176 * all methods, invoked on the returned object. The returned object reference
1177 * can be passed to the remote client, enabling remote invocations.
1180 * If the specified servant is active, it is returned. Otherwise, if the POA
1181 * has the IMPLICIT_ACTIVATION policy the method activates the servant. In
1182 * this case, if the servant activator is set, the
1183 * {@link ServantActivatorOperations#incarnate} method will be called.
1186 * @throws ServantNotActive if the servant is inactive and no
1187 * IMPLICIT_ACTIVATION policy applies.
1188 * @throws WrongPolicy This method needs the RETAIN policy and either the
1189 * UNIQUE_ID or IMPLICIT_ACTIVATION policies.
1191 * @return the object, exposing the given servant in the context of this POA.
1193 public org
.omg
.CORBA
.Object
servant_to_reference(Servant the_Servant
)
1194 throws ServantNotActive
, WrongPolicy
1196 required(ServantRetentionPolicyValue
.RETAIN
);
1198 AOM
.Obj exists
= null;
1200 if (!applies(IdUniquenessPolicyValue
.MULTIPLE_ID
))
1201 exists
= aom
.findServant(the_Servant
);
1205 if (exists
.isDeactiveted())
1207 if (applies(ImplicitActivationPolicyValue
.IMPLICIT_ACTIVATION
))
1210 exists
.setDeactivated(false);
1211 incarnate(exists
, exists
.key
, the_Servant
, false);
1214 throw new ServantNotActive();
1217 return exists
.object
;
1220 && applies(ImplicitActivationPolicyValue
.IMPLICIT_ACTIVATION
))
1224 byte[] object_key
= AOM
.getFreeId();
1226 ServantDelegateImpl delegate
= new ServantDelegateImpl(the_Servant
,
1228 create_and_connect(object_key
, the_Servant
._all_interfaces(this,
1229 object_key
)[0], delegate
);
1231 return delegate
.object
;
1234 throw new ServantNotActive();
1238 * Incarnate in cases when request forwarding is not expected because the
1239 * servant must be provided by the servant activator.
1241 * @param x the aom entry, where the object is replaced by value, returned by
1242 * servant activator (if not null).
1244 * @param object_key the object key.
1246 * @param a_servant the servant that was passed as a parameter in the
1247 * activation method.
1249 * @param use_forwarding if true, the gnuForwardRequest is throw under the
1250 * forwarding exception (for remote client). Otherwise, the request is
1251 * internally redirected (for local invocation).
1253 private Servant
incarnate(AOM
.Obj x
, byte[] object_key
,
1254 Servant a_servant
, boolean use_forwarding
1257 if (servant_activator
!= null)
1262 servant
= servant_activator
.incarnate(object_key
, this);
1264 catch (ForwardRequest ex
)
1267 throw new gnuForwardRequest(ex
.forward_reference
);
1270 ForwardedServant
.create((ObjectImpl
) ex
.forward_reference
);
1272 if (servant
!= null && x
!= null)
1273 x
.setServant(servant
);
1274 if (servant
== null && x
!= null)
1275 servant
= x
.servant
;
1278 else if (a_servant
!= null)
1280 x
.setServant(a_servant
);
1283 else if (x
.servant
!= null)
1287 else if (default_servant
!= null)
1289 x
.setServant(default_servant
);
1293 throw new BAD_INV_ORDER("No servant given and the servant activator not set");
1297 * Return the POA manager, associated with this POA.
1299 * @return the associated POA manager (always available).
1301 public POAManager
the_POAManager()
1307 * Returns the adapter activator, associated with this POA.
1308 * The newly created POA has no activator (null would be
1309 * returned). The ORB root POA also initially has no activator.
1311 * @return tha adapter activator or null if this POA has no
1312 * associated adapter activator.
1314 public AdapterActivator
the_activator()
1320 * Set the adapter activator for this POA.
1322 * @param an_activator the activator being set.
1324 public void the_activator(AdapterActivator an_activator
)
1326 m_activator
= an_activator
;
1330 * The children of this POA.
1332 * @return the array of all childs for this POA.
1334 public POA
[] the_children()
1336 POA
[] poas
= new POA
[ children
.size() ];
1337 for (int i
= 0; i
< poas
.length
; i
++)
1339 poas
[ i
] = (POA
) children
.get(i
);
1345 * Return the name of this POA.
1347 * @return the name of POA, relative to its parent.
1349 public String
the_name()
1355 * Return the parent of this POA.
1357 * @return the parent POA or <code>null</code> if this is a root POA.
1359 public POA
the_parent()
1364 /** {@inheritDoc} */
1365 public IdAssignmentPolicy
create_id_assignment_policy(IdAssignmentPolicyValue a_value
)
1367 return new gnuIdAssignmentPolicy(a_value
);
1370 /** {@inheritDoc} */
1371 public IdUniquenessPolicy
create_id_uniqueness_policy(IdUniquenessPolicyValue a_value
)
1373 return new gnuIdUniquenessPolicy(a_value
);
1376 /** {@inheritDoc} */
1377 public ImplicitActivationPolicy
create_implicit_activation_policy(ImplicitActivationPolicyValue a_value
)
1379 return new gnuImplicitActivationPolicy(a_value
);
1382 /** {@inheritDoc} */
1383 public LifespanPolicy
create_lifespan_policy(LifespanPolicyValue a_value
)
1385 return new gnuLifespanPolicy(a_value
);
1388 /** {@inheritDoc} */
1389 public RequestProcessingPolicy
create_request_processing_policy(RequestProcessingPolicyValue a_value
)
1391 return new gnuRequestProcessingPolicy(a_value
);
1394 /** {@inheritDoc} */
1395 public ServantRetentionPolicy
create_servant_retention_policy(ServantRetentionPolicyValue a_value
)
1397 return new gnuServantRetentionPolicy(a_value
);
1400 /** {@inheritDoc} */
1401 public ThreadPolicy
create_thread_policy(ThreadPolicyValue a_value
)
1403 return new gnuThreadPolicy(a_value
);
1408 * Destroy this POA and all descendant POAs. The destroyed POAs can be later
1409 * re-created via {@link AdapterActivator} or by invoking {@link #create_POA}.
1410 * This differs from {@link PoaManagerOperations#deactivate} that does not
1411 * allow recreation of the deactivated POAs. After deactivation, recreation is
1412 * only possible if the POAs were later destroyed.
1415 * The remote invocation on the target, belonging to the POA that is currently
1416 * destroyed return the remote exception ({@link TRANSIENT}, minor code 4).
1419 * @param etherealize_objects if true, and POA has RETAIN policy, and the
1420 * servant manager is available, the servant manager method
1421 * {@link ServantActivatorOperations#etherealize} is called for each <i>active</i>
1422 * object in the Active Object Map. This method should not try to access POA
1423 * being destroyed. If <code>destroy</code> is called multiple times before
1424 * the destruction completes, the etherialization should be invoked only once.
1426 * @param wait_for_completion if true, the method waits till the POA being
1427 * destroyed completes all current requests and etherialization. If false, the
1428 * method returns immediately.
1430 public void destroy(boolean etherealize_objects
, boolean wait_for_completion
)
1432 // Notify the IOR interceptors about that the POA is destroyed.
1433 if (m_orb
.iIor
!= null)
1434 m_orb
.iIor
.adapter_state_changed(
1435 new ObjectReferenceTemplate
[] { getReferenceTemplate() },
1436 NON_EXISTENT
.value
);
1438 if (wait_for_completion
)
1441 // Nofify the IOR interceptors that the POA is destroyed.
1442 if (m_manager
instanceof gnuPOAManager
)
1444 ((gnuPOAManager
) m_manager
).poaDestroyed(this);
1447 // Put the brake instead of manager, preventing the subsequent
1449 gnuPOAManager g
= new gnuPOAManager();
1450 g
.state
= State
.INACTIVE
;
1453 // Disconnect from parent.
1454 if (parent
instanceof gnuPOA
)
1456 ((gnuPOA
) parent
).children
.remove(this);
1459 unregisterFromManager();
1461 // Disconnect from the ORB all objects, registered with this POA.
1462 ArrayList keys
= new ArrayList();
1463 keys
.addAll(aom
.keySet());
1467 for (int i
= 0; i
< keys
.size(); i
++)
1469 key
= (byte[]) keys
.get(i
);
1471 if (obj
.poa
== this)
1472 m_orb
.disconnect(obj
.object
);
1475 m_orb
.identityDestroyed(this);
1477 if (etherealize_objects
&& servant_activator
!= null && !m_inDestruction
)
1481 m_inDestruction
= true;
1483 POA
[] ch
= the_children();
1484 for (int i
= 0; i
< ch
.length
; i
++)
1486 ch
[i
].destroy(etherealize_objects
, wait_for_completion
);
1491 * Destroy this POA if it has not been destroyed, destroys it.
1493 protected void finalize()
1494 throws java
.lang
.Throwable
1496 if (!m_inDestruction
)
1497 destroy(false, false);
1501 * Remove self from the manager list.
1503 private void unregisterFromManager()
1505 if (m_manager
instanceof gnuPOAManager
)
1507 gnuPOAManager p
= (gnuPOAManager
) m_manager
;
1513 * Get the policy of the given type, associated with this POA.
1515 * @param a_policy_type a type of the requested policy.
1516 * @return a policy of the given type, applyting to this POA.
1518 * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not
1519 * been specified for this POA.
1521 public Policy
_get_policy(int a_policy_type
)
1522 throws org
.omg
.CORBA
.BAD_PARAM
1524 for (int i
= 0; i
< s_policies
.length
; i
++)
1526 if (s_policies
[ i
].policy_type() == a_policy_type
)
1527 return s_policies
[ i
].copy();
1529 throw new BAD_PARAM("No policy type " + a_policy_type
);
1533 * Get the copy of the policy array.
1535 public Policy
[] getPolicyArray()
1537 Policy
[] r
= new Policy
[ s_policies
.length
];
1538 for (int i
= 0; i
< s_policies
.length
; i
++)
1540 r
[ i
] = s_policies
[ i
].copy();
1546 * The POAs cannot be created by this method.
1548 * @specnote this is also not possible in Suns jdk at least till 1.4.
1550 * @throws NO_IMPLEMENT always.
1552 public org
.omg
.CORBA
.Object
_set_policy_override(Policy
[] policies
,
1556 throw new NO_IMPLEMENT("Use createPOA instead.");
1560 * Get the ORB, where this POA is connected.
1568 * Connect the given delegate under the given key, also calling incarnate.
1570 private void create_and_connect(byte[] object_key
, String repository_id
,
1571 ServantDelegateImpl delegate
)
1574 connect_to_orb(object_key
, getReferenceFactory().make_object(repository_id
,
1576 if (servant_activator
!= null)
1577 incarnate(null, object_key
, delegate
.servant
, false);
1581 * Check if the POA is not in a discarding mode. The activation
1582 * operations are forbidded in discarding mode.
1584 * @throws TRANSIENT if the POA is in discarding mode.
1586 void checkDiscarding()
1589 if (m_manager
.get_state() == State
.DISCARDING
)
1590 throw new TRANSIENT("Discarding mode", 1, CompletionStatus
.COMPLETED_MAYBE
);
1594 * Connect the given delegate object to orb.
1596 protected void connect_to_orb(byte[] an_Object_Id
, org
.omg
.CORBA
.Object object
)
1598 if (applies(ThreadPolicyValue
.SINGLE_THREAD_MODEL
))
1599 m_orb
.connect_1_thread(object
, toIORKey(an_Object_Id
), this);
1601 m_orb
.connect(object
, toIORKey(an_Object_Id
));
1605 * Returns the representation of this POA tree.
1607 public String
toString()
1609 CPStringBuilder b
= new CPStringBuilder(name
);
1611 if (children
.size() != 0)
1615 for (int i
= 0; i
< children
.size(); i
++)
1617 b
.append(children
.get(i
));
1618 if (i
< children
.size() - 2)
1623 return b
.toString();
1627 * Check if the policy set is valid.
1629 protected boolean validatePolicies(Policy
[] a
)
1630 throws InvalidPolicy
1632 if (applies(ServantRetentionPolicyValue
.NON_RETAIN
))
1634 if (!applies(RequestProcessingPolicyValue
.USE_DEFAULT_SERVANT
) &&
1635 !applies(RequestProcessingPolicyValue
.USE_SERVANT_MANAGER
)
1639 for (short i
= 0; i
< a
.length
; i
++)
1641 if (a
[ i
].policy_type() == SERVANT_RETENTION_POLICY_ID
.value
)
1644 throw new InvalidPolicy("NON_RETAIN requires either " +
1645 "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER",
1654 * Recursively searches for the given object in the POA tree.
1656 public AOM
.Obj
findObject(org
.omg
.CORBA
.Object object
)
1658 AOM
.Obj h
= aom
.findObject(object
);
1663 for (int i
= 0; i
< children
.size(); i
++)
1665 h
= ((gnuPOA
) children
.get(i
)).findObject(object
);
1674 * Recursively searches for the given key in the POA tree.
1675 * @param ior_key the key, ecapsulating both object
1679 public AOM
.Obj
findKey(byte[] object_id
, byte[] poa_id
)
1682 if (Arrays
.equals(poa_id
, id()))
1683 h
= aom
.get(object_id
);
1688 for (int i
= 0; i
< children
.size(); i
++)
1690 h
= ((gnuPOA
) children
.get(i
)).findKey(object_id
, poa_id
);
1699 * Parses the given key, extracts poa and object id and searches
1700 * for such reference.
1702 public AOM
.Obj
findIorKey(byte[] ior_key
)
1704 BufferredCdrInput in
= new BufferredCdrInput(ior_key
);
1705 int signature
= in
.read_long();
1706 if (signature
!= SIGNATURE
)
1709 byte[] id
= in
.read_sequence();
1710 byte[] poa
= in
.read_sequence();
1711 return findKey(id
, poa
);
1715 * Converts the object Id into the IOR key. IOR key must be
1716 * unique in the scope of the ORB, and Ids only in the scope of POA.
1717 * Hence the IOR key includes the POA identifiers.
1719 public byte[] toIORKey(byte[] object_id
)
1721 BufferedCdrOutput buffer
= new BufferedCdrOutput();
1722 buffer
.write_long(SIGNATURE
);
1723 buffer
.write_sequence(object_id
);
1724 buffer
.write_sequence(id());
1725 return buffer
.buffer
.toByteArray();
1729 * Extracts the object id from the ior key.
1733 * @return the encapsulated object ior key or null if
1734 * this ior key either refers a different POA or encoding signature
1737 public byte[] idFormIor(byte[] ior_key
)
1739 BufferredCdrInput in
= new BufferredCdrInput(ior_key
);
1740 int signature
= in
.read_long();
1741 if (signature
!= SIGNATURE
)
1744 byte[] object_id
= in
.read_sequence();
1745 byte[] poa_id
= in
.read_sequence();
1746 if (Arrays
.equals(poa_id
, id()))
1753 * Recursively searches for the given servant in the POA tree.
1755 public AOM
.Obj
findServant(Servant servant
)
1757 AOM
.Obj h
= aom
.findServant(servant
);
1762 for (int i
= 0; i
< children
.size(); i
++)
1764 h
= ((gnuPOA
) children
.get(i
)).findServant(servant
);
1773 * Get the object reference template of this POA.
1774 * Instantiate a singleton instance, if required.
1776 public ObjectReferenceTemplate
getReferenceTemplate()
1778 if (refTemplate
== null)
1779 refTemplate
= new RefTemplate();
1784 public ObjectReferenceFactory
getReferenceFactory()
1786 return m_object_factory
;
1789 public void setReferenceFactory(ObjectReferenceFactory factory
)
1791 m_object_factory
= factory
;
1795 * Create the object (needed by the factory interface).
1797 public Object
make_object(String a_repository_id
, byte[] an_object_id
)
1799 AOM
.Obj existing
= aom
.get(an_object_id
);
1800 // The object may already exist. In this case, it is just returned.
1801 if (existing
!= null && existing
.object
!= null)
1802 return existing
.object
;
1805 return new gnuServantObject(new String
[] { a_repository_id
},
1806 an_object_id
, this, m_orb
);
1811 * Required by object reference factory ops.
1813 public String
[] _truncatable_ids()
1815 return ref_template_ids
;