| /* gnuAbstractPOA.java -- |
| Copyright (C) 2005 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| package gnu.CORBA.Poa; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| |
| import org.omg.CORBA.BAD_INV_ORDER; |
| import org.omg.CORBA.BAD_PARAM; |
| import org.omg.CORBA.CompletionStatus; |
| import org.omg.CORBA.LocalObject; |
| import org.omg.CORBA.NO_IMPLEMENT; |
| import org.omg.CORBA.OBJ_ADAPTER; |
| import org.omg.CORBA.ORB; |
| import org.omg.CORBA.Object; |
| import org.omg.CORBA.Policy; |
| import org.omg.CORBA.SetOverrideType; |
| import org.omg.CORBA.TRANSIENT; |
| import org.omg.CORBA.portable.ObjectImpl; |
| import org.omg.PortableInterceptor.NON_EXISTENT; |
| import org.omg.PortableInterceptor.ObjectReferenceFactory; |
| import org.omg.PortableInterceptor.ObjectReferenceTemplate; |
| import org.omg.PortableInterceptor.ObjectReferenceTemplateHelper; |
| import org.omg.PortableServer.AdapterActivator; |
| import org.omg.PortableServer.ForwardRequest; |
| import org.omg.PortableServer.IdAssignmentPolicy; |
| import org.omg.PortableServer.IdAssignmentPolicyValue; |
| import org.omg.PortableServer.IdUniquenessPolicy; |
| import org.omg.PortableServer.IdUniquenessPolicyValue; |
| import org.omg.PortableServer.ImplicitActivationPolicy; |
| import org.omg.PortableServer.ImplicitActivationPolicyValue; |
| import org.omg.PortableServer.LifespanPolicy; |
| import org.omg.PortableServer.LifespanPolicyValue; |
| import org.omg.PortableServer.POA; |
| import org.omg.PortableServer.POAManager; |
| import org.omg.PortableServer.RequestProcessingPolicy; |
| import org.omg.PortableServer.RequestProcessingPolicyValue; |
| import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; |
| import org.omg.PortableServer.Servant; |
| import org.omg.PortableServer.ServantActivator; |
| import org.omg.PortableServer.ServantLocator; |
| import org.omg.PortableServer.ServantManager; |
| import org.omg.PortableServer.ServantRetentionPolicy; |
| import org.omg.PortableServer.ServantRetentionPolicyValue; |
| import org.omg.PortableServer.ThreadPolicy; |
| import org.omg.PortableServer.ThreadPolicyValue; |
| import org.omg.PortableServer.POAManagerPackage.State; |
| import org.omg.PortableServer.POAPackage.AdapterAlreadyExists; |
| import org.omg.PortableServer.POAPackage.AdapterNonExistent; |
| import org.omg.PortableServer.POAPackage.InvalidPolicy; |
| import org.omg.PortableServer.POAPackage.NoServant; |
| import org.omg.PortableServer.POAPackage.ObjectAlreadyActive; |
| import org.omg.PortableServer.POAPackage.ObjectNotActive; |
| import org.omg.PortableServer.POAPackage.ServantAlreadyActive; |
| import org.omg.PortableServer.POAPackage.ServantNotActive; |
| import org.omg.PortableServer.POAPackage.WrongAdapter; |
| import org.omg.PortableServer.POAPackage.WrongPolicy; |
| |
| import gnu.CORBA.OrbFunctional; |
| import gnu.CORBA.CDR.BufferredCdrInput; |
| import gnu.CORBA.CDR.BufferedCdrOutput; |
| |
| /** |
| * Our POA implementation. |
| * |
| * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) |
| */ |
| public class gnuPOA |
| extends LocalObject |
| implements POA, ObjectReferenceFactory |
| { |
| /** |
| * The object reference template, associated with this POA. |
| * |
| * @since 1.5 |
| */ |
| class RefTemplate implements ObjectReferenceTemplate |
| { |
| /** |
| * Use serialVersionUID for interoperability. |
| */ |
| private static final long serialVersionUID = 1; |
| |
| RefTemplate() |
| { |
| // The adapter name is computed once. |
| ArrayList names = new ArrayList(); |
| names.add(the_name()); |
| |
| POA poa = the_parent(); |
| while (poa != null) |
| { |
| names.add(poa.the_name()); |
| poa = poa.the_parent(); |
| } |
| |
| // Fill in the string array in reverse (more natural) order, |
| // root POA first. |
| m_adapter_name = new String[names.size()]; |
| |
| for (int i = 0; i < m_adapter_name.length; i++) |
| m_adapter_name[i] = (String) names.get(m_adapter_name.length - i - 1); |
| } |
| |
| /** |
| * The adapter name |
| */ |
| final String[] m_adapter_name; |
| |
| /** |
| * Get the name of this POA. |
| */ |
| public String[] adapter_name() |
| { |
| return (String[]) m_adapter_name.clone(); |
| } |
| |
| /** |
| * Get the ORB id. |
| */ |
| public String orb_id() |
| { |
| return m_orb.orb_id; |
| } |
| |
| /** |
| * Get the server id. |
| */ |
| public String server_id() |
| { |
| return OrbFunctional.server_id; |
| } |
| |
| /** |
| * Create the object. |
| */ |
| public Object make_object(String repositoryId, byte[] objectId) |
| { |
| return create_reference_with_id(objectId, repositoryId); |
| } |
| |
| /** |
| * Get the array of truncatible repository ids. |
| */ |
| public String[] _truncatable_ids() |
| { |
| return ref_template_ids; |
| } |
| } |
| |
| /** |
| * Use serialVersionUID for interoperability. |
| */ |
| private static final long serialVersionUID = 1; |
| |
| /** |
| * The adapter reference template. |
| */ |
| ObjectReferenceTemplate refTemplate; |
| |
| /** |
| * The reference template repository ids. Defined outside the class as it |
| * cannot have static members. |
| */ |
| final static String[] ref_template_ids = |
| new String[] { ObjectReferenceTemplateHelper.id() }; |
| |
| /** |
| * The active object map, mapping between object keys, objects and servants. |
| */ |
| public final AOM aom = new AOM(); |
| |
| /** |
| * The children of this POA. |
| */ |
| final ArrayList children = new ArrayList(); |
| |
| /** |
| * The name of this POA. |
| */ |
| final String name; |
| |
| /** |
| * The parent of this POA (null for the root POA). |
| */ |
| final POA parent; |
| |
| /** |
| * The ior key signature, indicating, that the ior key is encoded using |
| * internal agreements of this implementation (0x'free'). |
| */ |
| static final int SIGNATURE = 0x66726565; |
| |
| /** |
| * The adapter activator for this POA, null if no activator is set. |
| */ |
| AdapterActivator m_activator; |
| |
| /** |
| * The POA manager for this POA. |
| */ |
| POAManager m_manager; |
| |
| /** |
| * The servant manager (servant activator) for this POA. |
| */ |
| ServantActivator servant_activator; |
| |
| /** |
| * The servant manager (servant locator) for this POA. |
| */ |
| ServantLocator servant_locator; |
| |
| /** |
| * The default servant, if on is in use. |
| */ |
| Servant default_servant; |
| |
| /** |
| * The cached poa id value, computed once. |
| */ |
| private byte[] m_poa_id; |
| |
| /** |
| * The all policy values that apply to this POA. |
| * The used policy values are singletons, unique between policies. |
| */ |
| private final HashSet m_policies; |
| |
| /** |
| * An array of the set policies. |
| */ |
| Policy[] s_policies; |
| |
| /** |
| * The ORB, where the POA is connected. |
| */ |
| final ORB_1_4 m_orb; |
| |
| /** |
| * When true, the POA is being destroyed or is destroyed. |
| */ |
| boolean m_inDestruction; |
| |
| /** |
| * True if the active object map is used by this POA. |
| * The value is moved into separate boolean value due |
| * necessity of the frequent checks. |
| */ |
| public final boolean retain_servant; |
| |
| /** |
| * The object reference factory, used to create the new object |
| * references. |
| */ |
| ObjectReferenceFactory m_object_factory = this; |
| |
| /** |
| * Create a new abstract POA. |
| * |
| * @param a_parent the parent of this POA. |
| * @param a_name a name for this POA. |
| * @param a_manager a manager for this POA. If null, a new |
| * {@link gnuPOAManager} will be instantiated. |
| * @param a_policies an array of policies that apply to this POA. |
| * @param an_orb an ORB for this POA. |
| */ |
| public gnuPOA(gnuPOA a_parent, String a_name, POAManager a_manager, |
| Policy[] a_policies, ORB_1_4 an_orb |
| ) |
| throws InvalidPolicy |
| { |
| // Add default policies. |
| Policy[] all_policies = StandardPolicies.withDefault(a_policies); |
| |
| name = a_name; |
| parent = a_parent; |
| m_orb = an_orb; |
| |
| if (a_manager != null) |
| m_manager = a_manager; |
| else |
| m_manager = new gnuPOAManager(); |
| |
| if (m_manager instanceof gnuPOAManager) |
| { |
| gnuPOAManager g = (gnuPOAManager) m_manager; |
| g.addPoa(this); |
| } |
| |
| m_policies = new HashSet(all_policies.length); |
| |
| s_policies = new Policy[ all_policies.length ]; |
| for (int i = 0; i < s_policies.length; i++) |
| { |
| s_policies [ i ] = all_policies [ i ].copy(); |
| m_policies.add(((AccessiblePolicy) s_policies [ i ]).getValue()); |
| } |
| |
| retain_servant = applies(ServantRetentionPolicyValue.RETAIN); |
| |
| validatePolicies(a_policies); |
| |
| refTemplate = new RefTemplate(); |
| } |
| |
| /** |
| * Wait while at least one of the threads in this POA is actively |
| * processing one of requests. |
| */ |
| public void waitWhileRunning() |
| { |
| // First pause. |
| long time = 1; |
| |
| // Maximal duration between checks. |
| long max = 500; |
| |
| boolean runs; |
| |
| do |
| { |
| runs = m_orb.currents.has(this); |
| |
| if (runs) |
| { |
| // Avoid taking CPU resources |
| // from the thread that is running. |
| try |
| { |
| Thread.sleep(time); |
| time = time * 2; |
| if (time > max) |
| time = max; |
| } |
| catch (InterruptedException ex) |
| { |
| } |
| } |
| } |
| while (runs); |
| } |
| |
| /** |
| * Etherealize all objects, associated with this POA. Invoked from the |
| * {@link gnuPOAManager} only if it is known that the servant_activator |
| * holds non-null value. |
| */ |
| protected void etherealizeAll() |
| { |
| if (servant_activator == null) |
| return; |
| |
| ArrayList keys = new ArrayList(); |
| keys.addAll(aom.keySet()); |
| |
| byte[] key; |
| AOM.Obj obj; |
| boolean last; |
| for (int i = 0; i < keys.size(); i++) |
| { |
| key = (byte[]) keys.get(i); |
| obj = aom.get(key); |
| |
| if (obj.poa == this) |
| { |
| aom.remove(key); |
| |
| if (!obj.isDeactiveted()) |
| { |
| // Check if the servant still stays under the other key. |
| last = aom.findServant(obj.servant) == null; |
| servant_activator.etherealize(obj.key, this, obj.servant, true, |
| last |
| ); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Create an instance of the POA with the given features. |
| * This method is not responsible for duplicate checking |
| * or adding the returned instance to any possible table. |
| * |
| * @param child_name the name of the poa being created. |
| * @param manager the poa manager (never null). |
| * @param policies the array of policies. |
| * @param an_orb the ORB for this POA. |
| * |
| * @return the created POA. |
| * |
| * @throws InvalidPolicy for conflicting or otherwise invalid policies.| |
| */ |
| protected POA createPoaInstance(String child_name, POAManager a_manager, |
| Policy[] policies, ORB_1_4 an_orb |
| ) |
| throws InvalidPolicy |
| { |
| POAManager some_manager = |
| a_manager == null ? new gnuPOAManager() : a_manager; |
| |
| if (some_manager instanceof gnuPOAManager) |
| { |
| ((gnuPOAManager) some_manager).addPoa(this); |
| } |
| |
| return new gnuPOA(this, child_name, some_manager, policies, an_orb); |
| } |
| |
| /** |
| * Check if the given policy value applies to this POA. |
| * |
| * @param policy_value a policy value to check. The policy values are |
| * singletons and unique between the different policies, so the policy |
| * type is not passed. |
| * |
| * @return true if the policy value applies, false otherwise. |
| */ |
| public final boolean applies(java.lang.Object policy_value) |
| { |
| return m_policies.contains(policy_value); |
| } |
| |
| /** |
| * Check for the presence of the required policy. |
| * |
| * @param policy_value a policy value to check. |
| * |
| * @throws WrongPolicy if the required policy value is not applicable. |
| */ |
| public final void required(java.lang.Object policy_value) |
| throws WrongPolicy |
| { |
| if (!applies(policy_value)) |
| throw new WrongPolicy(policy_value + " policy required."); |
| } |
| |
| /** |
| * Check for the absence of the given policy. |
| * |
| * @param policy_value a policy value to check. |
| * |
| * @throws WrongPolicy if the passed policy value is applicable. |
| */ |
| public final void excluding(java.lang.Object policy_value) |
| throws WrongPolicy |
| { |
| if (applies(policy_value)) |
| throw new WrongPolicy(policy_value + " policy applies."); |
| } |
| |
| /** |
| * Find and optionally activate the child POA with the given name. |
| * |
| * @param poa_name the name of the POA to find. |
| * @param activate_it if the child with the specified name is not found |
| * or inactive and this parameter is true, the target POA activator is |
| * invoked to activate that child. If this succeeds, that child POA |
| * is returned. |
| * |
| * @throws AdapterNonExistent if no active child with the given name |
| * is found and one of the following is true: |
| * a) the target POA has no associated |
| * {@link AdapterActivator}. b) that activator fails to activate the |
| * child POA. c) <code>activate_id</code> = false. |
| */ |
| public POA find_POA(String poa_name, boolean activate_it) |
| throws AdapterNonExistent |
| { |
| POA child; |
| for (int i = 0; i < children.size(); i++) |
| { |
| child = (POA) children.get(i); |
| if (child.the_name().equals(poa_name)) |
| return child; |
| } |
| |
| if (activate_it && m_activator != null) |
| { |
| boolean activated = m_activator.unknown_adapter(this, poa_name); |
| if (!activated) |
| throw new AdapterNonExistent(poa_name + " activation failed."); |
| |
| // Tha activator should add the child to the childrent table. |
| for (int i = 0; i < children.size(); i++) |
| { |
| child = (POA) children.get(i); |
| if (child.the_name().equals(poa_name)) |
| return child; |
| } |
| throw new AdapterNonExistent(poa_name + " not created. "); |
| } |
| else |
| throw new AdapterNonExistent(poa_name); |
| } |
| |
| /** |
| * Generate the Object Id for the given servant and add the servant to the |
| * Active Object Map using this Id a a key. If the servant activator is set, |
| * its incarnate method will be called. |
| * |
| * @param a_servant a servant that would serve the object with the returned |
| * Object Id. If null is passed, under apporoprate policies the servant |
| * activator is invoked. |
| * |
| * @return the generated objert Id for the given servant. |
| * |
| * @throws ServantAlreadyActive if this servant is already in the Active |
| * Object Map and the UNIQUE_ID policy applies. |
| * |
| * @throws WrongPolicy if the required policies SYSTEM_ID and RETAIN do not |
| * apply to this POA. |
| */ |
| public byte[] activate_object(Servant a_servant) |
| throws ServantAlreadyActive, WrongPolicy |
| { |
| checkDiscarding(); |
| required(ServantRetentionPolicyValue.RETAIN); |
| required(IdAssignmentPolicyValue.SYSTEM_ID); |
| |
| AOM.Obj exists = aom.findServant(a_servant); |
| |
| if (exists != null) |
| { |
| if (exists.isDeactiveted()) |
| { |
| // If exists but deactivated, activate and return |
| // the existing key. |
| exists.setDeactivated(false); |
| incarnate(exists, exists.key, a_servant, false); |
| return exists.key; |
| } |
| else if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) |
| throw new ServantAlreadyActive(); |
| |
| // It multiple ids are allowed, exit block allowing repetetive |
| // activations. |
| } |
| |
| byte[] object_key = AOM.getFreeId(); |
| ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this, |
| object_key); |
| create_and_connect(object_key, |
| a_servant._all_interfaces(this, object_key)[0], delegate); |
| return object_key; |
| } |
| |
| /** |
| * Add the given servant to the Active Object Map as a servant for the object |
| * with the provided Object Id. If the servant activator is set, its incarnate |
| * method will be called. |
| * |
| * @param an_Object_Id an object id for the given object. |
| * @param a_servant a servant that will serve the object with the given Object |
| * Id. If null is passed, under apporoprate policies the servant activator is |
| * invoked. |
| * |
| * @throws ObjectAlreadyActive if the given object id is already in the Active |
| * Object Map. |
| * @throws ServantAlreadyActive if the UNIQUE_ID policy applies and this |
| * servant is already in use. |
| * @throws WrongPolicy if the required RETAIN policy does not apply to this |
| * POA. |
| * @throws BAD_PARAM if the passed object id is invalid due any reason. |
| */ |
| public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant) |
| throws ServantAlreadyActive, ObjectAlreadyActive, |
| WrongPolicy |
| { |
| activate_object_with_id(an_Object_Id, a_servant, false); |
| } |
| |
| /** |
| * Same as activate_object_with_id, but permits gnuForwardRequest forwarding |
| * exception. This is used when the activation is called from the remote |
| * invocation context and we have possibility to return the forwarding |
| * message. |
| */ |
| public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant, |
| boolean use_forwarding) |
| throws ServantAlreadyActive, ObjectAlreadyActive, WrongPolicy |
| { |
| checkDiscarding(); |
| required(ServantRetentionPolicyValue.RETAIN); |
| |
| // If the UNIQUE_ID applies, the servant being passed must not be |
| // already active. |
| if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) |
| { |
| AOM.Obj sx = aom.findServant(a_servant, false); |
| if (sx != null) |
| throw new ServantAlreadyActive(); |
| } |
| |
| AOM.Obj exists = aom.get(an_Object_Id); |
| if (exists != null) |
| { |
| if (exists.servant == null) |
| { |
| locateServant(an_Object_Id, a_servant, exists, use_forwarding); |
| exists.setDeactivated(false); |
| } |
| else if (exists.isDeactiveted()) |
| { |
| exists.setDeactivated(false); |
| incarnate(exists, an_Object_Id, a_servant, use_forwarding); |
| } |
| else |
| throw new ObjectAlreadyActive(); |
| } |
| else |
| { |
| ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this, |
| an_Object_Id); |
| create_and_connect(an_Object_Id, a_servant._all_interfaces(this, |
| an_Object_Id)[0], delegate); |
| } |
| } |
| |
| /** |
| * Locate the servant for this object Id and connect it to ORB. |
| * |
| * @param an_Object_Id the object id. |
| * @param a_servant the servant (may be null). |
| * @param exists an existing active object map entry. |
| * @param use_forwarding allow to throw the gnuForwardRequest if the activator |
| * throws ForwardRequest. |
| * |
| * @throws OBJ_ADAPTER minor 4 if the servant cannot be located (the required |
| * servant manager may be missing). |
| */ |
| private void locateServant(byte[] an_Object_Id, Servant a_servant, |
| AOM.Obj exists, boolean use_forwarding |
| ) |
| throws InternalError |
| { |
| // An object was created with create_reference. |
| gnuServantObject object = (gnuServantObject) exists.object; |
| if (servant_activator != null) |
| { |
| exists.setServant(incarnate(exists, an_Object_Id, a_servant, |
| use_forwarding |
| ) |
| ); |
| } |
| else if (default_servant != null) |
| { |
| exists.setServant(default_servant); |
| } |
| if (exists.servant == null) |
| { |
| exists.setServant(a_servant); |
| } |
| if (exists.servant == null) |
| { |
| throw new OBJ_ADAPTER("no servant", 4, CompletionStatus.COMPLETED_NO); |
| } |
| |
| ServantDelegateImpl delegate = |
| new ServantDelegateImpl(exists.servant, this, an_Object_Id); |
| exists.servant._set_delegate(delegate); |
| object.setServant(exists.servant); |
| connect_to_orb(an_Object_Id, delegate.object); |
| } |
| |
| /** |
| * Deactivate object with the given id. |
| * |
| * The deactivated object will continue to process requests that arrived |
| * before decativation. If this POA has the associated |
| * servant manager, a {@link ServantActivatorOperations#etherealize} is |
| * immediately invoked on the passed id. |
| * |
| * @throws WrongPolicy if the required RETAIN policy does not apply to |
| * this POA. |
| */ |
| public void deactivate_object(byte[] the_Object_Id) |
| throws ObjectNotActive, WrongPolicy |
| { |
| required(ServantRetentionPolicyValue.RETAIN); |
| |
| AOM.Obj exists = aom.get(the_Object_Id); |
| |
| if (exists == null || exists.isDeactiveted()) |
| throw new ObjectNotActive(); |
| |
| exists.setDeactivated(true); |
| |
| // Check if this servant is serving something else. |
| aom.remove(the_Object_Id); |
| |
| AOM.Obj other = aom.findServant(exists.servant, false); |
| |
| boolean remaining = other != null; |
| |
| aom.put(exists); |
| |
| if (servant_activator != null) |
| servant_activator.etherealize(the_Object_Id, this, exists.servant, false, |
| remaining |
| ); |
| } |
| |
| /** |
| * Create the object reference, encapsulating the given repository Id and |
| * the Object Id, generated by this POA. The returned object will not be |
| * activated by default and may be activated on the first invocation by |
| * the servant manager (if it is set and if policies are applicable). |
| * |
| * @param a_repository_id the repository id for the given object, can |
| * be null if to be requested from the servant later. |
| * |
| * @throws WrongPolicy if the required SYSTEM_ID policy does not apply to |
| * this POA. |
| */ |
| public org.omg.CORBA.Object create_reference(String a_repository_id) |
| throws WrongPolicy |
| { |
| required(IdAssignmentPolicyValue.SYSTEM_ID); |
| return create_reference_with_id(AOM.getFreeId(), a_repository_id); |
| } |
| |
| /** |
| * <p> |
| * Create the object reference, encapsulating the given repository Id and |
| * the given Object Id. The returned object will <i>not</i> be |
| * activated by default and may be activated on the first invocation by |
| * the servant manager (if the IMPLICIT_ACTIVATION policy applies). |
| * |
| * @param an_object_id the object id for the object being created. If this |
| * POA uses the SYSTEM_ID policy, the portable application should only |
| * pass the ids, generated by this POA. |
| * |
| * @param a_repository_id the repository id for the object being created, |
| * can be null if this information should be later requested from the |
| * servant. |
| */ |
| public org.omg.CORBA.Object create_reference_with_id(byte[] an_object_id, |
| String a_repository_id |
| ) |
| { |
| String[] ids; |
| if (a_repository_id == null) |
| ids = null; |
| else |
| ids = new String[] { a_repository_id }; |
| |
| // Check maybe such object is already activated. |
| AOM.Obj e = aom.get(an_object_id); |
| |
| Servant servant; |
| if (e == null) |
| { |
| servant = null; |
| } |
| else |
| { |
| servant = e.servant; |
| e.setDeactivated(false); |
| } |
| |
| gnuServantObject object = |
| new gnuServantObject(ids, an_object_id, this, m_orb); |
| object._set_delegate(new LocalDelegate(object, this, an_object_id)); |
| aom.add(object.Id, object, servant, this); |
| connect_to_orb(an_object_id, object); |
| |
| return object; |
| } |
| |
| /** |
| * Creates a new POA as a child of the target POA. |
| * |
| * @param child_name the name of the child POA being created. |
| * @param manager the manager that will control the new POA. If this parameter |
| * is null, a new POA manager is created and associated with the new POA. |
| * |
| * @param policies the policies, applicable for the parent POA. Policies |
| * are <i>not</i> inherited from the parent POA. |
| * |
| * @return an newly created POA. The POA will be intially in the holding |
| * state and must be activated to start processing requests. |
| * |
| * @throws AdapterAlreadyExists if the child with the given child_name |
| * already exists for the current POA. |
| * @throws InvalidPolicy if the policies conflict with each other or are |
| * otherwise inappropriate. |
| * |
| * @see #the_children() |
| */ |
| public POA create_POA(String child_name, POAManager manager, Policy[] policies) |
| throws AdapterAlreadyExists, InvalidPolicy |
| { |
| POA child; |
| for (int i = 0; i < children.size(); i++) |
| { |
| child = (POA) children.get(i); |
| if (child.the_name().equals(child_name)) |
| throw new AdapterAlreadyExists(name + "/" + child_name); |
| } |
| |
| POA poa = createPoaInstance(child_name, manager, policies, m_orb); |
| children.add(poa); |
| return poa; |
| } |
| |
| /** |
| * Returns a default servant for this POA. |
| * |
| * @return a servant that will be used for requests for |
| * which no servant is found in the Active Object Map. |
| * |
| * @throws NoServant if there is no default servant associated with this POA. |
| * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. |
| */ |
| public Servant get_servant() |
| throws NoServant, WrongPolicy |
| { |
| required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); |
| if (default_servant == null) |
| throw new NoServant(); |
| return default_servant; |
| } |
| |
| /** |
| * Sets the default servant for this POA. |
| * |
| * @param a_servant a servant that will be used for requests for |
| * which no servant is found in the Active Object Map. |
| * |
| * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. |
| */ |
| public void set_servant(Servant a_servant) |
| throws WrongPolicy |
| { |
| required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); |
| default_servant = a_servant; |
| } |
| |
| /** |
| * Set a servant manager for this POA. |
| * |
| * @param a servant manager being set. If the RETAIN policy applies, the |
| * manager must implement a {@link ServantActivator}. If the NON_RETAIN |
| * policy applies, the manager must implement a {@link ServantLocator}. |
| * |
| * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not |
| * apply to this POA. |
| * |
| * @throws OBJ_ADAPTER minor code 4 if the passed manager does not |
| * implement the required interface ({@link ServantActivator}, |
| * {@link ServantLocator}). The POA, that has the RETAIN policy uses |
| * servant managers that are ServantActivators. When the POA has the |
| * NON_RETAIN policy it uses servant managers that are ServantLoacators. |
| * |
| * @throws BAD_INV_ORDER minor code 6 if the method is called more than once |
| * on the same POA. The manager can be set only once. |
| */ |
| public void set_servant_manager(ServantManager a_manager) |
| throws WrongPolicy |
| { |
| required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); |
| if (servant_activator != null || servant_locator != null) |
| throw new BAD_INV_ORDER("Setting manager twice for " + name, 6, |
| CompletionStatus.COMPLETED_NO |
| ); |
| |
| if (applies(ServantRetentionPolicyValue.RETAIN)) |
| { |
| if (a_manager instanceof ServantActivator) |
| servant_activator = (ServantActivator) a_manager; |
| else |
| throw new OBJ_ADAPTER("RETAIN requires ServantActivator", 4, |
| CompletionStatus.COMPLETED_NO |
| ); |
| } |
| else if (applies(ServantRetentionPolicyValue.NON_RETAIN)) |
| { |
| if (a_manager instanceof ServantLocator) |
| servant_locator = (ServantLocator) a_manager; |
| else |
| throw new OBJ_ADAPTER("NON_RETAIN requires ServantLocator", 4, |
| CompletionStatus.COMPLETED_NO |
| ); |
| } |
| else |
| throw new WrongPolicy("No servant retention policy is specified."); |
| } |
| |
| /** |
| * Get the servant manager, associated with this POA. |
| * |
| * @return the associated servant manager or null if it has |
| * been previously set. |
| * |
| * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not |
| * apply to this POA. |
| */ |
| public ServantManager get_servant_manager() |
| throws WrongPolicy |
| { |
| required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); |
| |
| if (servant_activator != null) |
| return servant_activator; |
| else |
| return servant_locator; |
| } |
| |
| /** |
| * Get the unique Id of the POA in the process in which it is created. |
| * This Id is needed by portable interceptors. The id is unique |
| * for the life span of the POA in the process. For persistent |
| * POAs, if a POA is created in the same path with the same name as |
| * another POA, these POAs are identical have the same id. All transient |
| * POAs are assumed unique. |
| */ |
| public byte[] id() |
| { |
| if (m_poa_id != null) |
| return m_poa_id; |
| else |
| { |
| BufferedCdrOutput buffer = new BufferedCdrOutput(); |
| POA p = this; |
| while (p != null) |
| { |
| buffer.write_string(p.the_name()); |
| p = p.the_parent(); |
| } |
| m_poa_id = buffer.buffer.toByteArray(); |
| return m_poa_id; |
| } |
| } |
| |
| /** |
| * Returns the reference to the active object with the given Id. |
| * |
| * @param the_Object_Id the object id. |
| * |
| * @throws ObjectNotActive if there is no active object with such Id |
| * in the scope of this POA. |
| * @throws WrongPolicy if the required RETAIN policy does not apply to |
| * this POA. |
| */ |
| public org.omg.CORBA.Object id_to_reference(byte[] the_Object_Id) |
| throws ObjectNotActive, WrongPolicy |
| { |
| required(ServantRetentionPolicyValue.RETAIN); |
| |
| AOM.Obj ref = aom.get(the_Object_Id); |
| if (ref == null) |
| throw new ObjectNotActive(); |
| else |
| return ref.object; |
| } |
| |
| /** |
| * Returns the servant that serves the active object with the given Id. |
| * |
| * @param the_Object_Id the object id. |
| * |
| * @throws ObjectNotActive if there is no active object with such Id or |
| * it is not currently active. |
| * @throws WrongPolicy. This method requires either RETAIN or |
| * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them |
| * apply to this POA. |
| */ |
| public Servant id_to_servant(byte[] the_Object_Id) |
| throws ObjectNotActive, WrongPolicy |
| { |
| if (applies(ServantRetentionPolicyValue.RETAIN)) |
| { |
| AOM.Obj ref = aom.get(the_Object_Id); |
| if (ref == null || ref.isDeactiveted()) |
| { |
| if (default_servant != null) |
| return default_servant; |
| else |
| throw new ObjectNotActive(); |
| } |
| else if (ref.servant != null) |
| return ref.servant; |
| else if (default_servant != null) |
| return default_servant; |
| else |
| throw new ObjectNotActive(); |
| } |
| else if (default_servant != null) |
| { |
| return default_servant; |
| } |
| else |
| throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); |
| } |
| |
| /** |
| * Returns the Object Id, encapsulated in the given object reference. |
| * |
| * @param the_Object the object that has been previously created with this |
| * POA. It need not be active. |
| * |
| * @throws WrongAdapter if the passed object is not known for this POA. |
| * @throws WrongPolicy never (declared for the future extensions only). |
| */ |
| public byte[] reference_to_id(org.omg.CORBA.Object the_Object) |
| throws WrongAdapter, WrongPolicy |
| { |
| AOM.Obj ref = aom.findObject(the_Object); |
| if (ref == null) |
| throw new WrongAdapter(); |
| return ref.key; |
| } |
| |
| /** |
| * Returns the servant that is serving this object. |
| * |
| * @return if the RETAIN policy applies and the object is in the Active Object |
| * Map, the method returns the servant, associated with this object. |
| * Otherwise, if the USE_DEFAULT_SERVANT policy applies, the method returns |
| * the default servant (if one was set). |
| * |
| * @throws ObjectNotActive if none of the conditions above are satisfied. |
| * @throws WrongAdapter if the object reference was not created with this POA. |
| * @throws WrongPolicy. This method requires either RETAIN or |
| * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them |
| * apply to this POA. |
| */ |
| public Servant reference_to_servant(org.omg.CORBA.Object the_Object) |
| throws ObjectNotActive, WrongPolicy, WrongAdapter |
| { |
| if (applies(ServantRetentionPolicyValue.RETAIN)) |
| { |
| AOM.Obj ref = aom.findObject(the_Object); |
| if (ref == null) |
| { |
| String object; |
| if (the_Object == null) |
| object = "null passed"; |
| else if (the_Object instanceof gnuServantObject) |
| { |
| gnuServantObject gs = (gnuServantObject) the_Object; |
| object = "Wrong owner POA " + gs.poa.the_name(); |
| } |
| else |
| object = "Unknown " + the_Object.getClass().getName(); |
| |
| throw new WrongAdapter(object + " for '" + the_name() + "'"); |
| } |
| else if (ref.isDeactiveted() || ref.servant == null) |
| { |
| if (default_servant != null) |
| return default_servant; |
| else |
| throw new ObjectNotActive(); |
| } |
| else |
| return ref.servant; |
| } |
| else if (default_servant != null) |
| { |
| return default_servant; |
| } |
| else |
| throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); |
| } |
| |
| /** |
| * Returns the id of the object, served by the given servant (assuming that |
| * the servant serves only one object). The id is found in one of the |
| * following ways. |
| * <ul> |
| * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and the |
| * specified servant is active, the method return the Object Id associated |
| * with that servant. </li> |
| * <li> If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and |
| * either the POA has the MULTIPLE_ID policy or the specified servant is |
| * inactive, the method activates the servant using a POA-generated Object Id |
| * and the Interface Id associated with the servant, and returns that Object |
| * Id. </li> |
| * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified |
| * is the default servant, and the method is being invoked in the context of |
| * executing a request on the default servant, the method returns the ObjectId |
| * associated with the current invocation. </li> |
| * </ul> |
| * |
| * @throws ServantNotActive in all cases, not listed in the list above. |
| * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or a |
| * combination of the RETAIN policy and either the UNIQUE_ID or |
| * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions |
| * are not satisfied. |
| */ |
| public byte[] servant_to_id(Servant the_Servant) |
| throws ServantNotActive, WrongPolicy |
| { |
| if (applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) || |
| applies(ServantRetentionPolicyValue.RETAIN) && |
| ( |
| applies(IdUniquenessPolicyValue.UNIQUE_ID) || |
| applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) |
| ) |
| ) |
| { |
| AOM.Obj ref = null; |
| if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) |
| ref = aom.findServant(the_Servant); |
| if (ref == null && |
| applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) |
| ) |
| { |
| // Try to activate. |
| try |
| { |
| return activate_object(the_Servant); |
| } |
| catch (ServantAlreadyActive ex) |
| { |
| // Either it shuld not be or the policy allows multiple ids. |
| throw new InternalError(); |
| } |
| } |
| if (ref == null) |
| throw new ServantNotActive(); |
| else |
| return ref.key; |
| } |
| else |
| throw new WrongPolicy("(RETAIN and UNIQUE ID) " + |
| "or USE_DEFAULT_SERVANT required." |
| ); |
| } |
| |
| /** |
| * <p> |
| * Converts the given servant to the object reference. The servant will serve |
| * all methods, invoked on the returned object. The returned object reference |
| * can be passed to the remote client, enabling remote invocations. |
| * </p> |
| * <p> |
| * If the specified servant is active, it is returned. Otherwise, if the POA |
| * has the IMPLICIT_ACTIVATION policy the method activates the servant. In |
| * this case, if the servant activator is set, the |
| * {@link ServantActivatorOperations#incarnate} method will be called. |
| * </p> |
| * |
| * @throws ServantNotActive if the servant is inactive and no |
| * IMPLICIT_ACTIVATION policy applies. |
| * @throws WrongPolicy This method needs the RETAIN policy and either the |
| * UNIQUE_ID or IMPLICIT_ACTIVATION policies. |
| * |
| * @return the object, exposing the given servant in the context of this POA. |
| */ |
| public org.omg.CORBA.Object servant_to_reference(Servant the_Servant) |
| throws ServantNotActive, WrongPolicy |
| { |
| required(ServantRetentionPolicyValue.RETAIN); |
| |
| AOM.Obj exists = null; |
| |
| if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) |
| exists = aom.findServant(the_Servant); |
| |
| if (exists != null) |
| { |
| if (exists.isDeactiveted()) |
| { |
| if (applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)) |
| { |
| checkDiscarding(); |
| exists.setDeactivated(false); |
| incarnate(exists, exists.key, the_Servant, false); |
| } |
| else |
| throw new ServantNotActive(); |
| } |
| else |
| return exists.object; |
| } |
| if (exists == null |
| && applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)) |
| { |
| checkDiscarding(); |
| |
| byte[] object_key = AOM.getFreeId(); |
| |
| ServantDelegateImpl delegate = new ServantDelegateImpl(the_Servant, |
| this, object_key); |
| create_and_connect(object_key, the_Servant._all_interfaces(this, |
| object_key)[0], delegate); |
| |
| return delegate.object; |
| } |
| else |
| throw new ServantNotActive(); |
| } |
| |
| /** |
| * Incarnate in cases when request forwarding is not expected because the |
| * servant must be provided by the servant activator. |
| * |
| * @param x the aom entry, where the object is replaced by value, returned by |
| * servant activator (if not null). |
| * |
| * @param key the object key. |
| * |
| * @param a_servant the servant that was passed as a parameter in the |
| * activation method. |
| * |
| * @param use_forwarding if true, the gnuForwardRequest is throw under the |
| * forwarding exception (for remote client). Otherwise, the request is |
| * internally redirected (for local invocation). |
| */ |
| private Servant incarnate(AOM.Obj x, byte[] object_key, |
| Servant a_servant, boolean use_forwarding |
| ) |
| { |
| if (servant_activator != null) |
| { |
| Servant servant; |
| try |
| { |
| servant = servant_activator.incarnate(object_key, this); |
| } |
| catch (ForwardRequest ex) |
| { |
| if (use_forwarding) |
| throw new gnuForwardRequest(ex.forward_reference); |
| else |
| servant = |
| ForwardedServant.create((ObjectImpl) ex.forward_reference); |
| } |
| if (servant != null && x != null) |
| x.setServant(servant); |
| if (servant == null && x != null) |
| servant = x.servant; |
| return servant; |
| } |
| else if (a_servant != null) |
| { |
| x.setServant(a_servant); |
| return a_servant; |
| } |
| else if (x.servant != null) |
| { |
| return x.servant; |
| } |
| else if (default_servant != null) |
| { |
| x.setServant(default_servant); |
| return x.servant; |
| } |
| else |
| throw new BAD_INV_ORDER("No servant given and the servant activator not set"); |
| } |
| |
| /** |
| * Return the POA manager, associated with this POA. |
| * |
| * @return the associated POA manager (always available). |
| */ |
| public POAManager the_POAManager() |
| { |
| return m_manager; |
| } |
| |
| /** |
| * Returns the adapter activator, associated with this POA. |
| * The newly created POA has no activator (null would be |
| * returned). The ORB root POA also initially has no activator. |
| * |
| * @return tha adapter activator or null if this POA has no |
| * associated adapter activator. |
| */ |
| public AdapterActivator the_activator() |
| { |
| return m_activator; |
| } |
| |
| /** |
| * Set the adapter activator for this POA. |
| * |
| * @param the activator being set. |
| */ |
| public void the_activator(AdapterActivator an_activator) |
| { |
| m_activator = an_activator; |
| } |
| |
| /** |
| * The children of this POA. |
| * |
| * @return the array of all childs for this POA. |
| */ |
| public POA[] the_children() |
| { |
| POA[] poas = new POA[ children.size() ]; |
| for (int i = 0; i < poas.length; i++) |
| { |
| poas [ i ] = (POA) children.get(i); |
| } |
| return poas; |
| } |
| |
| /** |
| * Return the name of this POA. |
| * |
| * @return the name of POA, relative to its parent. |
| */ |
| public String the_name() |
| { |
| return name; |
| } |
| ; |
| |
| /** |
| * Return the parent of this POA. |
| * |
| * @return the parent POA or <code>null</code> if this is a root POA. |
| */ |
| public POA the_parent() |
| { |
| return parent; |
| } |
| |
| /** {@inheritDoc} */ |
| public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue a_value) |
| { |
| return new gnuIdAssignmentPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue a_value) |
| { |
| return new gnuIdUniquenessPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue a_value) |
| { |
| return new gnuImplicitActivationPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public LifespanPolicy create_lifespan_policy(LifespanPolicyValue a_value) |
| { |
| return new gnuLifespanPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue a_value) |
| { |
| return new gnuRequestProcessingPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue a_value) |
| { |
| return new gnuServantRetentionPolicy(a_value); |
| } |
| |
| /** {@inheritDoc} */ |
| public ThreadPolicy create_thread_policy(ThreadPolicyValue a_value) |
| { |
| return new gnuThreadPolicy(a_value); |
| } |
| |
| /** |
| * <p> |
| * Destroy this POA and all descendant POAs. The destroyed POAs can be later |
| * re-created via {@link AdapterActivator} or by invoking {@link #create_POA}. |
| * This differs from {@link PoaManagerOperations#deactivate} that does not |
| * allow recreation of the deactivated POAs. After deactivation, recreation is |
| * only possible if the POAs were later destroyed. |
| * </p> |
| * <p> |
| * The remote invocation on the target, belonging to the POA that is currently |
| * destroyed return the remote exception ({@link TRANSIENT}, minor code 4). |
| * </p> |
| * |
| * @param etherealize_objects if true, and POA has RETAIN policy, and the |
| * servant manager is available, the servant manager method |
| * {@link ServantActivatorOperations#etherealize} is called for each <i>active</i> |
| * object in the Active Object Map. This method should not try to access POA |
| * being destroyed. If <code>destroy</code> is called multiple times before |
| * the destruction completes, the etherialization should be invoked only once. |
| * |
| * @param wait_for_completion if true, the method waits till the POA being |
| * destroyed completes all current requests and etherialization. If false, the |
| * method returns immediately. |
| */ |
| public void destroy(boolean etherealize_objects, boolean wait_for_completion) |
| { |
| // Notify the IOR interceptors about that the POA is destroyed. |
| if (m_orb.iIor != null) |
| m_orb.iIor.adapter_state_changed( |
| new ObjectReferenceTemplate[] { getReferenceTemplate() }, |
| NON_EXISTENT.value); |
| |
| if (wait_for_completion) |
| waitWhileRunning(); |
| |
| // Nofify the IOR interceptors that the POA is destroyed. |
| if (m_manager instanceof gnuPOAManager) |
| { |
| ((gnuPOAManager) m_manager).poaDestroyed(this); |
| } |
| |
| // Put the brake instead of manager, preventing the subsequent |
| // requests. |
| gnuPOAManager g = new gnuPOAManager(); |
| g.state = State.INACTIVE; |
| m_manager = g; |
| |
| // Disconnect from parent. |
| if (parent instanceof gnuPOA) |
| { |
| ((gnuPOA) parent).children.remove(this); |
| } |
| |
| unregisterFromManager(); |
| |
| // Disconnect from the ORB all objects, registered with this POA. |
| ArrayList keys = new ArrayList(); |
| keys.addAll(aom.keySet()); |
| |
| byte[] key; |
| AOM.Obj obj; |
| for (int i = 0; i < keys.size(); i++) |
| { |
| key = (byte[]) keys.get(i); |
| obj = aom.get(key); |
| if (obj.poa == this) |
| m_orb.disconnect(obj.object); |
| } |
| |
| m_orb.identityDestroyed(this); |
| |
| if (etherealize_objects && servant_activator != null && !m_inDestruction) |
| { |
| etherealizeAll(); |
| } |
| m_inDestruction = true; |
| |
| POA[] ch = the_children(); |
| for (int i = 0; i < ch.length; i++) |
| { |
| ch[i].destroy(etherealize_objects, wait_for_completion); |
| } |
| } |
| |
| /** |
| * Destroy this POA if it has not been destroyed, destroys it. |
| */ |
| protected void finalize() |
| throws java.lang.Throwable |
| { |
| if (!m_inDestruction) |
| destroy(false, false); |
| } |
| |
| /** |
| * Remove self from the manager list. |
| */ |
| private void unregisterFromManager() |
| { |
| if (m_manager instanceof gnuPOAManager) |
| { |
| gnuPOAManager p = (gnuPOAManager) m_manager; |
| p.removePOA(this); |
| } |
| } |
| |
| /** |
| * Get the policy of the given type, associated with this POA. |
| * |
| * @param a_policy_type a type of the requested policy. |
| * @return a policy of the given type, applyting to this POA. |
| * |
| * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not |
| * been specified for this POA. |
| */ |
| public Policy _get_policy(int a_policy_type) |
| throws org.omg.CORBA.BAD_PARAM |
| { |
| for (int i = 0; i < s_policies.length; i++) |
| { |
| if (s_policies [ i ].policy_type() == a_policy_type) |
| return s_policies [ i ].copy(); |
| } |
| throw new BAD_PARAM("No policy type " + a_policy_type); |
| } |
| |
| /** |
| * Get the copy of the policy array. |
| */ |
| public Policy[] getPolicyArray() |
| { |
| Policy[] r = new Policy[ s_policies.length ]; |
| for (int i = 0; i < s_policies.length; i++) |
| { |
| r [ i ] = s_policies [ i ].copy(); |
| } |
| return r; |
| } |
| |
| /** |
| * The POAs cannot be created by this method. |
| * |
| * @specnote this is also not possible in Suns jdk at least till 1.4. |
| * |
| * @throws NO_IMPLEMENT always. |
| */ |
| public org.omg.CORBA.Object _set_policy_override(Policy[] policies, |
| SetOverrideType how |
| ) |
| { |
| throw new NO_IMPLEMENT("Use createPOA instead."); |
| } |
| |
| /** |
| * Get the ORB, where this POA is connected. |
| */ |
| public ORB orb() |
| { |
| return m_orb; |
| } |
| |
| /** |
| * Connect the given delegate under the given key, also calling incarnate. |
| */ |
| private void create_and_connect(byte[] object_key, String repository_id, |
| ServantDelegateImpl delegate) |
| { |
| aom.add(delegate); |
| connect_to_orb(object_key, getReferenceFactory().make_object(repository_id, |
| object_key)); |
| if (servant_activator != null) |
| incarnate(null, object_key, delegate.servant, false); |
| } |
| |
| /** |
| * Check if the POA is not in a discarding mode. The activation |
| * operations are forbidded in discarding mode. |
| * |
| * @throws TRANSIENT if the POA is in discarding mode. |
| */ |
| private void checkDiscarding() |
| throws TRANSIENT |
| { |
| if (m_manager.get_state() == State.DISCARDING) |
| throw new TRANSIENT("Discarding mode", 1, CompletionStatus.COMPLETED_MAYBE); |
| } |
| |
| /** |
| * Connect the given delegate object to orb. |
| */ |
| protected void connect_to_orb(byte[] an_Object_Id, org.omg.CORBA.Object object) |
| { |
| if (applies(ThreadPolicyValue.SINGLE_THREAD_MODEL)) |
| m_orb.connect_1_thread(object, toIORKey(an_Object_Id), this); |
| else |
| m_orb.connect(object, toIORKey(an_Object_Id)); |
| } |
| |
| /** |
| * Returns the representation of this POA tree. |
| */ |
| public String toString() |
| { |
| StringBuffer b = new StringBuffer(name); |
| |
| if (children.size() != 0) |
| { |
| b.append(" ("); |
| |
| for (int i = 0; i < children.size(); i++) |
| { |
| b.append(children.get(i)); |
| if (i < children.size() - 2) |
| b.append(", "); |
| } |
| b.append(")"); |
| } |
| return b.toString(); |
| } |
| |
| /** |
| * Check if the policy set is valid. |
| */ |
| protected boolean validatePolicies(Policy[] a) |
| throws InvalidPolicy |
| { |
| if (applies(ServantRetentionPolicyValue.NON_RETAIN)) |
| { |
| if (!applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) && |
| !applies(RequestProcessingPolicyValue.USE_SERVANT_MANAGER) |
| ) |
| { |
| short p = 0; |
| for (short i = 0; i < a.length; i++) |
| { |
| if (a [ i ].policy_type() == SERVANT_RETENTION_POLICY_ID.value) |
| p = i; |
| } |
| throw new InvalidPolicy("NON_RETAIN requires either " + |
| "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER", |
| p |
| ); |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Recursively searches for the given object in the POA tree. |
| */ |
| public AOM.Obj findObject(org.omg.CORBA.Object object) |
| { |
| AOM.Obj h = aom.findObject(object); |
| if (h != null) |
| return h; |
| else |
| { |
| for (int i = 0; i < children.size(); i++) |
| { |
| h = ((gnuPOA) children.get(i)).findObject(object); |
| if (h != null) |
| return h; |
| } |
| } |
| return h; |
| } |
| |
| /** |
| * Recursively searches for the given key in the POA tree. |
| * @param ior_key the key, ecapsulating both object |
| * and poa ids. |
| * @return |
| */ |
| public AOM.Obj findKey(byte[] object_id, byte[] poa_id) |
| { |
| AOM.Obj h = null; |
| if (Arrays.equals(poa_id, id())) |
| h = aom.get(object_id); |
| if (h != null) |
| return h; |
| else |
| { |
| for (int i = 0; i < children.size(); i++) |
| { |
| h = ((gnuPOA) children.get(i)).findKey(object_id, poa_id); |
| if (h != null) |
| return h; |
| } |
| } |
| return h; |
| } |
| |
| /** |
| * Parses the given key, extracts poa and object id and searches |
| * for such reference. |
| */ |
| public AOM.Obj findIorKey(byte[] ior_key) |
| { |
| BufferredCdrInput in = new BufferredCdrInput(ior_key); |
| int signature = in.read_long(); |
| if (signature != SIGNATURE) |
| return null; |
| |
| byte[] id = in.read_sequence(); |
| byte[] poa = in.read_sequence(); |
| return findKey(id, poa); |
| } |
| |
| /** |
| * Converts the object Id into the IOR key. IOR key must be |
| * unique in the scope of the ORB, and Ids only in the scope of POA. |
| * Hence the IOR key includes the POA identifiers. |
| */ |
| public byte[] toIORKey(byte[] object_id) |
| { |
| BufferedCdrOutput buffer = new BufferedCdrOutput(); |
| buffer.write_long(SIGNATURE); |
| buffer.write_sequence(object_id); |
| buffer.write_sequence(id()); |
| return buffer.buffer.toByteArray(); |
| } |
| |
| /** |
| * Extracts the object id from the ior key. |
| * |
| * @param ior_key |
| * |
| * @return the encapsulated object ior key or null if |
| * this ior key either refers a different POA or encoding signature |
| * mismatch. |
| */ |
| public byte[] idFormIor(byte[] ior_key) |
| { |
| BufferredCdrInput in = new BufferredCdrInput(ior_key); |
| int signature = in.read_long(); |
| if (signature != SIGNATURE) |
| return null; |
| |
| byte[] object_id = in.read_sequence(); |
| byte[] poa_id = in.read_sequence(); |
| if (Arrays.equals(poa_id, id())) |
| return object_id; |
| else |
| return null; |
| } |
| |
| /** |
| * Recursively searches for the given servant in the POA tree. |
| */ |
| public AOM.Obj findServant(Servant servant) |
| { |
| AOM.Obj h = aom.findServant(servant); |
| if (h != null) |
| return h; |
| else |
| { |
| for (int i = 0; i < children.size(); i++) |
| { |
| h = ((gnuPOA) children.get(i)).findServant(servant); |
| if (h != null) |
| return h; |
| } |
| } |
| return h; |
| } |
| |
| /** |
| * Get the object reference template of this POA. |
| * Instantiate a singleton instance, if required. |
| */ |
| public ObjectReferenceTemplate getReferenceTemplate() |
| { |
| if (refTemplate == null) |
| refTemplate = new RefTemplate(); |
| |
| return refTemplate; |
| } |
| |
| public ObjectReferenceFactory getReferenceFactory() |
| { |
| return m_object_factory; |
| } |
| |
| public void setReferenceFactory(ObjectReferenceFactory factory) |
| { |
| m_object_factory = factory; |
| } |
| |
| /** |
| * Create the object (needed by the factory interface). |
| */ |
| public Object make_object(String a_repository_id, byte[] an_object_id) |
| { |
| AOM.Obj existing = aom.get(an_object_id); |
| // The object may already exist. In this case, it is just returned. |
| if (existing != null && existing.object != null) |
| return existing.object; |
| else |
| { |
| return new gnuServantObject(new String[] { a_repository_id }, |
| an_object_id, this, m_orb); |
| } |
| } |
| |
| /** |
| * Required by object reference factory ops. |
| */ |
| public String[] _truncatable_ids() |
| { |
| return ref_template_ids; |
| } |
| } |