diff options
Diffstat (limited to 'libjava/classpath/gnu/CORBA/Poa')
25 files changed, 6723 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/CORBA/Poa/AOM.java b/libjava/classpath/gnu/CORBA/Poa/AOM.java new file mode 100644 index 000000000..4b2264f3c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/AOM.java @@ -0,0 +1,406 @@ +/* AOM.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 gnu.CORBA.ByteArrayComparator; + +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.Servant; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Implements the conception of the Active Object Map. + * If the POA supports the RETAIN policy, it maintains an Active + * Object Map, that associates Object Ids with active servants. + * Each association constitutes an active object. We use a single map + * for all POAs on the given orb. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class AOM +{ + /** + * The reference data about the object, placed on the AOM. + */ + public class Obj + { + /** + * Create an initialised instance. + */ + Obj(gnuServantObject _object, byte[] _key, Servant _servant, gnuPOA _poa) + { + object = _object; + key = _key; + servant = _servant; + poa = _poa; + } + + /** + * The object. + */ + public final gnuServantObject object; + + /** + * The servant, serving the given object. + */ + public Servant servant; + + /** + * The local servant that once served this object. + * This field is used by {@link ForwardedServant} when it discovers that + * the forwarding chaing returns back to the original location. + * It should not be used anywhere else. + */ + Servant primary_servant; + + /** + * The POA, where the object is connected. + */ + public final gnuPOA poa; + + /** + * The object key. + */ + public final byte[] key; + + /** + * If true, this entry is deactivated. + */ + public boolean deactivated; + + /** + * Set the servant value, preserving any non null + * value as the primary servant. + */ + public void setServant(Servant s) + { + if (primary_servant == null) + primary_servant = s; + servant = s; + } + + /** + * Get the servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Get the deactivation state. + */ + public boolean isDeactiveted() + { + return deactivated; + } + + /** + * Set the deactivation state. + */ + public void setDeactivated(boolean state) + { + deactivated = state; + } + } + + /** + * The free number to give for the next instance. + * This field is incremented each time the + * new collection of the connected objects is created. + * Each collection has its own unique instance number. + */ + private static long free_id; + + /** + * The map of the all connected objects, maps the object key to the + * object. + */ + Map objects = new TreeMap(new ByteArrayComparator()); + + /** + * Get the record of the stored object. If the object is mapped several times + * under the different keys, one of the mappings is used. + * + * @param stored_object the stored object + * + * @return the record about the stored object, null if this object is not + * stored here. + */ + public Obj findObject(org.omg.CORBA.Object stored_object) + { + if (stored_object == null) + return null; + + Map.Entry item; + Iterator iter; + Obj ref; + + if (stored_object instanceof ObjectImpl) + { + // If the delegate is available, search by delegate. + Delegate d = ((ObjectImpl) stored_object)._get_delegate(); + Delegate d2; + + if (d != null) + { + iter = objects.entrySet().iterator(); + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + d2 = ref.object._get_delegate(); + + if (d == d2 || (d2 != null && d2.equals(d))) + return ref; + } + } + } + + // For other objects (or if not possible to get the delegate), + // search by .equals + iter = objects.entrySet().iterator(); + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (stored_object.equals(ref.object)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. If the servant is mapped to + * several objects, this returns the first found occurence. + * + * @param servant a servant to find. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. + * If the servant is mapped to several objects, this + * returns the first found occurence. + * + * @param servant a servant to find. + * @param speficies if to search for the inactive (true) or active + * (false) servant. A servant with unmatching activity is ignored + * by this method. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant, boolean inactive) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (ref.deactivated == inactive) + if (ref.servant != null) + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Add the new object to the repository. The object key is + * generated automatically. + * + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the poa, where the object is connected. + * + * @return the newly created object record. + */ + public Obj add(gnuServantObject object, Servant servant, gnuPOA poa) + { + return add(generateObjectKey(object), object, servant, poa); + } + + /** + * Add the new object to the repository. + * + * @param key the object key. + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the POA, where the object is connected. + */ + public Obj add(byte[] key, gnuServantObject object, Servant servant, + gnuPOA poa + ) + { + Obj rec = new Obj(object, key, servant, poa); + objects.put(key, rec); + return rec; + } + + /** + * Add the new object to the repository. + * + * @param delegate the delegate, providing data about the servant, key, POA + * and object. + * @param port the port that this object would take. + */ + public Obj add(ServantDelegateImpl delegate) + { + Obj rec = + new Obj(delegate.object, delegate.servant_id, delegate.servant, + delegate.poa + ); + objects.put(delegate.servant_id, rec); + return rec; + } + + /** + * Put back the definition structure that has probably been removed earlier. + */ + public void put(Obj obj) + { + objects.put(obj.key, obj); + } + + /** + * Get the stored object. + * + * @param key the key (in the byte array form). + * + * @return the matching object, null if none is matching. + */ + public Obj get(byte[] key) + { + return (Obj) objects.get(key); + } + + /** + * Get the map key set. + */ + public Set keySet() + { + return objects.keySet(); + } + + /** + * Remove the given object, indiciating it by the key. + * + * @param object the object to remove. + */ + public void remove(byte[] key) + { + objects.remove(key); + } + + /** + * Generate the object key, unique in the currently + * running java virtual machine. The passed object + * parameter is currently not in use. + * + * @return the generated key. + */ + protected byte[] generateObjectKey(org.omg.CORBA.Object object) + { + byte[] key; + + // The repetetive keys cannot be generated, but theoretically + // the same keys can be passed when calling add(byte[]...). + // Hence we check if the key is not already in the map and, + // if it is, use the subsequent value. + do + { + key = getFreeId(); + } + while (objects.containsKey(key)); + return key; + } + + /** + * Get the next free 8 byte id, surely unique between calls of this + * method for the currently running virtual machine. + */ + public static synchronized byte[] getFreeId() + { + byte[] r = new byte[ 8 ]; + + // Start from the faster-changing. + r [ 0 ] = ((byte) (0xff & free_id)); + r [ 1 ] = ((byte) (0xff & (free_id >> 8))); + r [ 2 ] = ((byte) (0xff & (free_id >> 16))); + r [ 3 ] = ((byte) (0xff & (free_id >> 24))); + r [ 4 ] = ((byte) (0xff & (free_id >> 32))); + r [ 5 ] = ((byte) (0xff & (free_id >> 40))); + r [ 6 ] = ((byte) (0xff & (free_id >> 48))); + r [ 7 ] = ((byte) (0xff & (free_id >> 56))); + + free_id++; + + return r; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java b/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java new file mode 100644 index 000000000..5468d2292 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java @@ -0,0 +1,62 @@ +/* AccessiblePolicy.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 org.omg.CORBA.Policy; + +/** + * The Classpath implementation of the policy, providing the policy + * value and the code of the policy type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface AccessiblePolicy + extends Policy +{ + /** + * Get the value of this policy + */ + java.lang.Object getValue(); + + /** + * Get the integer code of this policy value. + */ + int getCode(); + +} diff --git a/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java b/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java new file mode 100644 index 000000000..4ee02995d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java @@ -0,0 +1,85 @@ +/* DynamicImpHandler.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 org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.DynamicImplementation; + +/** + * The InvokeHandler, indicating, that the target is a dynamic + * implementation rather than an invoke handler. These two + * types are not substitutable, but in some methods have possibility + * just to handle them differently. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class DynamicImpHandler + implements InvokeHandler +{ + /** + * The servant that is a dynamic implementation rather than + * invoke handler. + */ + public final DynamicImplementation servant; + + /** + * Create a new instance, wrapping some dyn implementation. + * @param _servant + */ + public DynamicImpHandler(DynamicImplementation _servant) + { + servant = _servant; + } + + /** + * We cannot invoke properly without having parameter info. + * + * @throws BAD_OPERATION, always. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + { + throw new BAD_OPERATION(servant + " is not an InvokeHandler."); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java new file mode 100644 index 000000000..a85173526 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java @@ -0,0 +1,107 @@ +/* ForwardRequestHolder.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 gnu.CORBA.ForwardRequestHelper; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableServer.ForwardRequest; + +/** +* A holder for the exception {@link ForwardRequest}. + +* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +*/ +public class ForwardRequestHolder + implements Streamable +{ + /** + * The stored ForwardRequest value. + */ + public ForwardRequest value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public ForwardRequestHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public ForwardRequestHolder(ForwardRequest initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = ForwardRequestHelper.read(input); + } + + /** + * Get the typecode of the ForwardRequest. + */ + public TypeCode _type() + { + return ForwardRequestHelper.type(); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + ForwardRequestHelper.write(output, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java new file mode 100644 index 000000000..c54a02654 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java @@ -0,0 +1,209 @@ +/* ForwardedServant.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 gnu.CORBA.IOR; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.IorObject; +import gnu.CORBA.Minor; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; + +import java.io.IOException; + +/** + * A "virtual servant", delegating all invocation to the wrapped + * object (usually remote). Used in cases when it is necessary to + * handle the request forwarding. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ForwardedServant + extends Servant + implements InvokeHandler +{ + /** + * The reference object, handling requests. + */ + public final ObjectImpl ref; + + /** + * Create an instance, forwarding requests to the given object. + */ + ForwardedServant(ObjectImpl a_ref) + { + ref = a_ref; + } + + /** + * Create an instance of the forwarded servant. + * + * @param a_ref a reference where request should be forwarded. + * + * @return a created forwarded servant or null if the parameter + * forwards request to itself. Returning null will force to find + * a right servant in one of many possible ways, depending on + * policies. + */ + public static Servant create(org.omg.CORBA.Object a_ref) + { + try + { + ObjectImpl fto = (ObjectImpl) a_ref; + + // Check maybe the remote side forwarded back to our local object. + if (fto instanceof IorObject) + { + IorObject iref = (IorObject) fto; + + // Check maybe the IOR is local. + ORB t_orb = iref._orb(); + if (t_orb instanceof ORB_1_4) + { + ORB_1_4 orb = (ORB_1_4) t_orb; + Delegate d = iref._get_delegate(); + if (d instanceof IorDelegate) + { + IorDelegate ird = (IorDelegate) iref._get_delegate(); + IOR ior = ird.getIor(); + if (orb.LOCAL_HOST.equalsIgnoreCase(ior.Internet.host)) + { + AOM.Obj rx = orb.rootPOA.findIorKey(ior.key); + if (rx != null) + { + if (rx.object == fto || + rx.object._is_equivalent(fto) + ) + return rx.primary_servant; + else + fto = (ObjectImpl) rx.object; + } + } + } + } + } + return new ForwardedServant(fto); + } + catch (ClassCastException ex) + { + throw new BAD_PARAM("ObjectImpl required but " + a_ref + " passed ", + 0x5005, CompletionStatus.COMPLETED_NO + ); + } + } + + /** + * Forward the call to the wrapped object. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + throws SystemException + { + org.omg.CORBA.portable.InputStream in = null; + org.omg.CORBA.portable.OutputStream out = null; + try + { + try + { + out = ref._request(method, true); + + // Transfer request information. + int b; + while ((b = input.read()) >= 0) + { + out.write(b); + } + in = ref._invoke(out); + + // Read the returned data. + out = handler.createReply(); + while ((b = in.read()) >= 0) + { + out.write(b); + } + } + catch (IOException io_ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Forwarding; + m.initCause(io_ex); + throw m; + } + } + catch (ApplicationException ex) + { + in = ex.getInputStream(); + + String _id = ex.getId(); + throw new MARSHAL(_id, 5101, CompletionStatus.COMPLETED_NO); + } + catch (RemarshalException remarsh) + { + _invoke(method, input, handler); + } + finally + { + ref._releaseReply(in); + } + return out; + } + + /** + * Delegates to the wrapped object. + */ + public String[] _all_interfaces(POA poa, byte[] key) + { + return ref._ids(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java b/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java new file mode 100644 index 000000000..b415034a3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java @@ -0,0 +1,106 @@ +/* InvalidPolicyHolder.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 org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableServer.POAPackage.InvalidPolicy; +import org.omg.PortableServer.POAPackage.InvalidPolicyHelper; + +/** +* A holder for the exception {@link InvalidPolicy}. + +* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +*/ +public class InvalidPolicyHolder + implements Streamable +{ + /** + * The stored InvalidPolicy value. + */ + public InvalidPolicy value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public InvalidPolicyHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public InvalidPolicyHolder(InvalidPolicy initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = InvalidPolicyHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + InvalidPolicyHelper.write(output, value); + } + + /** + * Get the typecode of the InvalidPolicy. + */ + public TypeCode _type() + { + return InvalidPolicyHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java new file mode 100644 index 000000000..7b42fde1e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java @@ -0,0 +1,385 @@ +/* LocalDelegate.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 gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.StreamBasedRequest; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Request; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; + +import java.util.Arrays; + +/** + * A local delegate, transferring all object requests to the locally available + * servant. This class is involved in handling the method invocations on the + * local object, obtained by POA.create_reference_with_id. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalDelegate + extends org.omg.CORBA_2_3.portable.Delegate + implements IorProvider +{ + /** + * The same servant as an invocation handler. + */ + gnuServantObject object; + + String operation; + + public final gnuPOA poa; + + final byte[] Id; + + /** + * Create a local delegate, forwarding requests to the servant that must also + * be an invocation handler. + */ + public LocalDelegate(gnuServantObject an_object, gnuPOA a_poa, byte[] an_id) + { + object = an_object; + poa = a_poa; + Id = an_id; + } + + /** + * Get the IOR of the connected object. + */ + public IOR getIor() + { + return object.getIor(); + } + + public Request request(org.omg.CORBA.Object target, String method) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq; + } + + public void release(org.omg.CORBA.Object target) + { + } + + public boolean is_equivalent(org.omg.CORBA.Object target, + org.omg.CORBA.Object other) + { + if (target == other) + return true; + else if (target instanceof ObjectImpl && other instanceof ObjectImpl) + { + org.omg.CORBA.portable.Delegate a = null; + org.omg.CORBA.portable.Delegate b = null; + try + { + a = ((ObjectImpl) target)._get_delegate(); + b = ((ObjectImpl) other)._get_delegate(); + } + catch (Exception ex) + { + // Unable to get one of the delegates. + return false; + } + if (a instanceof LocalDelegate && b instanceof LocalDelegate) + { + byte[] k1 = ((LocalDelegate) a).Id; + byte[] k2 = ((LocalDelegate) b).Id; + return Arrays.equals(k1, k2); + } + else + return false; + } + else + return false; + } + + /** + * Always return false. + */ + public boolean non_existent(org.omg.CORBA.Object target) + { + return false; + } + + /** + * Get hash code. + */ + public int hash(org.omg.CORBA.Object target, int maximum) + { + return hashCode() % maximum; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean is_a(org.omg.CORBA.Object a_servant, String idl_id) + { + String[] maybe = object._ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe[i].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return <code>this</code>. + */ + public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target) + { + return target; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns, + ExceptionList exceptions, ContextList ctx_list) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + rq.set_exceptions(exceptions); + rq.set_context_list(ctx_list); + return rq; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + return rq; + } + + /** + * Not in use. + */ + public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target) + { + throw new NO_IMPLEMENT(); + } + + /** + * Create a request to invoke the method of this CORBA object. + * + * @param operation the name of the method to invoke. + * @param response_expected specifies if this is one way message or the + * response to the message is expected. + * + * @return the stream where the method arguments should be written. + */ + public org.omg.CORBA.portable.OutputStream request( + org.omg.CORBA.Object target, String method, boolean response_expected) + { + operation = method; + + // Check if the object is not explicitly deactivated. + AOM.Obj e = poa.aom.get(Id); + if (e != null && e.isDeactiveted()) + { + if (poa.servant_activator != null || poa.servant_locator != null) + { + // This will force the subsequent activation. + object.setServant(null); + e.setServant(null); + e.setDeactivated(false); + } + else + throw new OBJECT_NOT_EXIST("Deactivated"); + } + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq.getParameterStream(); + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String method, CookieHolder cookie) + { + return object.getHandler(method, cookie, false); + } + + /** + * Return the ORB of the associated POA. The parameter is not in use. + */ + public ORB orb(org.omg.CORBA.Object target) + { + return poa.orb(); + } + + /** + * Make an invocation. + * + * @param target not in use. + * @param output the stream request that should be returned by + * {@link #m_request} in this method. + * @throws ApplicationException if the use exception is thrown by the servant + * method. + */ + public InputStream invoke(org.omg.CORBA.Object target, OutputStream output) + throws ApplicationException + { + try + { + StreamBasedRequest sr = (StreamBasedRequest) output; + + LocalRequest lr = (LocalRequest) sr.request; + InvokeHandler handler = lr.object.getHandler(lr.operation(), lr.cookie, + false); + + if (handler instanceof DynamicImpHandler) + { + // The local request known how to handle it, but the different + // method must be called. + lr.invoke(); + + // The encapsulation will inherit orb, endian, charsets, etc. + AbstractCdrOutput buf = sr.createEncapsulation(); + + // Write all request parameters to the buffer stream. + if (lr.env().exception() != null) + { + try + { + UnknownUserException uex = (UnknownUserException) lr.env().exception(); + throw new ApplicationException(uex.except.type().id(), + uex.except.create_input_stream()); + } + catch (BadKind ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + if (lr.return_value() != null) + lr.return_value().write_value(buf); + + NamedValue a; + try + { + for (int i = 0; i < lr.arguments().count(); i++) + { + a = lr.arguments().item(i); + if (a.flags() == ARG_INOUT.value + || a.flags() == ARG_INOUT.value) + { + a.value().write_value(buf); + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + + return buf.create_input_stream(); + } + else + { + LocalRequest lrq = (LocalRequest) sr.request; + return lrq.s_invoke(handler); + } + } + catch (gnuForwardRequest f) + { + try + { + return ((ObjectImpl) f.forward_reference)._invoke(f.forward_reference._request( + operation, true)); + } + catch (RemarshalException e) + { + // Never thrown in this place by Classpath implementation. + throw new NO_IMPLEMENT(); + } + } + } + + public void releaseReply(org.omg.CORBA.Object target, InputStream input) + { + release(target); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java new file mode 100644 index 000000000..ca5b57b00 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java @@ -0,0 +1,687 @@ +/* LocalRequest.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 gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.GIOP.MessageHeader; +import gnu.CORBA.GIOP.v1_2.ReplyHeader; +import gnu.CORBA.GIOP.v1_2.RequestHeader; +import gnu.CORBA.Interceptor.gnuClientRequestInfo; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuAny; +import gnu.CORBA.gnuRequest; +import gnu.CORBA.StreamHolder; +import gnu.CORBA.StreamBasedRequest; + +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +/** + * Directs the invocation to the locally available servant. The POA servant does + * not longer implement the CORBA object and cannot be substituted directly. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalRequest extends gnuRequest implements ResponseHandler, + CurrentOperations +{ + /** + * Used by servant locator, if involved. + */ + CookieHolder cookie; + + /** + * The object Id. + */ + final byte[] Id; + + /** + * The message header (singleton is sufficient). + */ + private static final MessageHeader header = new MessageHeader(); + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise. + */ + boolean exceptionReply; + + /** + * The buffer to write into. + */ + BufferedCdrOutput buffer; + + /** + * The responsible POA. + */ + final gnuPOA poa; + + /** + * The servant delegate to obtain the handler. + */ + gnuServantObject object; + + /** + * Used (reused) with dynamic implementation. + */ + LocalServerRequest serverRequest; + + /** + * Create an instance of the local request. + */ + public LocalRequest(gnuServantObject local_object, gnuPOA a_poa, byte[] an_id) + { + Id = an_id; + poa = a_poa; + + // Instantiate the cookie holder only if required. + if (poa.servant_locator != null) + { + cookie = new CookieHolder(); + } + object = local_object; + prepareStream(); + } + + /** + * Make an invocation and return a stream from where the results can be read + * and throw ApplicationException, where applicable. + */ + org.omg.CORBA.portable.InputStream s_invoke(InvokeHandler handler) + throws ApplicationException + { + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + return input; + } + else + { + input.mark(500); + + String id = input.read_string(); + try + { + input.reset(); + } + catch (IOException ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + throw new ApplicationException(id, input); + } + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + + /** + * Make an invocation and return a stream from where the results can be read. + * + * @param handler the invoke handler (can be null, then it is obtained self + * dependently). + */ + public org.omg.CORBA.portable.InputStream v_invoke(InvokeHandler handler) + { + // Check maybe POA is in the discarding mode (will throw TRANSIENT if it is). + poa.checkDiscarding(); + + // Local request must be intercepted both by server and request + // interceptors. + boolean s_intercept = false; + ServerRequestInterceptorOperations s_interceptor = null; + gnuServerRequestInfo s_info = null; + + boolean c_intercept = false; + ClientRequestInterceptorOperations c_interceptor = null; + gnuClientRequestInfo c_info = null; + + try + { + if (poa.m_orb.iServer != null || poa.m_orb.iClient != null) + { + setORB(poa.m_orb); + + // These two are only needed with interceptors. + m_rqh = new RequestHeader(); + m_rqh.operation = m_operation; + m_rph = new ReplyHeader(); + + m_rqh.object_key = object.Id; + m_rph.request_id = m_rqh.request_id; + } + + if (poa.m_orb.iClient != null) + { + c_interceptor = poa.m_orb.iClient; + + c_info = new gnuClientRequestInfo(this); + c_intercept = true; + + c_interceptor.send_request(c_info); + + m_target = object; + } + + if (poa.m_orb.iServer != null) + { + s_interceptor = poa.m_orb.iServer; + + s_info = new gnuServerRequestInfo(object, m_rqh, m_rph); + s_info.m_request = this; + + s_intercept = true; + + s_interceptor.receive_request_service_contexts(s_info); + } + + if (handler == null) + { + handler = object.getHandler(operation(), cookie, false); + } + + BufferedCdrOutput request_part = new BufferedCdrOutput(); + + request_part.setOrb(orb()); + + if (m_args != null && m_args.count() > 0) + { + write_parameters(header, request_part); + + if (m_parameter_buffer != null) + { + throw new BAD_INV_ORDER("Please either add parameters or " + + "write them into stream, but not both " + "at once." + ); + } + } + + if (m_parameter_buffer != null) + { + write_parameter_buffer(header, request_part); + } + + Servant servant; + + if (handler instanceof Servant) + { + servant = (Servant) handler; + } + else + { + throw new BAD_OPERATION("Unexpected handler type " + handler); + } + + org.omg.CORBA.portable.InputStream input = + request_part.create_input_stream(); + + // Ensure the servant (handler) has a delegate set. + ServantDelegateImpl sd = null; + + Delegate d = null; + + try + { + d = servant._get_delegate(); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof ServantDelegateImpl) + { + // If the delegate is already set, try to reuse the existing + // instance. + sd = (ServantDelegateImpl) d; + if (sd.object != object) + { + sd = new ServantDelegateImpl(servant, poa, Id); + } + } + else + { + sd = new ServantDelegateImpl(servant, poa, Id); + } + servant._set_delegate(sd); + + try + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.put(Thread.currentThread(), this); + } + + try + { + if (s_intercept) + { + s_interceptor.receive_request(s_info); + } + handler._invoke(m_operation, input, this); + + // Handler is casted into i_handler. + if ((s_intercept || c_intercept) && isExceptionReply()) + { + s_info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + m_rph.reply_status = ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = new gnuAny(); + OutputStream buf = getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + m_exception_id = uex_idl; + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, in); + + m_environment.exception(exception); + ObjectCreator.insertWithHelper(a, exception); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new StreamHolder( + buf.create_input_stream() + ) + ); + + RecordTypeCode r = + new RecordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName(uex_idl)); + } + + s_info.m_usr_exception = a; + c_info.m_wrapped_exception = a; + s_interceptor.send_exception(s_info); + c_interceptor.receive_exception(c_info); + } + else + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + s_interceptor.send_reply(s_info); + } + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.NO_EXCEPTION; + c_interceptor.receive_reply(c_info); + } + } + } + catch (SystemException sys_ex) + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + s_info.m_sys_exception = sys_ex; + s_interceptor.send_exception(s_info); + } + + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.SYSTEM_EXCEPTION; + + Any a = new gnuAny(); + if (ObjectCreator.insertSysException(a, sys_ex)) + { + c_info.m_wrapped_exception = a; + } + c_interceptor.receive_exception(c_info); + } + + throw sys_ex; + } + } + finally + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.remove(Thread.currentThread()); + } + } + + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(object.Id, poa, operation(), + cookie.value, object.getServant() + ); + } + return buffer.create_input_stream(); + } + + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward = s_info.m_forward_reference; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward = fex2.forward; + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + // May be thrown during activation. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward_reference; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward_reference; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + throw fex; + } + } + + /** + * Make an invocation and store the result in the fields of this Request. Used + * with DII only. + */ + public void invoke() + { + InvokeHandler handler = object.getHandler(operation(), cookie, false); + + if (handler instanceof DynamicImpHandler) + { + DynamicImplementation dyn = ((DynamicImpHandler) handler).servant; + if (serverRequest == null) + { + serverRequest = new LocalServerRequest(this); + } + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + dyn.invoke(serverRequest); + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + else + { + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + NamedValue arg; + + // Read return value, if set. + if (m_result != null) + { + m_result.value().read_value(input, m_result.value().type()); + } + + // Read returned parameters, if set. + if (m_args != null) + { + for (int i = 0; i < m_args.count(); i++) + { + try + { + arg = m_args.item(i); + + // Both ARG_INOUT and ARG_OUT have this binary flag set. + if ((arg.flags() & ARG_OUT.value) != 0) + { + arg.value().read_value(input, arg.value().type()); + } + } + catch (Bounds ex) + { + Unexpected.error(ex); + } + } + } + } + else// User exception reply + { + // Prepare an Any that will hold the exception. + gnuAny exc = new gnuAny(); + + exc.insert_Streamable(new StreamHolder(input)); + + UnknownUserException unuex = new UnknownUserException(exc); + m_environment.exception(unuex); + } + } + } + + /** + * Get an output stream for providing details about the exception. Before + * returning the stream, the handler automatically writes the message header + * and the reply about exception header, but not the message header. + * + * @return the stream to write exception details into. + */ + public OutputStream createExceptionReply() + { + exceptionReply = true; + prepareStream(); + return buffer; + } + + /** + * Get an output stream for writing a regular reply (not an exception). + * + * Before returning the stream, the handler automatically writes the regular + * reply header, but not the message header. + * + * @return the output stream for writing a regular reply. + */ + public OutputStream createReply() + { + exceptionReply = false; + prepareStream(); + return buffer; + } + + /** + * Get the buffer, normally containing the written reply. The reply includes + * the reply header (or the exception header) but does not include the message + * header. + * + * The stream buffer can also be empty if no data have been written into + * streams, returned by {@link #createReply()} or + * {@link #createExceptionReply()}. + * + * @return the CDR output stream, containing the written output. + */ + BufferedCdrOutput getBuffer() + { + return buffer; + } + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise (usually no-exception reply). + */ + boolean isExceptionReply() + { + return exceptionReply; + } + + /** + * Compute the header offset, set the correct version number and codeset. + */ + private void prepareStream() + { + buffer = new BufferedCdrOutput(); + buffer.setOrb(orb()); + } + + /** + * Get the parameter stream, where the invocation arguments should be written + * if they are written into the stream directly. + */ + public StreamBasedRequest getParameterStream() + { + m_parameter_buffer = new StreamBasedRequest(); + m_parameter_buffer.request = this; + m_parameter_buffer.setOrb(poa.orb()); + return m_parameter_buffer; + } + + public byte[] get_object_id() throws NoContext + { + return Id; + } + + public POA get_POA() throws NoContext + { + return poa; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java new file mode 100644 index 000000000..714e029fe --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java @@ -0,0 +1,199 @@ +/* LocalServerRequest.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 gnu.CORBA.gnuNamedValue; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ServerRequest; +import org.omg.CORBA.UnknownUserException; + +/** + * Used to make local invocations via LocalRequest. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalServerRequest + extends ServerRequest +{ + /** + * The local request, on the base of that this instance is created. + */ + final LocalRequest request; + + /** + * Create a new instance. + */ + public LocalServerRequest(LocalRequest _request) + { + request = _request; + } + + /** + * Get the argument list that can be modified. + */ + public void params(NVList args) + { + arguments(args); + } + + /** + * Get contexts. + */ + public Context ctx() + { + return request.ctx(); + } + + /** + * Get the operatin being performed. + */ + public String operation() + { + return request.operation(); + } + + /** + * Get the argument list that can be modified. + * The direction depends on the size of the passed list. + * The empty list is filled with the request arguments. + * The non-empty list is used to set the request arguments. + */ + public void arguments(NVList args) + { + NVList l = request.arguments(); + NamedValue a; + + try + { + if (args.count() == 0) + { + // Transfer to the passed parameter. + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + args.add_value(a.name(), a.value(), a.flags()); + } + } + else + { + // Transfer from the passed parameter. + if (l.count() != args.count()) + throw new BAD_PARAM("Argument number mismatch, current " + + l.count() + ", passed " + args.count() + ); + try + { + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + if (a.flags() == ARG_INOUT.value || + a.flags() == ARG_OUT.value + ) + { + ((gnuNamedValue) a).setValue(args.item(i).value()); + } + } + } + catch (ClassCastException cex) + { + InternalError ierr = new InternalError(); + ierr.initCause(cex); + throw ierr; + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + + /** + * Set the result. + */ + public void set_result(Any result) + { + gnuNamedValue g = new gnuNamedValue(); + g.setValue(result); + g.setFlags(ARG_OUT.value); + request.set_result(g); + } + + /** + * Get the name of the method being called. + */ + public String op_name() + { + return request.operation(); + } + + /** + * Set the exception that has been thrown. + */ + public void set_exception(Any exc) + { + request.env().exception(new UnknownUserException(exc)); + } + + /** + * Set the result. + */ + public void result(Any r) + { + set_result(r); + } + + /** + * Set the exception. + */ + public void except(Any exc) + { + set_exception(exc); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java new file mode 100644 index 000000000..360537e2c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java @@ -0,0 +1,293 @@ +/* ORB_1_4.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 gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; +import gnu.CORBA.Connected_objects.cObject; +import gnu.CORBA.DynAn.gnuDynAnyFactory; +import gnu.CORBA.Interceptor.ClientRequestInterceptors; +import gnu.CORBA.Interceptor.IORInterceptors; +import gnu.CORBA.Interceptor.Registrator; +import gnu.CORBA.Interceptor.ServerRequestInterceptors; +import gnu.CORBA.Interceptor.gnuIcCurrent; +import gnu.CORBA.Interceptor.gnuIorInfo; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Policy; +import org.omg.CORBA.PolicyError; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.PolicyFactory; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.POAPackage.InvalidPolicy; + +import java.applet.Applet; +import java.util.Properties; + +/** + * The ORB, supporting POAs that are the feature of jdk 1.4. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ORB_1_4 + extends OrbFunctional +{ + /** + * The root POA. + */ + public final gnuPOA rootPOA; + + /** + * Maps the active threads to the invocation data ("POA Current's"). + */ + public gnuPoaCurrent currents = new gnuPoaCurrent(); + + /** + * Maps the active threads to the interceptor data ("Interceptor Current's"). + */ + public gnuIcCurrent ic_current = new gnuIcCurrent(this); + + /** + * Creates dynamic anys. + */ + public gnuDynAnyFactory factory = new gnuDynAnyFactory(this); + + /** + * Calls the parent constructor and additionally puts the "RootPOA", + * "RootPOAManager", "POACurrent" and "DynAnyFactory" into initial references. + */ + public ORB_1_4() + { + super(); + try + { + rootPOA = new gnuPOA(null, "RootPOA", null, StandardPolicies.rootPoa(), this); + } + catch (InvalidPolicy ex) + { + // Invalid default policy set. + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + initial_references.put("RootPOA", rootPOA); + initial_references.put("RootPOAManager", rootPOA.the_POAManager()); + initial_references.put("POACurrent", currents); + initial_references.put("DynAnyFactory", factory); + initial_references.put("PICurrent", ic_current); + } + + /** + * If the super method detects that the object is not connected to this ORB, + * try to find and activate the object. + */ + public String object_to_string(org.omg.CORBA.Object forObject) + { + try + { + return super.object_to_string(forObject); + } + catch (Exception ex) + { + try + { + AOM.Obj exists = rootPOA.findObject(forObject); + if (exists == null) + throw new OBJECT_NOT_EXIST(forObject == null ? "null" + : forObject.toString()); + else if (exists.poa instanceof gnuPOA) + ((gnuPOA) exists.poa).connect_to_orb(exists.key, forObject); + else + exists.poa.create_reference_with_id(exists.key, + ((ObjectImpl) exists.object)._ids()[0]); + } + catch (Exception bex) + { + BAD_PARAM bad = new BAD_PARAM("Unable to activate " + forObject); + bad.initCause(bex); + throw bad; + } + + return super.object_to_string(forObject); + } + } + + /** + * Destroy all poas and then call the superclass method. + */ + public void destroy() + { + // This will propagate through the whole POA tree. + rootPOA.destroy(true, false); + + super.destroy(); + } + + /** + * Do interceptor registration. + * + * @param properties the properties, between those names the agreed prefix + * "org.omg.PortableInterceptor.ORBInitializerClass." is searched. + * + * @param args the string array, passed to the ORB.init + */ + protected void registerInterceptors(Properties properties, String[] args) + { + Registrator registrator = new Registrator(this, properties, args); + + policyFactories = registrator.m_policyFactories; + + registrator.pre_init(); + initial_references.putAll(registrator.getRegisteredReferences()); + registrator.post_init(); + + if (registrator.hasIorInterceptors()) + iIor = new IORInterceptors(registrator); + + if (registrator.hasServerRequestInterceptors()) + iServer = new ServerRequestInterceptors(registrator); + + if (registrator.hasClientRequestInterceptors()) + iClient = new ClientRequestInterceptors(registrator); + + policyFactories = registrator.m_policyFactories; + } + + /** + * Create IOR and allow registered interceptors to add additional components. + */ + protected IOR createIOR(cObject ref) + throws BAD_OPERATION + { + IOR ior = super.createIOR(ref); + if (iIor != null) + { + AOM.Obj obj = rootPOA.findIorKey(ior.key); + + gnuPOA poa; + + // Null means that the object was connected to the ORB directly. + if (obj == null) + poa = rootPOA; + else + poa = obj.poa; + + gnuIorInfo info = new gnuIorInfo(this, poa, ior); + + // This may modify the ior. + iIor.establish_components(info); + iIor.components_established(info); + } + return ior; + } + + /** + * Create policy using the previously registered factory. + */ + public Policy create_policy(int type, Any value) + throws PolicyError + { + Integer policy = new Integer(type); + + PolicyFactory forge = (PolicyFactory) policyFactories.get(policy); + if (forge == null) + throw new PolicyError("No factory registered for policy " + type, + (short) type); + else + return forge.create_policy(type, value); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(Applet app, Properties props) + { + super.set_parameters(app, props); + registerInterceptors(props, new String[0]); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(String[] para, Properties props) + { + super.set_parameters(para, props); + registerInterceptors(props, para); + } + + /** + * This method is called by RMI-IIOP {@link javax.rmi.Tie#orb(ORB)}, passing + * <code>this</code> as parameter. The ORB will try to connect that tie as + * one of its objects, if it is not already connected. If the wrapper is an + * instance of Servant this method also activates the root poa (if not already + * active). + */ + public void set_delegate(java.lang.Object wrapper) + { + if (wrapper instanceof org.omg.CORBA.Object) + { + org.omg.CORBA.Object object = (org.omg.CORBA.Object) wrapper; + if (connected_objects.getKey(object) == null) + connect(object); + } + else if (wrapper instanceof Servant) + { + Servant s = (Servant) wrapper; + if (rootPOA.findServant(s) == null) + try + { + rootPOA.servant_to_reference(s); + if (rootPOA.the_POAManager().get_state().value() == State._HOLDING) + rootPOA.the_POAManager().activate(); + } + catch (Exception e) + { + BAD_OPERATION bad = new BAD_OPERATION("Unable to connect " + + wrapper + " to " + this); + throw bad; + } + } + } + +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java b/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java new file mode 100644 index 000000000..2123a1c9c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java @@ -0,0 +1,232 @@ +/* ServantDelegateImpl.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 gnu.CORBA.Unexpected; + +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.Object; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAHelper; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.portable.Delegate; + +/** + * The implementation of the servant delegate for the locally existing + * servant.The associated servant that must also implement the + * {@link InvokeHandler} interface. Each servant requires a separate + * instance of this delegate and can serve a single object only. + * Hence the fields are final, but the delegate is typically reused + * unless the same servant is connected to different objects. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ServantDelegateImpl + implements Delegate +{ + /** + * The servant, associated with this object. + */ + final Servant servant; + + /** + * The servant (not object) id. + */ + final byte[] servant_id; + + /** + * The POA, where the servant is connected. + */ + final gnuPOA poa; + + /** + * The object, exposed as an object, served by this servant. + */ + final gnuServantObject object; + + /** + * Create the delegat for the servant that will be connected to the + * given poa. The method is normally called from inside of gnuPOA. + * The constructor sets the newly created delegate as the delegate to this + * servant by calling Servant._set_delegate. + * + * @param a_poa the poa. + * @param a_servant the servant. + * @param a_servant_id the servant id. + */ + public ServantDelegateImpl(Servant a_servant, gnuPOA a_poa, byte[] a_servant_id) + { + poa = a_poa; + servant = a_servant; + servant_id = a_servant_id; + servant._set_delegate(this); + object = + new gnuServantObject(servant, servant_id, (ORB_1_4) servant._orb(), a_poa); + object._set_delegate(new LocalDelegate(object, poa, a_servant_id)); + } + + /** + * Check if this object could be named by the given repository id. + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this + * object. + */ + public boolean is_a(Servant a_servant, String idl_id) + { + same(a_servant); + + String[] maybe = object.repository_ids; + if (maybe == null) + maybe = servant._all_interfaces(poa, object.Id); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return the ORB's default POA. + */ + public POA default_POA(Servant a_servant) + { + same(a_servant); + try + { + return POAHelper.narrow(orb(a_servant).resolve_initial_references("RootPOA")); + } + catch (InvalidName ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get ORB. + */ + public ORB orb(Servant a_servant) + { + same(a_servant); + return poa.orb(); + } + + /** + * Get the object, exposing the servant. + */ + public Object this_object(Servant a_servant) + { + same(a_servant); + try + { + return poa.aom.get(poa.m_orb.currents.get_object_id()).object; + } + catch (NoContext ex) + { + return object; + } + } + + /** + * Not supported. + * + * @specnote Same as for Sun up till 1.5 inclusive. + */ + public Object get_interface_def(Servant a_servant) + { + same(a_servant); + throw new NO_IMPLEMENT(); + } + + /** + * Get the Id of the object being currently served. + */ + public byte[] object_id(Servant a_servant) + { + same(a_servant); + try + { + byte[] id = poa.m_orb.currents.get_object_id(); + return id; + } + catch (NoContext ex) + { + return object.Id; + } + } + + /** + * Always returns false; + */ + public boolean non_existent(Servant a_servant) + { + same(a_servant); + return false; + } + + /** + * Return the associated POA. + */ + public POA poa(Servant a_servant) + { + same(a_servant); + try + { + return poa.m_orb.currents.get_POA(); + } + catch (NoContext ex) + { + return poa; + } + } + + /** + * Checks if the passed servant is the same as the servant, associated with + * this delegate. This class requires a single servant per delegate. + */ + void same(Servant some_servant) + { + if (servant != some_servant) + throw new InternalError("Only one servant per delegate is supported."); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java b/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java new file mode 100644 index 000000000..6b84031f1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java @@ -0,0 +1,128 @@ +/* StandardPolicies.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 org.omg.CORBA.Policy; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.ThreadPolicyValue; + +import java.util.ArrayList; + +/** + * Contains the frequently uset POA policy sets. The policy + * arrays are package private for security reasons, the cloned + * copies are returned. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class StandardPolicies +{ + /** + * The default policy set, as defined in OMG specs. This is also + * the policy set for the root POA. + */ + private static final AccessiblePolicy[] rootPOASet = + new AccessiblePolicy[] + { + new gnuThreadPolicy(ThreadPolicyValue.ORB_CTRL_MODEL), + new gnuLifespanPolicy(LifespanPolicyValue.TRANSIENT), + new gnuIdUniquenessPolicy(IdUniquenessPolicyValue.UNIQUE_ID), + new gnuIdAssignmentPolicy(IdAssignmentPolicyValue.SYSTEM_ID), + new gnuServantRetentionPolicy(ServantRetentionPolicyValue.RETAIN), + new gnuRequestProcessingPolicy(RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY), + new gnuImplicitActivationPolicy(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + }; + + /** + * Return the policy set, applicable for the root POA, as defined + * in OMG specs. + */ + public static Policy[] rootPoa() + { + Policy[] p = new Policy[ rootPOASet.length ]; + System.arraycopy(rootPOASet, 0, p, 0, p.length); + return p; + } + + /** + * Convert the potentially incomplete policy array into array, containing + * the complete policy set. + * + * @param policies the policy list, may be incomplete (even zero size). + * + * @return the complete policy array. The missing, but needed policies + * are added with they default values. + */ + public static Policy[] withDefault(Policy[] policies) + { + ArrayList current = new ArrayList(rootPOASet.length); + Policy p_default; + boolean specified; + + for (int i = 0; i < rootPOASet.length; i++) + { + p_default = rootPOASet [ i ]; + specified = false; + ForThis: + for (int j = 0; j < policies.length; j++) + { + if (policies [ j ].policy_type() == p_default.policy_type()) + { + specified = true; + current.add(policies [ j ]); + break ForThis; + } + } + if (!specified) + current.add(p_default.copy()); + } + + Policy[] complete = new Policy[ current.size() ]; + for (int i = 0; i < complete.length; i++) + { + complete [ i ] = (Policy) current.get(i); + } + return complete; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java new file mode 100644 index 000000000..fc64e6bb1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java @@ -0,0 +1,81 @@ +/* gnuAdapterActivator.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 org.omg.CORBA.LocalObject; +import org.omg.PortableServer.AdapterActivator; +import org.omg.PortableServer.POA; + +/** + * Defines a simple adapter activator. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuAdapterActivator + extends LocalObject + implements AdapterActivator +{ + /** + * Create a new POA on the parent, using the parent policy set + * from the suitable parent of grandparend and with independent + * POA manager (passing null to the createPOA). + * + * @param parent a parent. Either this parent or one of its + * grandparents must be gnuAbstractPOA, able to provide a + * policy set. + * + * @param child_name the name of the child being created. + * + * @return true on success or false if no gnuAbstractPOA + * found till the root poa. + */ + public boolean unknown_adapter(POA parent, String child_name) + { + try + { + POA n = parent.create_POA(child_name, null, StandardPolicies.rootPoa()); + n.the_POAManager().activate(); + } + catch (Exception ex) + { + return false; + } + return true; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java new file mode 100644 index 000000000..01c6cccd5 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java @@ -0,0 +1,90 @@ +/* gnuForwardRequest.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 gnu.CORBA.GIOP.ReplyHeader; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * The class, indicating that the request should be forwarded to another + * target. We cannot use ForwardRequest because the exception is throws + * from methods that does not declare throwing it. Hence must be + * RuntimeException. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuForwardRequest + extends RuntimeException +{ + /** + * Use serialVersionUID (v1.4) for interoperability. + */ + private static final long serialVersionUID = -1L; + + /** + * The object reference, indicating the new location of the invocation target. + */ + public ObjectImpl forward_reference; + + /** + * This information shows if we use LOCATION_FORWARD or + * LOCATION_FORWARD_PERM in request. By defalult, LOCATION_FORWARD + * is always used. To use LOCATION_FORWARD_PERM, this exception should + * be thrown from the servant manager instead of ForwardRequest, + * with this field set to ReplyHeader.LOCATION_FORWARD_PERM. + */ + public byte forwarding_code = ReplyHeader.LOCATION_FORWARD; + + /** + * Create the ForwardRequest with explaining message and + * initialising the object reference to the given value. + * + * @param why a string, explaining, why this exception has been thrown. + * @param a_forward_reference a value for forward_reference. + */ + public gnuForwardRequest(org.omg.CORBA.Object a_forward_reference) + { + if (a_forward_reference instanceof ObjectImpl) + this.forward_reference = (ObjectImpl) a_forward_reference; + else + throw new BAD_PARAM("ObjectImpl expected"); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java new file mode 100644 index 000000000..1234abce6 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdAssignmentPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; +import org.omg.PortableServer.IdAssignmentPolicy; +import org.omg.PortableServer.IdAssignmentPolicyValue; + +/** + * Implementation of the id assignment policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdAssignmentPolicy + extends _PolicyImplBase + implements IdAssignmentPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdAssignmentPolicy(IdAssignmentPolicyValue v) + { + super(ID_ASSIGNMENT_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdAssignmentPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdAssignmentPolicyValue value() + { + return (IdAssignmentPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java new file mode 100644 index 000000000..21d8c54c4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdUniquenessPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID; +import org.omg.PortableServer.IdUniquenessPolicy; +import org.omg.PortableServer.IdUniquenessPolicyValue; + +/** + * Implementation of the id uniqueness policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdUniquenessPolicy + extends _PolicyImplBase + implements IdUniquenessPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdUniquenessPolicy(IdUniquenessPolicyValue v) + { + super(ID_UNIQUENESS_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdUniquenessPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdUniquenessPolicyValue value() + { + return (IdUniquenessPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java new file mode 100644 index 000000000..96ce42708 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java @@ -0,0 +1,80 @@ +/* gnuImplicitActivationPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID; +import org.omg.PortableServer.ImplicitActivationPolicy; +import org.omg.PortableServer.ImplicitActivationPolicyValue; + +/** + * Implementation of the implicit activation policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuImplicitActivationPolicy + extends _PolicyImplBase + implements ImplicitActivationPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuImplicitActivationPolicy(ImplicitActivationPolicyValue v) + { + super(IMPLICIT_ACTIVATION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ImplicitActivationPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ImplicitActivationPolicyValue value() + { + return (ImplicitActivationPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java new file mode 100644 index 000000000..6efb9d603 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java @@ -0,0 +1,80 @@ +/* gnuLifespanPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.LIFESPAN_POLICY_ID; +import org.omg.PortableServer.LifespanPolicy; +import org.omg.PortableServer.LifespanPolicyValue; + +/** + * The implementation of the life span policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuLifespanPolicy + extends _PolicyImplBase + implements LifespanPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuLifespanPolicy(LifespanPolicyValue v) + { + super(LIFESPAN_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/LifespanPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public LifespanPolicyValue value() + { + return (LifespanPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java new file mode 100644 index 000000000..5d323305a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java @@ -0,0 +1,1817 @@ +/* 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 gnu.java.lang.CPStringBuilder; + +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 a_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 object_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 an_activator 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. + */ + 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() + { + CPStringBuilder b = new CPStringBuilder(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; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java new file mode 100644 index 000000000..db43751a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java @@ -0,0 +1,272 @@ +/* gnuPOAManager.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 org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.LocalObject; +import org.omg.PortableInterceptor.NON_EXISTENT; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.AdapterInactive; +import org.omg.PortableServer.POAManagerPackage.State; + +import java.util.HashSet; +import java.util.Iterator; + +/** + * The implementation of the POA manager. The manager is a controlled + * switch that can change its states in response to the method calls + * and throw exceptions if the requested change is invalid. It is possible + * to check the state this switch. It does not do anything else. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPOAManager + extends LocalObject + implements POAManager +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The POAs, controlled by this manager. + */ + private HashSet POAs = new HashSet(); + + /** + * The state of the manager. The newly created manager is always + * in the holding state. + */ + State state = State.HOLDING; + + /** + * Get the state of the POA manager. + */ + public State get_state() + { + return state; + } + + /** + * Turns the associated POAs into active state, allowing them to receive + * and process requests. + * + * @throws AdapterInactive if the POAs are in the inactive state. + * If once inactivated, the POA cannot be activated again. This + * method can only be called to leave the holding or discarding state. + */ + public void activate() + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.ACTIVE; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + } + + /** + * Turns the associated POAs into holding state. In this state, the POAs + * queue incoming requests but do not process them. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void hold_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.HOLDING; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + } + + /** + * + * Turns the asociated POAs into inactive state. The POAs in the incative + * state will reject new requests. If the POA is once inactivated, it + * cannot be activated again. The operation is used when + * the associated POAs are to be shut down. + * + * @param etherealize_objects if true, the servant managers of the + * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies, + * will receive a call of {@link ServantActivatorOperations#etherealize}. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + * + * @throws AdapterInactive if the POAs are already in the inactive state. + * + * @see POAOperations#destroy + */ + public void deactivate(boolean etherealize_objects, + boolean wait_for_completion + ) + throws AdapterInactive + { + if (state == State.INACTIVE) + throw new AdapterInactive("Repetetive inactivation"); + state = State.INACTIVE; + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + + Iterator iter = POAs.iterator(); + while (iter.hasNext()) + { + gnuPOA poa = (gnuPOA) iter.next(); + + // If the servant activator is non null, this means it has been + // set - hence the policies are appropriate. + if (poa.servant_activator != null) + poa.etherealizeAll(); + } + } + + /** + * Turns the associated POAs into discaring state. In this state, the POAs + * discard the incoming requests. This mode is used in situations when + * the server is flooded with requests. The client receives remote exception + * ({@link org.omg.CORBA.TRANSIENT}, minor code 1). + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void discard_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.DISCARDING; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + } + + /** + * Suspend the current thread while at least one of the associated POA is + * actively processing some requests. The method assumes that the POAs + * are not accepting the <i>new</i> requests due manager state. + * + * @throws BAD_INV_ORDER if the POAs are in the active state. + */ + public void waitForIdle() + { + if (state == State.ACTIVE) + throw new BAD_INV_ORDER("The state is active"); + + gnuPOA poa; + Iterator iter = POAs.iterator(); + + while (iter.hasNext()) + { + poa = (gnuPOA) iter.next(); + poa.waitWhileRunning(); + } + } + + /** + * Add the POA that will be controlled by this manager. + * + * @param poa the POA. + */ + public void addPoa(gnuPOA poa) + { + POAs.add(poa); + } + + /** + * Remove the POA, releasing it from the control of this manager. + * Called in POA finaliser. + * + * @param poa the POA to remove. + */ + public void removePOA(gnuPOA poa) + { + POAs.remove(poa); + } + + /** + * This method is called when POA is destryed. The interceptors are + * notified. + */ + public void poaDestroyed(gnuPOA poa) + { + notifyInterceptors(NON_EXISTENT.value); + } + + /** + * Notify CORBA 3.0 interceptors about the status change. + */ + public synchronized void notifyInterceptors(int new_state) + { + gnuPOA poa; + Iterator iter = POAs.iterator(); + + // The System.identityHashCode is also called in gnuIorInfo. + while (iter.hasNext()) + { + poa = (gnuPOA) iter.next(); + if (poa.m_orb.iIor != null) + { + poa.m_orb.iIor.adapter_manager_state_changed( + System.identityHashCode(this), (short) new_state); + } + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java new file mode 100644 index 000000000..d489d0e83 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java @@ -0,0 +1,179 @@ +/* gnuPoaCurrent.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 org.omg.CORBA.CurrentHelper; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.Current; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; + +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +/** + * Supports the "Poa current" concept, providing the id and poa of + * the object currently being served. There is only one instance + * of this class per ORB. It maintains a thread to information map. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPoaCurrent + extends ObjectImpl + implements Current +{ + /** + * The table, mapping threads to records. + */ + private TreeMap threads = new TreeMap(); + + /** + * Get the array of POA current repository ids. + * + * @return a single member array, containing value, returned + * by the {@link CurrentHelper#id}, normally + * "IDL:omg.org/PortableServer/Current:2.3". + */ + public String[] _ids() + { + return new String[] { CurrentHelper.id() }; + } + + /** + * Get the object id, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public byte[] get_object_id() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_object_id(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Get the object POA, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public POA get_POA() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_POA(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Add the entry to the map. + */ + public void put(Thread t, CurrentOperations record) + { + synchronized (threads) + { + threads.put(t.getName(), record); + } + } + + /** + * Check if this Poa has some running threads. + */ + public boolean has(POA poa) + { + synchronized (threads) + { + Iterator iter = threads.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry item = (Map.Entry) iter.next(); + try + { + if (((CurrentOperations) item.getValue()).get_POA() == poa) + { + return true; + } + } + catch (NoContext ex) + { + throw new InternalError(); + } + } + } + return false; + } + + /** + * Check if this thread is registered. + */ + public boolean has(Thread t) + { + synchronized (threads) + { + return threads.containsKey(t.getName()); + } + } + + /** + * Remove the entry from the map. + */ + public void remove(Thread t) + { + synchronized (threads) + { + threads.remove(t.getName()); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java new file mode 100644 index 000000000..4e322e5e2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java @@ -0,0 +1,80 @@ +/* gnuRequestProcessingPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID; +import org.omg.PortableServer.RequestProcessingPolicy; +import org.omg.PortableServer.RequestProcessingPolicyValue; + +/** + * The implementation of the request processing policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuRequestProcessingPolicy + extends _PolicyImplBase + implements RequestProcessingPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuRequestProcessingPolicy(RequestProcessingPolicyValue v) + { + super(REQUEST_PROCESSING_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/RequestProcessingPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public RequestProcessingPolicyValue value() + { + return (RequestProcessingPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java new file mode 100644 index 000000000..17ef452a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java @@ -0,0 +1,825 @@ +/* gnuServantObject.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 gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.IorObject; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.Minor; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.ResponseHandlerImpl; +import gnu.CORBA.StreamHolder; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TRANSIENT; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +import java.util.Arrays; + +/** + * Represents a CORBA object, being locally served by the associated servant. + * The calls to the object are forwarded to the calls to the servant. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantObject extends ObjectImpl + implements org.omg.CORBA.Object, + InvokeHandler, + CurrentOperations, + IorProvider +{ + /** + * The associated servant that must also implement the {@link InvokeHandler} + * interface. This value can be temporary null if the object was created using + * POA.create_reference or POA.create_reference_with_id, private to force + * always to use {@link setServant}. + */ + private Servant servant; + + /** + * The Id of this object. + */ + public final byte[] Id; + + /** + * The poa that takes care about this object. + */ + public final gnuPOA poa; + + /** + * The POA manager, used to control the work of this object. + */ + public final POAManager manager; + + /** + * The orb. + */ + public final ORB_1_4 orb; + + /** + * The object repository ids, if they were specified separately. Normally, the + * ids are requested from the servant. + */ + public final String[] repository_ids; + + /** + * True indicates that the NO_RETAIN policy applies for the servant. + * The servant must be discarded after the each call. + */ + boolean noRetain; + + /** + * Create an object with no connected servant. The servant must be set later. + * + * @param a_repository_ids an array of repository ids, can be null (then ids + * will be requested from the servant). + * @param an_id the object id. + * @param a_poa the POA. + */ + public gnuServantObject(String[] a_repository_ids, byte[] an_id, + gnuPOA a_poa, ORB_1_4 an_orb + ) + { + repository_ids = a_repository_ids; + Id = an_id; + manager = a_poa.the_POAManager(); + poa = a_poa; + orb = an_orb; + + noRetain = poa.applies(ServantRetentionPolicyValue.NON_RETAIN); + } + + /** + * Get the IOR as it would be for this object. + */ + public IOR getIor() + { + return orb.getLocalIor(this); + } + + /** + * Create a servant object, associated with the passed servant. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler}. + */ + public gnuServantObject(Servant a_servant, byte[] an_id, ORB_1_4 an_orb, + gnuPOA a_poa + ) + { + Id = an_id; + setServant(a_servant); + poa = a_poa; + if (poa != null) + { + manager = poa.the_POAManager(); + } + else + { + manager = null; + } + repository_ids = null; + orb = an_orb; + + noRetain = poa != null && poa.applies(ServantRetentionPolicyValue.NON_RETAIN); + } + + /** + * Set a servant, if it has not been previously set. + * + * @param a_servant a servant to set, can be null to indicate the necessity + * for the subsequent activation. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler} or + * {@link DynamicImplementation} and also not null. + */ + public void setServant(Servant a_servant) + { + if (a_servant != null && + !(a_servant instanceof InvokeHandler) && + !(a_servant instanceof DynamicImplementation) + ) + { + throw new BAD_PARAM("Must be either InvokeHandler or " + + "DynamicImplementation, but is " + a_servant + ); + } + servant = a_servant; + } + + /** + * Returns the associated servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String operation, CookieHolder cookie, + boolean forwarding_allowed + ) throws gnuForwardRequest + { + if (servant != null && !noRetain) + { + return servantToHandler(servant); + } + else + { + // Use servant locator to locate the servant. + if (poa.servant_locator != null) + { + try + { + servant = + poa.servant_locator.preinvoke(Id, poa, operation, cookie); + return servantToHandler(servant); + } + catch (org.omg.PortableServer.ForwardRequest forw_ex) + { + if (forwarding_allowed) + { + throw new gnuForwardRequest(forw_ex.forward_reference); + } + else + { + servant = + ForwardedServant.create(forw_ex.forward_reference); + return servantToHandler(servant); + } + } + } + else + // Use servant activator to locate the servant. + if (poa.applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) && + poa.applies(ServantRetentionPolicyValue.RETAIN) + ) + { + try + { + poa.activate_object_with_id(Id, servant, forwarding_allowed); + servant = poa.id_to_servant(Id); + return servantToHandler(servant); + } + catch (gnuForwardRequest forwarded) + { + throw forwarded; + } + catch (Exception ex) + { + BAD_OPERATION bad = + new BAD_OPERATION("Unable to activate", Minor.Activation, + CompletionStatus.COMPLETED_NO + ); + bad.initCause(ex); + throw bad; + } + } + else if (poa.default_servant != null) + { + servant = poa.default_servant; + return servantToHandler(servant); + } + + // No servant and no servant manager - throw exception. + else + { + throw new BAD_OPERATION("Unable to activate", Minor.Activation, + CompletionStatus.COMPLETED_NO + ); + } + } + } + + /** + * Convert the servant to invocation handler. + */ + public InvokeHandler servantToHandler(Servant a_servant) + { + if (a_servant instanceof InvokeHandler) + { + return (InvokeHandler) a_servant; + } + else if (a_servant instanceof DynamicImplementation) + { + return new DynamicImpHandler((DynamicImplementation) a_servant); + } + else + { + throw new BAD_OPERATION(a_servant + + " must be either InvokeHandler or " + "POA DynamicImplementation" + ); + } + } + + /** + * Create a servant object, associated with the passed servant. Requests the + * object id from the servant. Depending on the policies of the servants POA, + * the calls are eithe not synchronized or synchronized on POA or ORB. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + */ + public gnuServantObject(Servant a_servant, gnuPOA a_poa) + { + this(a_servant, a_servant._object_id(), (ORB_1_4) a_servant._orb(), a_poa); + } + + /** + * Delegates call to servant, passing the poa and Id. + */ + public String[] _ids() + { + if (repository_ids == null) + { + return getServant()._all_interfaces(poa, Id); + } + else + { + return repository_ids; + } + } + + /** + * Gets a string representation. + */ + public String toString() + { + CPStringBuilder b = new CPStringBuilder("Servant object ("); + for (int i = 0; i < Id.length; i++) + { + b.append(Integer.toHexString(Id [ i ] & 0xFF)); + b.append(' '); + } + b.append(')'); + return b.toString(); + } + + /** + * Always returns true. + */ + public boolean _is_local() + { + return true; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean _is_a(String idl_id) + { + String[] maybe = _ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + { + return true; + } + } + return false; + } + + /** + * Get an ORB, associated with the servant of this object. + * + * @return + */ + public ORB _orb() + { + return getServant()._orb(); + } + + /** + * Handle the invocation (delegates to servant). + * + * @throws TRANSIENT minor 0x535503e9 if the POA is in discarding mode. + * @throws OBJ_ADAPTER minor 0x535503ea if the POA is inactivated. + * @throws OBJECT_NOT_EXISTS minor 0x535503ec if this object is inactivated. + * + * @specnote see {@link POAManagerOperations} for specnotes about the minor + * codes. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler r_handler + ) throws SystemException + { + boolean intercept = false; + ServerRequestInterceptorOperations interceptor = null; + gnuServerRequestInfo info = null; + ResponseHandlerImpl i_handler = null; + + try + { + if (orb.iServer != null && + r_handler instanceof ResponseHandlerImpl + ) + { + interceptor = orb.iServer; + + i_handler = (ResponseHandlerImpl) r_handler; + + info = + new gnuServerRequestInfo(this, i_handler.request_header, + i_handler.reply_header + ); + intercept = true; + + interceptor.receive_request_service_contexts(info); + } + + try + { + CookieHolder cookie = null; + AOM.Obj self = poa.aom.get(Id); + + if (poa.servant_locator != null) + { + // If the servant locator is in use, it is always responsible + // for providing the servant. + self.servant = servant = null; + cookie = new CookieHolder(); + } + else if (self != null && self.isDeactiveted()) + { + if (poa.applies( + ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION + ) && + poa.servant_activator != null + ) + { + // Reset the servant, forcing the subsequent activation. + servant = null; + } + else + { + throw new OBJECT_NOT_EXIST("Object deactivated", + 0x535503ec, CompletionStatus.COMPLETED_NO + ); + } + } + + InvokeHandler handler = getHandler(method, cookie, true); + + Delegate d = null; + + try + { + d = servant._get_delegate(); + orb.currents.put(Thread.currentThread(), this); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof ServantDelegateImpl) + { + // If the delegate is already set, check maybe we can + // reuse the existing instance. + if (((ServantDelegateImpl) d).object != this) + { + servant._set_delegate(new ServantDelegateImpl(servant, poa, Id)); + } + } + else + { + servant._set_delegate(new ServantDelegateImpl(servant, poa, Id)); + } + + try + { + switch (manager.get_state().value()) + { + case State._ACTIVE : + + OutputStream rt; + try + { + if (intercept) + { + interceptor.receive_request(info); + } + + rt = handler._invoke(method, input, r_handler); + + if (intercept) + { + // Handler is casted into i_handler. + if (i_handler.isExceptionReply()) + { + info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = orb.create_any(); + OutputStream buf = i_handler.getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, + in + ); + + ObjectCreator.insertWithHelper(a, + exception + ); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new StreamHolder( + buf.create_input_stream() + ) + ); + + RecordTypeCode r = + new RecordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName( + uex_idl + ) + ); + } + + info.m_usr_exception = a; + interceptor.send_exception(info); + } + else + { + info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + interceptor.send_reply(info); + } + } + } + catch (SystemException sys_ex) + { + if (intercept) + { + info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + info.m_sys_exception = sys_ex; + interceptor.send_exception(info); + } + throw sys_ex; + } + + return rt; + + case State._HOLDING : + + // The holding mode is implemented + // relying on the holding capabilites of the network + // support (if any). + // TODO FIXME in more recent CORBA applications, the + // client + // ORB can free the connection and wait for a server side + // notification about the completed request. Implement + // this + // as soon as JDK specification would allow bidirectional + // policy. + int sleep = 5; + int max = 500; + + // Wait till the state will be switched into some other + // mode. + while (manager.get_state().value() == State._HOLDING) + { + try + { + Thread.sleep(sleep); + if (sleep < max) + { + sleep = max; + } + } + catch (InterruptedException ex) + { + } + } + + // Handle another mode. + return _invoke(method, input, r_handler); + + case State._DISCARDING : + throw new TRANSIENT("Discarding mode", 0x535503e9, + CompletionStatus.COMPLETED_NO + ); + + case State._INACTIVE : + throw new OBJ_ADAPTER("POA deactivated", 0x535503ea, + CompletionStatus.COMPLETED_NO + ); + + default : + throw new InternalError(); // No more states. + } + } + finally + { + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(Id, poa, method, + cookie.value, servant + ); + } + } + } + finally + { + orb.currents.remove(Thread.currentThread()); + if (noRetain) + servant = null; + } + } + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward = info.m_forward_reference; + } + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward_reference; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + throw fex; + } + } + + /** + * Compare with another object for equality, comparing the object keys. + */ + public boolean equals(java.lang.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject o = (gnuServantObject) other; + + return Arrays.equals(o.Id, Id); + } + else + { + return false; + } + } + + /** + * Get the hash code, based on the object key. + */ + public int hashCode() + { + long s = 0; + int v = 1; + for (int i = 0; i < Id.length; i++) + { + s += Id [ i ] * v; + if (s > Integer.MAX_VALUE) + { + s = s % Integer.MAX_VALUE; + v = 1; + } + v = v * 8; + } + return (int) (s % Integer.MAX_VALUE); + } + + /** + * Get the object id. + */ + public byte[] get_object_id() + { + return Id; + } + + /** + * Get POA. + */ + public POA get_POA() + { + return poa; + } + + /** + * Returns without action. + */ + public void _release() + { + } + + /** + * Returns without action. + */ + public void _releaseReply(InputStream stream) + { + } + + /** + * Checks if this object is equivalent to another instance. These objects are + * assumed equal if they are connected to the same orb and poa under the same + * Id, regardless of they delegates. + * + * @param other instance to check. + * @return + */ + public boolean _is_equivalent(org.omg.CORBA.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject g = (gnuServantObject) other; + return orb == g.orb && poa == g.poa && Arrays.equals(Id, g.Id); + } + else if (other instanceof IorObject) + { + IorObject ir = ((IorObject) other); + try + { + IorDelegate ird = (IorDelegate) ir._get_delegate(); + byte[] ior_id = poa.idFormIor(ird.getIor().key); + if (ior_id != null && Arrays.equals(ior_id, Id)) + { + return true; + } + else + { + return false; + } + } + catch (Exception ex) + { + // Non - typical delegate or very specific subclass of + // IOR_constructed_object. + return super._is_equivalent(other); + } + } + return super._is_equivalent(other); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java new file mode 100644 index 000000000..95958d299 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java @@ -0,0 +1,80 @@ +/* gnuServantRetentionPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.ServantRetentionPolicy; +import org.omg.PortableServer.ServantRetentionPolicyValue; + +/** + * The implementation of the servant retention policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantRetentionPolicy + extends _PolicyImplBase + implements ServantRetentionPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuServantRetentionPolicy(ServantRetentionPolicyValue v) + { + super(SERVANT_RETENTION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ServantRetentionPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ServantRetentionPolicyValue value() + { + return (ServantRetentionPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java new file mode 100644 index 000000000..e7dac0f6a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java @@ -0,0 +1,80 @@ +/* gnuThreadPolicy.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 gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.THREAD_POLICY_ID; +import org.omg.PortableServer.ThreadPolicy; +import org.omg.PortableServer.ThreadPolicyValue; + +/** + * The implementation of the thread policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuThreadPolicy + extends _PolicyImplBase + implements ThreadPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuThreadPolicy(ThreadPolicyValue v) + { + super(THREAD_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ThreadPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ThreadPolicyValue value() + { + return (ThreadPolicyValue) getValue(); + } +} |