aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/CORBA
diff options
context:
space:
mode:
authorTom Tromey <tromey@gcc.gnu.org>2005-09-23 21:31:04 +0000
committerTom Tromey <tromey@gcc.gnu.org>2005-09-23 21:31:04 +0000
commit1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06 (patch)
tree3ca4b2e68dc14c3128b9c781d23f1d0b1f2bee49 /libjava/classpath/gnu/CORBA
parent9b044d19517541c95681d35a92dbc81e6e21d94f (diff)
downloadgcc-1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06.zip
gcc-1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06.tar.gz
gcc-1ea63ef8be1cc54dd0de9d82c684713a1dcf1e06.tar.bz2
Imported Classpath 0.18.
* sources.am, Makefile.in: Updated. * Makefile.am (nat_source_files): Removed natProxy.cc. * java/lang/reflect/natProxy.cc: Removed. * gnu/classpath/jdwp/VMFrame.java, gnu/classpath/jdwp/VMIdManager.java, gnu/classpath/jdwp/VMVirtualMachine.java, java/lang/reflect/VMProxy.java: New files. 2005-09-23 Thomas Fitzsimmons <fitzsim@redhat.com> * scripts/makemake.tcl (verbose): Add gnu/java/awt/peer/qt to BC list. 2005-09-23 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/java/net/DefaultContentHandlerFactory.java (getContent): Remove ClasspathToolkit references. 2005-09-23 Thomas Fitzsimmons <fitzsim@redhat.com> * gnu/awt/xlib/XCanvasPeer.java: Add new peer methods. * gnu/awt/xlib/XFramePeer.java: Likewise. * gnu/awt/xlib/XGraphicsConfiguration.java: Likewise. 2005-09-23 Thomas Fitzsimmons <fitzsim@redhat.com> * Makefile.am (libgcjawt_la_SOURCES): Remove jawt.c. Add classpath/native/jawt/jawt.c. * Makefile.in: Regenerate. * jawt.c: Remove file. * include/Makefile.am (tool_include__HEADERS): Remove jawt.h and jawt_md.h. Add ../classpath/include/jawt.h and ../classpath/include/jawt_md.h. * include/Makefile.in: Regenerate. * include/jawt.h: Regenerate. * include/jawt_md.h: Regenerate. From-SVN: r104586
Diffstat (limited to 'libjava/classpath/gnu/CORBA')
-rw-r--r--libjava/classpath/gnu/CORBA/CDR/Vio.java186
-rw-r--r--libjava/classpath/gnu/CORBA/CDR/cdrInput.java3
-rw-r--r--libjava/classpath/gnu/CORBA/CDR/cdrOutput.java12
-rw-r--r--libjava/classpath/gnu/CORBA/Connected_objects.java63
-rw-r--r--libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java7
-rw-r--r--libjava/classpath/gnu/CORBA/ExceptionCreator.java9
-rw-r--r--libjava/classpath/gnu/CORBA/Functional_ORB.java809
-rw-r--r--libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java27
-rw-r--r--libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java39
-rw-r--r--libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java138
-rw-r--r--libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java4
-rw-r--r--libjava/classpath/gnu/CORBA/IOR.java351
-rw-r--r--libjava/classpath/gnu/CORBA/IOR_Delegate.java343
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java82
-rw-r--r--libjava/classpath/gnu/CORBA/ObjectCreator.java195
-rw-r--r--libjava/classpath/gnu/CORBA/Restricted_ORB.java135
-rw-r--r--libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java37
-rw-r--r--libjava/classpath/gnu/CORBA/Simple_delegate.java33
-rw-r--r--libjava/classpath/gnu/CORBA/SocketRepository.java22
-rw-r--r--libjava/classpath/gnu/CORBA/bufferedResponseHandler.java88
-rw-r--r--libjava/classpath/gnu/CORBA/fixedTypeCode.java14
-rw-r--r--libjava/classpath/gnu/CORBA/gnuAny.java94
-rw-r--r--libjava/classpath/gnu/CORBA/gnuCodecFactory.java21
-rw-r--r--libjava/classpath/gnu/CORBA/gnuRequest.java668
-rw-r--r--libjava/classpath/gnu/CORBA/holderFactory.java123
-rw-r--r--libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java78
-rw-r--r--libjava/classpath/gnu/CORBA/primitiveTypeCode.java69
-rw-r--r--libjava/classpath/gnu/CORBA/typeNamer.java13
-rw-r--r--libjava/classpath/gnu/CORBA/universalHolder.java23
29 files changed, 2564 insertions, 1122 deletions
diff --git a/libjava/classpath/gnu/CORBA/CDR/Vio.java b/libjava/classpath/gnu/CORBA/CDR/Vio.java
index 8f17bd2..0a37132 100644
--- a/libjava/classpath/gnu/CORBA/CDR/Vio.java
+++ b/libjava/classpath/gnu/CORBA/CDR/Vio.java
@@ -46,6 +46,7 @@ import org.omg.CORBA.DataOutputStream;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.StringSeqHelper;
+import org.omg.CORBA.portable.BoxedValueHelper;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.Streamable;
@@ -55,6 +56,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
+import java.lang.reflect.Method;
+
/**
* A specialised class for reading and writing the value types.
*
@@ -222,7 +225,7 @@ public abstract class Vio
throw new MARSHAL("Unable to instantiate the value type");
else
{
- read_instance(input, ox, value_tag);
+ read_instance(input, ox, value_tag, null);
return (Serializable) ox;
}
}
@@ -285,7 +288,7 @@ public abstract class Vio
}
}
- read_instance(input, ox, value_tag);
+ read_instance(input, ox, value_tag, null);
return (Serializable) ox;
}
catch (Exception ex)
@@ -301,17 +304,22 @@ public abstract class Vio
* an instance.
*
* @param input a stream to read from.
- * @param value_instance an instance of the value.
+ *
+ * @param value_instance an pre-created instance of the value. If the
+ * helper is not null, this parameter is ignored an should be null.
+ *
+ * @param helper a helper to create an instance and read the object-
+ * specific part of the record. If the value_instance is used instead,
+ * this parameter should be null.
*
* @return the loaded value.
*
* @throws MARSHAL if the reading has failed due any reason.
*/
- public static Serializable read(InputStream input, Serializable value_instance)
+ public static Object read(InputStream input, Object value_instance,
+ Object helper
+ )
{
- // Explicitly prevent the stream from closing as we may need
- // to read the subsequent bytes as well. Stream may be auto-closed
- // in its finalizer.
try
{
int value_tag = input.read_long();
@@ -345,8 +353,9 @@ public abstract class Vio
}
}
- read_instance(input, value_instance, value_tag);
- return (Serializable) value_instance;
+ value_instance =
+ read_instance(input, value_instance, value_tag, helper);
+ return value_instance;
}
catch (Exception ex)
{
@@ -355,18 +364,43 @@ public abstract class Vio
}
/**
+ * Read using provided boxed value helper. This method expects
+ * the full value type header, followed by contents, that are
+ * delegated to the provided helper. It handles null.
+ *
+ * @param input the stream to read from.
+ * @param helper the helper that reads the type-specific part of
+ * the content.
+ *
+ * @return the value, created by the helper, or null if the
+ * header indicates that null was previously written.
+ */
+ public static Serializable read(InputStream input, Object helper)
+ {
+ return (Serializable) read(input, null, helper);
+ }
+
+ /**
* Fill in the instance fields by the data from the input stream.
* The method assumes that the value header, if any, is already
* behind. The information from the stream is stored into the
* passed ox parameter.
*
* @param input an input stream to read from.
- * @param value a value type object, must be either Streamable or
- * CustomMarshal.
+ *
+ * @param value a pre-instantiated value type object, must be either
+ * Streamable or CustomMarshal. If the helper is used, this parameter
+ * is ignored and should be null.
+ *
+ * @param value_tag the tag that must be read previously.
+ * @param helper the helper for read object specific part; may be
+ * null to read in using other methods.
+ *
+ * @return the value that was read.
*/
- public static void read_instance(InputStream input, Object value,
- int value_tag
- )
+ private static Object read_instance(InputStream input, Object value,
+ int value_tag, Object helper
+ )
{
try
{
@@ -377,7 +411,7 @@ public abstract class Vio
// Read all chunks.
int chunk_size = input.read_long();
- if (chunk_size <= 0)
+ if (chunk_size < 0)
throw new MARSHAL("Invalid first chunk size " + chunk_size);
byte[] r = new byte[ chunk_size ];
@@ -412,12 +446,29 @@ public abstract class Vio
// More than one chunk was present.
// Add the last chunk.
bout.write(r, 0, n);
- input = new cdrBufInput(bout.toByteArray());
+ input = new noHeaderInput(bout.toByteArray());
}
else
{
// Only one chunk was present.
- input = new cdrBufInput(r);
+ input = new noHeaderInput(r);
+ }
+ }
+ else
+ {
+ if (input instanceof cdrBufInput)
+ {
+ // Highly probable case.
+ input =
+ new noHeaderInput(((cdrBufInput) input).buffer.getBuffer());
+ }
+ else
+ {
+ cdrBufOutput bout = new cdrBufOutput();
+ int c;
+ while ((c = input.read()) >= 0)
+ bout.write((byte) c);
+ input = new noHeaderInput(bout.buffer.toByteArray());
}
}
}
@@ -447,12 +498,17 @@ public abstract class Vio
{
((Streamable) value)._read(input);
}
+ else if (helper instanceof BoxedValueHelper)
+ value = ((BoxedValueHelper) helper).read_value(input);
+ else if (helper instanceof ValueFactory)
+ value =
+ ((ValueFactory) helper).read_value((org.omg.CORBA_2_3.portable.InputStream) input);
else
// Stating the interfaces that the USER should use.
throw new MARSHAL("The " + value.getClass().getName() +
- " must implement either StreamableValue or CustomValue."
- );
+ " must implement either StreamableValue or CustomValue."
+ );
// The negative end of state marker is expected from OMG standard.
// If the chunking is used, this marker is already extracted.
@@ -462,6 +518,8 @@ public abstract class Vio
if (eor >= 0)
throw new MARSHAL("End of state marker has an invalid value " + eor);
}
+
+ return value;
}
/**
@@ -504,8 +562,8 @@ public abstract class Vio
* @throws MARSHAL if the writing failed due any reason.
*/
public static void write(OutputStream output, Serializable value,
- Class substitute
- )
+ Class substitute
+ )
{
// Write null if this is a null value.
if (value == null)
@@ -527,7 +585,35 @@ public abstract class Vio
if (value == null)
output.write_long(vt_NULL);
else
- write_instance(output, value, id);
+ write_instance(output, value, id, null);
+ }
+
+ /**
+ * Write standard value type header, followed by contents, produced
+ * by the boxed value helper.
+ *
+ * @param output the stream to write to.
+ * @param value the value to write, can be null.
+ * @param helper the helper that writes the value content if it is
+ * not null.
+ */
+ public static void write(OutputStream output, Serializable value,
+ Object helper
+ )
+ {
+ if (value == null)
+ output.write_long(vt_NULL);
+ else
+ {
+ String id;
+
+ if (helper instanceof BoxedValueHelper)
+ id = ((BoxedValueHelper) helper).get_id();
+ else
+ id = "";
+
+ write_instance(output, value, id, helper);
+ }
}
/**
@@ -537,10 +623,12 @@ public abstract class Vio
* @param output an output stream to write into.
* @param value a value to write.
* @param id a value repository id.
+ * @param helper a helper, writing object - specifica part. Can be null
+ * if the value should be written unsing other methods.
*/
private static void write_instance(OutputStream output, Serializable value,
- String id
- )
+ String id, Object helper
+ )
{
// This implementation always writes a single repository id.
// It never writes multiple repository ids and currently does not use
@@ -563,6 +651,11 @@ public abstract class Vio
output.write_long(value_tag);
output.write_string(id);
+ if (helper instanceof BoxedValueHelper)
+ {
+ ((BoxedValueHelper) helper).write_value(outObj, value);
+ }
+ else
// User defince write method is present.
if (value instanceof CustomMarshal)
{
@@ -580,11 +673,36 @@ public abstract class Vio
((Streamable) value)._write(outObj);
}
else
+ {
+ // Try to find helper via class loader.
+ boolean ok = false;
+ try
+ {
+ Class helperClass = Class.forName(ObjectCreator.toHelperName(id));
+
+ // It will be the helper for the encapsulated boxed value, not the
+ // for the global boxed value type itself.
+ Method write =
+ helperClass.getMethod("write",
+ new Class[]
+ {
+ org.omg.CORBA.portable.OutputStream.class, value.getClass()
+ }
+ );
+ write.invoke(null, new Object[] { outObj, value });
+ ok = true;
+ }
+ catch (Exception ex)
+ {
+ ok = false;
+ }
- // Stating the interfaces that the USER should use.
- throw new MARSHAL("The " + value.getClass().getName() +
- " must implement either StreamableValue or CustomValue."
- );
+ // Stating the interfaces that the USER should use.
+ if (!ok)
+ throw new MARSHAL("The " + value.getClass().getName() +
+ " must implement either StreamableValue" + " or CustomValue."
+ );
+ }
if (USE_CHUNKING)
{
@@ -611,8 +729,7 @@ public abstract class Vio
*
* @throws NO_IMPLEMENT, always.
*/
- private static void incorrect_plug_in(Throwable ex)
- throws NO_IMPLEMENT
+ static void incorrect_plug_in(Throwable ex) throws NO_IMPLEMENT
{
NO_IMPLEMENT no = new NO_IMPLEMENT("Incorrect CORBA plug-in");
no.initCause(ex);
@@ -629,10 +746,11 @@ public abstract class Vio
private static final void checkTag(int value_tag)
{
if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff) &&
- value_tag != vt_NULL && value_tag != vt_INDIRECTION
- )
+ value_tag != vt_NULL &&
+ value_tag != vt_INDIRECTION
+ )
throw new MARSHAL("Invalid value record, unsupported header tag: " +
- value_tag
- );
+ value_tag
+ );
}
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java b/libjava/classpath/gnu/CORBA/CDR/cdrInput.java
index 859f93a..69f9c8c 100644
--- a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java
+++ b/libjava/classpath/gnu/CORBA/CDR/cdrInput.java
@@ -1180,7 +1180,8 @@ public abstract class cdrInput
}
// Discard the null terminator and, if needed, the endian marker.
- return new String(s, p, n - nt - p);
+ String r = new String(s, p, n - nt - p);
+ return r;
}
catch (EOFException ex)
{
diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java
index 86ca3b1..85f341c 100644
--- a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java
+++ b/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java
@@ -41,6 +41,7 @@ package gnu.CORBA.CDR;
import gnu.CORBA.BigDecimalHelper;
import gnu.CORBA.GIOP.CharSets_OSF;
import gnu.CORBA.GIOP.cxCodeSet;
+import gnu.CORBA.Poa.gnuServantObject;
import gnu.CORBA.IOR;
import gnu.CORBA.Simple_delegate;
import gnu.CORBA.TypeCodeHelper;
@@ -99,7 +100,7 @@ public abstract class cdrOutput
/**
* The GIOP version.
*/
- protected Version giop = new Version(1, 0);
+ protected Version giop = new Version(1, 2);
/**
* The code set information.
@@ -327,6 +328,15 @@ public abstract class cdrOutput
IOR.write_null(this);
return;
}
+ else if (x instanceof gnuServantObject)
+ {
+ // The ORB may be different if several ORBs coexist
+ // in the same machine.
+ gnuServantObject g = (gnuServantObject) x;
+ IOR ior = g.orb.getLocalIor(x);
+ ior._write_no_endian(this);
+ return;
+ }
else if (x instanceof ObjectImpl)
{
Delegate d = ((ObjectImpl) x)._get_delegate();
diff --git a/libjava/classpath/gnu/CORBA/Connected_objects.java b/libjava/classpath/gnu/CORBA/Connected_objects.java
index 30d15e7..b7eefb1 100644
--- a/libjava/classpath/gnu/CORBA/Connected_objects.java
+++ b/libjava/classpath/gnu/CORBA/Connected_objects.java
@@ -60,11 +60,14 @@ public class Connected_objects
/**
* Create an initialised instance.
*/
- cObject(org.omg.CORBA.Object _object, int _port, byte[] _key)
+ cObject(org.omg.CORBA.Object _object, int _port, byte[] _key,
+ java.lang.Object an_identity
+ )
{
object = _object;
port = _port;
key = _key;
+ identity = an_identity;
}
/**
@@ -82,6 +85,12 @@ public class Connected_objects
*/
public final byte[] key;
+ /**
+ * The shared serving identity (usually POA) or null if no such
+ * applicable.
+ */
+ public final java.lang.Object identity;
+
public boolean equals(java.lang.Object other)
{
if (other instanceof cObject)
@@ -118,17 +127,23 @@ public class Connected_objects
*/
public cObject getKey(org.omg.CORBA.Object stored_object)
{
- Map.Entry item;
- Iterator iter = objects.entrySet().iterator();
- cObject ref;
-
- while (iter.hasNext())
+ synchronized (objects)
{
- item = (Map.Entry) iter.next();
- ref = (cObject) item.getValue();
- if (stored_object.equals(ref.object))
- return ref;
+ Map.Entry item;
+ Iterator iter = objects.entrySet().iterator();
+ cObject ref;
+
+ while (iter.hasNext())
+ {
+ item = (Map.Entry) iter.next();
+ ref = (cObject) item.getValue();
+ if (stored_object.equals(ref.object) ||
+ stored_object._is_equivalent(ref.object)
+ )
+ return ref;
+ }
}
+
return null;
}
@@ -144,7 +159,7 @@ public class Connected_objects
*/
public cObject add(org.omg.CORBA.Object object, int port)
{
- return add(generateObjectKey(object), object, port);
+ return add(generateObjectKey(object), object, port, null);
}
/**
@@ -155,10 +170,15 @@ public class Connected_objects
* @param port the port, on that the ORB will be listening on the
* remote invocations.
*/
- public cObject add(byte[] key, org.omg.CORBA.Object object, int port)
+ public cObject add(byte[] key, org.omg.CORBA.Object object, int port,
+ java.lang.Object identity
+ )
{
- cObject rec = new cObject(object, port, key);
- objects.put(key, rec);
+ cObject rec = new cObject(object, port, key, identity);
+ synchronized (objects)
+ {
+ objects.put(key, rec);
+ }
return rec;
}
@@ -171,12 +191,14 @@ public class Connected_objects
*/
public cObject get(byte[] key)
{
- return (cObject) objects.get(key);
+ synchronized (objects)
+ {
+ return (cObject) objects.get(key);
+ }
}
/**
* Get the map entry set.
- * @return
*/
public Set entrySet()
{
@@ -190,9 +212,12 @@ public class Connected_objects
*/
public void remove(org.omg.CORBA.Object object)
{
- cObject ref = getKey(object);
- if (ref != null)
- objects.remove(ref.key);
+ synchronized (objects)
+ {
+ cObject ref = getKey(object);
+ if (ref != null)
+ objects.remove(ref.key);
+ }
}
/**
diff --git a/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java
index 7afc81c..2558f53 100644
--- a/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java
+++ b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java
@@ -46,9 +46,8 @@ import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.Streamable;
/**
- * The name-value pair holder. The {@link NameValuePair} has no standard
- * holder defined, but it is needed to store the {@link NameValuePair} into
- * {@link Any}.
+ * The name-value pair holder. The {@link NameValuePair} has no standard holder
+ * defined, but it is needed to store the {@link NameValuePair} into {@link Any}.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
@@ -92,4 +91,4 @@ public class NameValuePairHolder
{
NameValuePairHelper.write(output, value);
}
-}
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/ExceptionCreator.java b/libjava/classpath/gnu/CORBA/ExceptionCreator.java
index 536053c..8b75205 100644
--- a/libjava/classpath/gnu/CORBA/ExceptionCreator.java
+++ b/libjava/classpath/gnu/CORBA/ExceptionCreator.java
@@ -145,14 +145,11 @@ public class ExceptionCreator
{
try
{
- String holder = toHelperName(idl);
-
- System.out.println("Helper " + holder);
-
- Class holderClass = Class.forName(holder);
+ String helper = toHelperName(idl);
+ Class helperClass = Class.forName(helper);
Method read =
- holderClass.getMethod("read",
+ helperClass.getMethod("read",
new Class[]
{
org.omg.CORBA.portable.InputStream.class
diff --git a/libjava/classpath/gnu/CORBA/Functional_ORB.java b/libjava/classpath/gnu/CORBA/Functional_ORB.java
index 7395f31..1565b2c 100644
--- a/libjava/classpath/gnu/CORBA/Functional_ORB.java
+++ b/libjava/classpath/gnu/CORBA/Functional_ORB.java
@@ -1,4 +1,4 @@
-/* FunctionalORB.java --
+/* Functional_ORB.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,24 +40,28 @@ package gnu.CORBA;
import gnu.CORBA.CDR.cdrBufInput;
import gnu.CORBA.CDR.cdrBufOutput;
+import gnu.CORBA.GIOP.CloseMessage;
import gnu.CORBA.GIOP.ErrorMessage;
import gnu.CORBA.GIOP.MessageHeader;
import gnu.CORBA.GIOP.ReplyHeader;
import gnu.CORBA.GIOP.RequestHeader;
-import gnu.CORBA.GIOP.CloseMessage;
+import gnu.CORBA.NamingService.NameParser;
import gnu.CORBA.NamingService.NamingServiceTransient;
+import gnu.CORBA.Poa.gnuForwardRequest;
-import org.omg.CORBA.BAD_INV_ORDER;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.CompletionStatus;
+import org.omg.CORBA.DATA_CONVERSION;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_RESOURCES;
import org.omg.CORBA.OBJECT_NOT_EXIST;
+import org.omg.CORBA.Object;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CORBA.Request;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.UNKNOWN;
+import org.omg.CORBA.WrongTransaction;
import org.omg.CORBA.portable.Delegate;
import org.omg.CORBA.portable.InvokeHandler;
import org.omg.CORBA.portable.ObjectImpl;
@@ -78,6 +82,7 @@ import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
+import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
@@ -87,26 +92,25 @@ import java.util.TreeMap;
/**
* The ORB implementation, capable to handle remote invocations on the
- * registered object.
+ * registered object. This class implements all features, required till the jdk
+ * 1.3 inclusive, but does not support the POA that appears since 1.4. The POA
+ * is supported by {@link gnu.CORBA.Poa.ORB_1_4}.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
-public class Functional_ORB
- extends Restricted_ORB
+public class Functional_ORB extends Restricted_ORB
{
/**
- * A server, responsible for listening on requests on some
- * local port. The ORB may listen on multiple ports and process
- * the requests in separate threads. Normally the server takes
- * one port per object being served.
+ * A server, responsible for listening on requests on some local port. The ORB
+ * may listen on multiple ports and process the requests in separate threads.
+ * Normally the server takes one port per object being served.
*/
- class portServer
- extends Thread
+ class portServer extends Thread
{
/**
* The number of the currently running parallel threads.
*/
- private int running_threads;
+ int running_threads;
/**
* The port on that this portServer is listening for requests.
@@ -119,8 +123,7 @@ public class Functional_ORB
ServerSocket service;
/**
- * True if the serving node must shutdown due
- * call of the close_now().
+ * True if the serving node must shutdown due call of the close_now().
*/
boolean terminated;
@@ -133,9 +136,8 @@ public class Functional_ORB
}
/**
- * Enter the serving loop (get request/process it).
- * All portServer normally terminate thy threads when
- * the Functional_ORB.running is set to false.
+ * Enter the serving loop (get request/process it). All portServer normally
+ * terminate thy threads when the Functional_ORB.running is set to false.
*/
public void run()
{
@@ -155,7 +157,7 @@ public class Functional_ORB
{
try
{
- serve(this, service);
+ tick();
}
catch (SocketException ex)
{
@@ -180,6 +182,16 @@ public class Functional_ORB
}
/**
+ * Perform a single serving step.
+ *
+ * @throws java.lang.Exception
+ */
+ void tick() throws Exception
+ {
+ serve(this, service);
+ }
+
+ /**
* Forcibly close the server socket and mark this port as free.
*/
public void close_now()
@@ -206,14 +218,41 @@ public class Functional_ORB
}
/**
- * The default value where the first instance of this ORB will start
- * looking for a free port.
+ * A server, responsible for listening on requests on some local port and
+ * serving multiple requests (probably to the different objects) on the same
+ * thread.
+ */
+ class sharedPortServer extends portServer
+ {
+ /**
+ * Create a new portServer, serving on specific port.
+ */
+ sharedPortServer(int _port)
+ {
+ super(_port);
+ }
+
+ /**
+ * Perform a single serving step.
+ *
+ * @throws java.lang.Exception
+ */
+ void tick() throws Exception
+ {
+ Socket request = service.accept();
+ serveStep(request, false);
+ }
+ }
+
+ /**
+ * The default value where the first instance of this ORB will start looking
+ * for a free port.
*/
public static int DEFAULT_INITIAL_PORT = 1126;
/**
- * The property of port, on that this ORB is listening for requests from clients.
- * This class supports one port per ORB only.
+ * The property of port, on that this ORB is listening for requests from
+ * clients. This class supports one port per ORB only.
*/
public static final String LISTEN_ON = "gnu.classpath.CORBA.ListenOn";
@@ -223,12 +262,14 @@ public class Functional_ORB
public static final String REFERENCE = "org.omg.CORBA.ORBInitRef";
/**
- * The property, defining the port on that the default name service is running.
+ * The property, defining the port on that the default name service is
+ * running.
*/
public static final String NS_PORT = "org.omg.CORBA.ORBInitialPort";
/**
- * The property, defining the host on that the default name service is running.
+ * The property, defining the host on that the default name service is
+ * running.
*/
public static final String NS_HOST = "org.omg.CORBA.ORBInitialHost";
@@ -238,24 +279,25 @@ public class Functional_ORB
public static final String NAME_SERVICE = "NameService";
/**
- * The if the client has once opened a socket, it should start sending
- * the message header in a given time. Otherwise the server will close the
- * socket. This prevents server hang when the client opens the socket,
- * but does not send any message, usually due crash on the client side.
+ * The if the client has once opened a socket, it should start sending the
+ * message header in a given time. Otherwise the server will close the socket.
+ * This prevents server hang when the client opens the socket, but does not
+ * send any message, usually due crash on the client side.
*/
public static String START_READING_MESSAGE =
"gnu.classpath.CORBA.TOUT_START_READING_MESSAGE";
/**
- * If the client has started to send the request message, the socket time
- * out changes to the specified value.
+ * If the client has started to send the request message, the socket time out
+ * changes to the specified value.
*/
- public static String WHILE_READING = "gnu.classpath.CORBA.TOUT_WHILE_READING";
+ public static String WHILE_READING =
+ "gnu.classpath.CORBA.TOUT_WHILE_READING";
/**
- * If the message body is received, the time out changes to the
- * specifice value. This must be longer, as includes time, required to
- * process the received task. We make it 40 minutes.
+ * If the message body is received, the time out changes to the specifice
+ * value. This must be longer, as includes time, required to process the
+ * received task. We make it 40 minutes.
*/
public static String AFTER_RECEIVING =
"gnu.classpath.CORBA.TOUT_AFTER_RECEIVING";
@@ -266,60 +308,59 @@ public class Functional_ORB
public final String LOCAL_HOST;
/**
- * The if the client has once opened a socket, it should start sending
- * the message header in a given time. Otherwise the server will close the
- * socket. This prevents server hang when the client opens the socket,
- * but does not send any message, usually due crash on the client side.
+ * The if the client has once opened a socket, it should start sending the
+ * message header in a given time. Otherwise the server will close the socket.
+ * This prevents server hang when the client opens the socket, but does not
+ * send any message, usually due crash on the client side.
*/
private int TOUT_START_READING_MESSAGE = 20 * 1000;
// (Here and below, we use * to make the meaning of the constant clearler).
/**
- * If the client has started to send the request message, the socket time
- * out changes to the specified value.
+ * If the client has started to send the request message, the socket time out
+ * changes to the specified value.
*/
private int TOUT_WHILE_READING = 2 * 60 * 1000;
/**
- * If the message body is received, the time out changes to the
- * specifice value. This must be longer, as includes time, required to
- * process the received task. We make it 40 minutes.
+ * If the message body is received, the time out changes to the specifice
+ * value. This must be longer, as includes time, required to process the
+ * received task. We make it 40 minutes.
*/
private int TOUT_AFTER_RECEIVING = 40 * 60 * 1000;
/**
- * Some clients tend to submit multiple requests over the
- * same socket. The server waits for the next request on
- * the same socket for the duration, specified
- * below. In additions, the request of this implementation also
- * waits for the same duration before closing the socket.
- * The default time is seven seconds.
+ * Some clients tend to submit multiple requests over the same socket. The
+ * server waits for the next request on the same socket for the duration,
+ * specified below. In additions, the request of this implementation also
+ * waits for the same duration before closing the socket. The default time is
+ * seven seconds.
*/
public static int TANDEM_REQUESTS = 7000;
/**
* The map of the already conncted objects.
*/
- protected final Connected_objects connected_objects = new Connected_objects();
+ protected final Connected_objects connected_objects =
+ new Connected_objects();
/**
- * The maximal CORBA version, supported by this ORB. The default value
- * 0 means that the ORB will not check the request version while trying
- * to respond.
+ * The maximal CORBA version, supported by this ORB. The default value 0 means
+ * that the ORB will not check the request version while trying to respond.
*/
protected Version max_version;
/**
- * Setting this value to false causes the ORB to shutdown after the
- * latest serving operation is complete.
+ * Setting this value to false causes the ORB to shutdown after the latest
+ * serving operation is complete.
*/
protected boolean running;
/**
* The map of the initial references.
*/
- private Map initial_references = new TreeMap();
+ protected Map initial_references = new TreeMap();
/**
* The currently active portServers.
@@ -332,12 +373,12 @@ public class Functional_ORB
private String ns_host;
/**
- * Probably free port, under that the ORB will try listening for
- * remote requests first. When the new object is connected, this
- * port is used first, then it is incremented by 1, etc. If the given
- * port is not available, up to 20 subsequent values are tried and then
- * the parameterless server socket contructor is called. The constant is
- * shared between multiple instances of this ORB.
+ * Probably free port, under that the ORB will try listening for remote
+ * requests first. When the new object is connected, this port is used first,
+ * then it is incremented by 1, etc. If the given port is not available, up to
+ * 20 subsequent values are tried and then the parameterless server socket
+ * contructor is called. The constant is shared between multiple instances of
+ * this ORB.
*/
private static int Port = DEFAULT_INITIAL_PORT;
@@ -345,6 +386,11 @@ public class Functional_ORB
* The port, on that the name service is expected to be running.
*/
private int ns_port = 900;
+
+ /**
+ * The name parser.
+ */
+ NameParser nameParser = new NameParser();
/**
* The instance, stored in this field, handles the asynchronous dynamic
@@ -358,10 +404,14 @@ public class Functional_ORB
protected LinkedList freed_ports = new LinkedList();
/**
- * The maximal allowed number of the currently running parallel
- * threads per object. For security reasons, this is made private and
- * unchangeable. After exceeding this limit, the NO_RESOURCES
- * is thrown back to the client.
+ * Maps a single-threaded POAs to they sharedPortServants.
+ */
+ protected Hashtable identities = new Hashtable();
+
+ /**
+ * The maximal allowed number of the currently running parallel threads per
+ * object. For security reasons, this is made private and unchangeable. After
+ * exceeding this limit, the NO_RESOURCES is thrown back to the client.
*/
private int MAX_RUNNING_THREADS = 256;
@@ -385,20 +435,19 @@ public class Functional_ORB
}
/**
- * If the max version is assigned, the orb replies with the error
- * message if the request version is above the supported 1.2 version.
- * This behavior is recommended by OMG, but not all implementations
- * respond that error message by re-sending the request, encoded in the older
- * version.
- */
+ * If the max version is assigned, the orb replies with the error message if
+ * the request version is above the supported 1.2 version. This behavior is
+ * recommended by OMG, but not all implementations respond that error message
+ * by re-sending the request, encoded in the older version.
+ */
public void setMaxVersion(Version max_supported)
{
max_version = max_supported;
}
/**
- * Get the maximal supported GIOP version or null if the version is
- * not checked.
+ * Get the maximal supported GIOP version or null if the version is not
+ * checked.
*/
public Version getMaxVersion()
{
@@ -406,17 +455,15 @@ public class Functional_ORB
}
/**
- * Get the currently free port, starting from the initially set port
- * and going up max 20 steps, then trying to bind into any free
- * address.
+ * Get the currently free port, starting from the initially set port and going
+ * up max 20 steps, then trying to bind into any free address.
*
* @return the currently available free port.
*
- * @throws NO_RESOURCES if the server socked cannot be opened on the
- * local host.
+ * @throws NO_RESOURCES if the server socked cannot be opened on the local
+ * host.
*/
- public int getFreePort()
- throws BAD_OPERATION
+ public int getFreePort() throws BAD_OPERATION
{
ServerSocket s;
int a_port;
@@ -473,12 +520,11 @@ public class Functional_ORB
}
/**
- * Set the port, on that the server is listening for the client requests.
- * If only one object is connected to the orb, the server will be
- * try listening on this port first. It the port is busy, or if more
- * objects are connected, the subsequent object will receive a larger
- * port values, skipping unavailable ports, if required. The change
- * applies globally.
+ * Set the port, on that the server is listening for the client requests. If
+ * only one object is connected to the orb, the server will be try listening
+ * on this port first. It the port is busy, or if more objects are connected,
+ * the subsequent object will receive a larger port values, skipping
+ * unavailable ports, if required. The change applies globally.
*
* @param a_Port a port, on that the server is listening for requests.
*/
@@ -488,14 +534,13 @@ public class Functional_ORB
}
/**
- * Connect the given CORBA object to this ORB. After the object is
- * connected, it starts receiving remote invocations via this ORB.
+ * Connect the given CORBA object to this ORB. After the object is connected,
+ * it starts receiving remote invocations via this ORB.
*
- * The ORB tries to connect the object to the port, that has been
- * previously set by {@link setPort(int)}. On failure, it tries
- * 20 subsequent larger values and then calls the parameterless
- * server socked constructor to get any free local port.
- * If this fails, the {@link NO_RESOURCES} is thrown.
+ * The ORB tries to connect the object to the port, that has been previously
+ * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger
+ * values and then calls the parameterless server socked constructor to get
+ * any free local port. If this fails, the {@link NO_RESOURCES} is thrown.
*
* @param object the object, must implement the {@link InvokeHandler})
* interface.
@@ -515,19 +560,18 @@ public class Functional_ORB
}
/**
- * Connect the given CORBA object to this ORB, explicitly specifying
- * the object key.
+ * Connect the given CORBA object to this ORB, explicitly specifying the
+ * object key.
*
- * The ORB tries to connect the object to the port, that has been
- * previously set by {@link setPort(int)}. On failure, it tries
- * 20 subsequent larger values and then calls the parameterless
- * server socked constructor to get any free local port.
- * If this fails, the {@link NO_RESOURCES} is thrown.
+ * The ORB tries to connect the object to the port, that has been previously
+ * set by {@link setPort(int)}. On failure, it tries 20 subsequent larger
+ * values and then calls the parameterless server socked constructor to get
+ * any free local port. If this fails, the {@link NO_RESOURCES} is thrown.
*
* @param object the object, must implement the {@link InvokeHandler})
* interface.
- * @param key the object key, usually used to identify the object from
- * remote side.
+ * @param key the object key, usually used to identify the object from remote
+ * side.
*
* @throws BAD_PARAM if the object does not implement the
* {@link InvokeHandler}).
@@ -536,7 +580,8 @@ public class Functional_ORB
{
int a_port = getFreePort();
- Connected_objects.cObject ref = connected_objects.add(key, object, a_port);
+ Connected_objects.cObject ref =
+ connected_objects.add(key, object, a_port, null);
IOR ior = createIOR(ref);
prepareObject(object, ior);
if (running)
@@ -544,11 +589,56 @@ public class Functional_ORB
}
/**
+ * Connect the given CORBA object to this ORB, explicitly specifying the
+ * object key and the identity of the thread (and port), where the object must
+ * be served. The identity is normally the POA.
+ *
+ * The new port server will be started only if there is no one already running
+ * for the same identity. Otherwise, the task of the existing port server will
+ * be widened, including duty to serve the given object. All objects,
+ * connected to a single identity by this method, will process they requests
+ * subsequently in the same thread. The method is used when the expected
+ * number of the objects is too large to have a single port and thread per
+ * object. This method is used by POAs, having a single thread policy.
+ *
+ * @param object the object, must implement the {@link InvokeHandler})
+ * interface.
+ * @param key the object key, usually used to identify the object from remote
+ * side.
+ * @param port the port, where the object must be connected.
+ *
+ * @throws BAD_PARAM if the object does not implement the
+ * {@link InvokeHandler}).
+ */
+ public void connect_1_thread(org.omg.CORBA.Object object, byte[] key,
+ java.lang.Object identity
+ )
+ {
+ sharedPortServer shared = (sharedPortServer) identities.get(identity);
+ if (shared == null)
+ {
+ int a_port = getFreePort();
+ shared = new sharedPortServer(a_port);
+ identities.put(identity, shared);
+ if (running)
+ {
+ portServers.add(shared);
+ shared.start();
+ }
+ }
+
+ Connected_objects.cObject ref =
+ connected_objects.add(key, object, shared.s_port, identity);
+ IOR ior = createIOR(ref);
+ prepareObject(object, ior);
+ }
+
+ /**
* Start the service on the given port of this IOR.
*
* @param ior the ior (only Internet.port is used).
*/
- private void startService(IOR ior)
+ public void startService(IOR ior)
{
portServer p = new portServer(ior.Internet.port);
portServers.add(p);
@@ -560,23 +650,22 @@ public class Functional_ORB
*/
public void destroy()
{
- super.destroy();
-
portServer p;
for (int i = 0; i < portServers.size(); i++)
{
p = (portServer) portServers.get(i);
p.close_now();
}
+ super.destroy();
}
/**
- * Disconnect the given CORBA object from this ORB. The object will be
- * no longer receiving the remote invocations. In response to the
- * remote invocation on this object, the ORB will send the
- * exception {@link OBJECT_NOT_EXIST}. The object, however, is not
- * destroyed and can receive the local invocations.
-
+ * Disconnect the given CORBA object from this ORB. The object will be no
+ * longer receiving the remote invocations. In response to the remote
+ * invocation on this object, the ORB will send the exception
+ * {@link OBJECT_NOT_EXIST}. The object, however, is not destroyed and can
+ * receive the local invocations.
+ *
* @param object the object to disconnect.
*/
public void disconnect(org.omg.CORBA.Object object)
@@ -599,8 +688,6 @@ public class Functional_ORB
// object implementation.
if (rmKey == null)
rmKey = connected_objects.getKey(object);
-
- // Disconnect the object on any success.
if (rmKey != null)
{
// Find and stop the corresponding portServer.
@@ -609,7 +696,7 @@ public class Functional_ORB
for (int i = 0; i < portServers.size(); i++)
{
p = (portServer) portServers.get(i);
- if (p.s_port == rmKey.port)
+ if (p.s_port == rmKey.port && !(p instanceof sharedPortServer))
{
p.close_now();
freed_ports.addFirst(new Integer(rmKey.port));
@@ -621,12 +708,47 @@ public class Functional_ORB
}
/**
+ * Notifies ORB that the shared service indentity (usually POA) is destroyed.
+ * The matching shared port server is terminated and the identity table entry
+ * is deleted. If this identity is not known for this ORB, the method returns
+ * without action.
+ *
+ * @param identity the identity that has been destroyed.
+ */
+ public void identityDestroyed(java.lang.Object identity)
+ {
+ if (identity == null)
+ return;
+
+ sharedPortServer ise = (sharedPortServer) identities.get(identity);
+ if (ise != null)
+ {
+ synchronized (connected_objects)
+ {
+ ise.close_now();
+ identities.remove(identity);
+
+ Connected_objects.cObject obj;
+ Map.Entry m;
+ Iterator iter = connected_objects.entrySet().iterator();
+ while (iter.hasNext())
+ {
+ m = (Map.Entry) iter.next();
+ obj = (Connected_objects.cObject) m.getValue();
+ if (obj.identity == identity)
+ iter.remove();
+ }
+ }
+ }
+ }
+
+ /**
* Find the local object, connected to this ORB.
*
* @param ior the ior of the potentially local object.
*
- * @return the local object, represented by the given IOR,
- * or null if this is not a local connected object.
+ * @return the local object, represented by the given IOR, or null if this is
+ * not a local connected object.
*/
public org.omg.CORBA.Object find_local_object(IOR ior)
{
@@ -655,26 +777,26 @@ public class Functional_ORB
Iterator iter = initial_references.keySet().iterator();
while (iter.hasNext())
- refs [ p++ ] = (String) iter.next();
-
+ {
+ refs [ p++ ] = (String) iter.next();
+ }
return refs;
}
/**
- * Get the IOR reference string for the given object.
- * The string embeds information about the object
- * repository Id, its access key and the server internet
- * address and port. With this information, the object
- * can be found by another ORB, possibly located on remote
- * computer.
+ * Get the IOR reference string for the given object. The string embeds
+ * information about the object repository Id, its access key and the server
+ * internet address and port. With this information, the object can be found
+ * by another ORB, possibly located on remote computer.
*
* @param the CORBA object
* @return the object IOR representation.
*
- * @throws BAD_PARAM if the object has not been previously
- * connected to this ORB.
- * @throws BAD_OPERATION in the unlikely case if the local host
- * address cannot be resolved.
+ * @throws BAD_PARAM if the object has not been previously connected to this
+ * ORB.
+ *
+ * @throws BAD_OPERATION in the unlikely case if the local host address cannot
+ * be resolved.
*
* @see string_to_object(String)
*/
@@ -693,8 +815,8 @@ public class Functional_ORB
if (rec == null)
throw new BAD_PARAM("The object " + forObject +
- " has not been previously connected to this ORB"
- );
+ " has not been previously connected to this ORB"
+ );
IOR ior = createIOR(rec);
@@ -702,17 +824,28 @@ public class Functional_ORB
}
/**
- * Find and return the easily accessible CORBA object, addressed
- * by name.
+ * Get the local IOR for the given object, null if the object is not local.
+ */
+ public IOR getLocalIor(org.omg.CORBA.Object forObject)
+ {
+ Connected_objects.cObject rec = connected_objects.getKey(forObject);
+ if (rec == null)
+ return null;
+ else
+ return createIOR(rec);
+ }
+
+ /**
+ * Find and return the easily accessible CORBA object, addressed by name.
*
* @param name the object name.
* @return the object
*
- * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name
- * is not associated with the known object.
+ * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name is not
+ * associated with the known object.
*/
public org.omg.CORBA.Object resolve_initial_references(String name)
- throws InvalidName
+ throws InvalidName
{
org.omg.CORBA.Object object = null;
try
@@ -738,9 +871,8 @@ public class Functional_ORB
}
/**
- * Start the ORBs main working cycle
- * (receive invocation - invoke on the local object - send response -
- * wait for another invocation).
+ * Start the ORBs main working cycle (receive invocation - invoke on the local
+ * object - send response - wait for another invocation).
*
* The method only returns after calling {@link #shutdown(boolean)}.
*/
@@ -758,27 +890,37 @@ public class Functional_ORB
m = (Map.Entry) iter.next();
obj = (Connected_objects.cObject) m.getValue();
- portServer subserver = new portServer(obj.port);
- portServers.add(subserver);
+ portServer subserver;
- // Reuse the current thread for the last portServer.
- if (!iter.hasNext())
+ if (obj.identity == null)
{
- // Discard the iterator, eliminating lock checks.
- iter = null;
- subserver.run();
- return;
+ subserver = new portServer(obj.port);
+ portServers.add(subserver);
}
else
- subserver.start();
+ subserver = (portServer) identities.get(obj.identity);
+
+ if (!subserver.isAlive())
+ {
+ // Reuse the current thread for the last portServer.
+ if (!iter.hasNext())
+ {
+ // Discard the iterator, eliminating lock checks.
+ iter = null;
+ subserver.run();
+ return;
+ }
+ else
+ subserver.start();
+ }
}
}
/**
* Shutdown the ORB server.
*
- * @param wait_for_completion if true, the current thread is
- * suspended until the shutdown process is complete.
+ * @param wait_for_completion if true, the current thread is suspended until
+ * the shutdown process is complete.
*/
public void shutdown(boolean wait_for_completion)
{
@@ -796,19 +938,26 @@ public class Functional_ORB
}
/**
- * Find and return the CORBA object, addressed by the given
- * IOR string representation. The object can (an usually is)
- * located on a remote computer, possibly running a different
- * (not necessary java) CORBA implementation.
- *
+ * Find and return the CORBA object, addressed by the given IOR string
+ * representation. The object can (an usually is) located on a remote
+ * computer, possibly running a different (not necessary java) CORBA
+ * implementation.
+ *
* @param ior the object IOR representation string.
- *
+ *
* @return the found CORBA object.
* @see object_to_string(org.omg.CORBA.Object)
*/
public org.omg.CORBA.Object string_to_object(String an_ior)
{
- IOR ior = IOR.parse(an_ior);
+ return nameParser.corbaloc(an_ior, this);
+ }
+
+ /**
+ * Convert ior reference to CORBA object.
+ */
+ public org.omg.CORBA.Object ior_to_object(IOR ior)
+ {
org.omg.CORBA.Object object = find_local_object(ior);
if (object == null)
{
@@ -816,9 +965,7 @@ public class Functional_ORB
try
{
if (impl._get_delegate() == null)
- {
- impl._set_delegate(new IOR_Delegate(this, ior));
- }
+ impl._set_delegate(new IOR_Delegate(this, ior));
}
catch (BAD_OPERATION ex)
{
@@ -828,21 +975,19 @@ public class Functional_ORB
}
object = impl;
- connected_objects.add(ior.key, impl, ior.Internet.port);
+ connected_objects.add(ior.key, impl, ior.Internet.port, null);
}
return object;
}
/**
- * Get the default naming service for the case when there no
- * NameService entries.
+ * Get the default naming service for the case when there no NameService
+ * entries.
*/
protected org.omg.CORBA.Object getDefaultNameService()
{
if (initial_references.containsKey(NAME_SERVICE))
- {
- return (org.omg.CORBA.Object) initial_references.get(NAME_SERVICE);
- }
+ return (org.omg.CORBA.Object) initial_references.get(NAME_SERVICE);
IOR ior = new IOR();
ior.Id = NamingContextExtHelper.id();
@@ -857,8 +1002,8 @@ public class Functional_ORB
}
/**
- * Find and return the object, that must be previously connected
- * to this ORB. Return null if no such object is available.
+ * Find and return the object, that must be previously connected to this ORB.
+ * Return null if no such object is available.
*
* @param key the object key.
*
@@ -877,8 +1022,7 @@ public class Functional_ORB
* @param app the current applet.
*
* @param props application specific properties, passed as the second
- * parameter in {@link #init(Applet, Properties)}.
- * Can be <code>null</code>.
+ * parameter in {@link #init(Applet, Properties)}. Can be <code>null</code>.
*/
protected void set_parameters(Applet app, Properties props)
{
@@ -891,27 +1035,23 @@ public class Functional_ORB
{
if (para [ i ] [ 0 ].equals(LISTEN_ON))
Port = Integer.parseInt(para [ i ] [ 1 ]);
-
if (para [ i ] [ 0 ].equals(REFERENCE))
{
- StringTokenizer st = new StringTokenizer(para [ i ] [ 1 ], "=");
+ StringTokenizer st =
+ new StringTokenizer(para [ i ] [ 1 ], "=");
initial_references.put(st.nextToken(),
- string_to_object(st.nextToken())
- );
+ string_to_object(st.nextToken())
+ );
}
if (para [ i ] [ 0 ].equals(NS_HOST))
ns_host = para [ i ] [ 1 ];
-
if (para [ i ] [ 0 ].equals(START_READING_MESSAGE))
TOUT_START_READING_MESSAGE = Integer.parseInt(para [ i ] [ 1 ]);
-
if (para [ i ] [ 0 ].equals(WHILE_READING))
TOUT_WHILE_READING = Integer.parseInt(para [ i ] [ 1 ]);
-
if (para [ i ] [ 0 ].equals(AFTER_RECEIVING))
TOUT_AFTER_RECEIVING = Integer.parseInt(para [ i ] [ 1 ]);
-
try
{
if (para [ i ] [ 0 ].equals(NS_PORT))
@@ -921,9 +1061,9 @@ public class Functional_ORB
{
BAD_PARAM bad =
new BAD_PARAM("Invalid " + NS_PORT +
- "property, unable to parse '" +
- props.getProperty(NS_PORT) + "'"
- );
+ "property, unable to parse '" +
+ props.getProperty(NS_PORT) + "'"
+ );
bad.initCause(ex);
throw bad;
}
@@ -935,52 +1075,54 @@ public class Functional_ORB
* Set the ORB parameters. This method is normally called from
* {@link #init(String[], Properties)}.
*
- * @param para the parameters, that were passed as the parameters
- * to the <code>main(String[] args)</code> method of the current standalone
+ * @param para the parameters, that were passed as the parameters to the
+ * <code>main(String[] args)</code> method of the current standalone
* application.
*
- * @param props application specific properties that were passed
- * as a second parameter in {@link init(String[], Properties)}).
- * Can be <code>null</code>.
+ * @param props application specific properties that were passed as a second
+ * parameter in {@link init(String[], Properties)}). Can be <code>null</code>.
*/
protected void set_parameters(String[] para, Properties props)
{
if (para.length > 1)
- for (int i = 0; i < para.length - 1; i++)
- {
- if (para [ i ].endsWith("ListenOn"))
- Port = Integer.parseInt(para [ i + 1 ]);
-
- if (para [ i ].endsWith("ORBInitRef"))
- {
- StringTokenizer st = new StringTokenizer(para [ i + 1 ], "=");
- initial_references.put(st.nextToken(),
- string_to_object(st.nextToken())
- );
- }
-
- if (para [ i ].endsWith("ORBInitialHost"))
- ns_host = para [ i + 1 ];
+ {
+ for (int i = 0; i < para.length - 1; i++)
+ {
+ if (para [ i ].endsWith("ListenOn"))
+ Port = Integer.parseInt(para [ i + 1 ]);
+ if (para [ i ].endsWith("ORBInitRef"))
+ {
+ StringTokenizer st = new StringTokenizer(para [ i + 1 ], "=");
+ initial_references.put(st.nextToken(),
+ string_to_object(st.nextToken())
+ );
+ }
- try
- {
- if (para [ i ].endsWith("ORBInitialPort"))
- ns_port = Integer.parseInt(para [ i + 1 ]);
- }
- catch (NumberFormatException ex)
- {
- throw new BAD_PARAM("Invalid " + para [ i ] +
- "parameter, unable to parse '" +
- props.getProperty(para [ i + 1 ]) + "'"
- );
- }
- }
+ if (para [ i ].endsWith("ORBInitialHost"))
+ ns_host = para [ i + 1 ];
+ try
+ {
+ if (para [ i ].endsWith("ORBInitialPort"))
+ ns_port = Integer.parseInt(para [ i + 1 ]);
+ }
+ catch (NumberFormatException ex)
+ {
+ throw new BAD_PARAM("Invalid " + para [ i ] +
+ "parameter, unable to parse '" +
+ props.getProperty(para [ i + 1 ]) + "'"
+ );
+ }
+ }
+ }
useProperties(props);
}
- private IOR createIOR(Connected_objects.cObject ref)
- throws BAD_OPERATION
+ /**
+ * Create IOR for the given object references.
+ */
+ protected IOR createIOR(Connected_objects.cObject ref)
+ throws BAD_OPERATION
{
IOR ior = new IOR();
ior.key = ref.key;
@@ -994,7 +1136,6 @@ public class Functional_ORB
}
if (ior.Id == null)
ior.Id = ref.object.getClass().getName();
-
try
{
ior.Internet.host = InetAddress.getLocalHost().getHostAddress();
@@ -1016,12 +1157,13 @@ public class Functional_ORB
* {@link InvokeHandler}).
*/
private void prepareObject(org.omg.CORBA.Object object, IOR ior)
- throws BAD_PARAM
+ throws BAD_PARAM
{
- if (!(object instanceof InvokeHandler))
- throw new BAD_PARAM(object.getClass().getName() +
- " does not implement InvokeHandler. "
- );
+ /*
+ * if (!(object instanceof InvokeHandler)) throw new
+ * BAD_PARAM(object.getClass().getName() + " does not implement
+ * InvokeHandler. " );
+ */
// If no delegate is set, set the default delegate.
if (object instanceof ObjectImpl)
@@ -1030,9 +1172,7 @@ public class Functional_ORB
try
{
if (impl._get_delegate() == null)
- {
- impl._set_delegate(new Simple_delegate(this, ior));
- }
+ impl._set_delegate(new Simple_delegate(this, ior));
}
catch (BAD_OPERATION ex)
{
@@ -1048,20 +1188,17 @@ public class Functional_ORB
* @param net_out the stream to write response into
* @param msh_request the request message header
* @param rh_request the request header
- * @param handler the invocation handler that has been used to
- * invoke the operation
- * @param sysEx the system exception, thrown during the invocation,
- * null if none.
+ * @param handler the invocation handler that has been used to invoke the
+ * operation
+ * @param sysEx the system exception, thrown during the invocation, null if
+ * none.
*
* @throws IOException
*/
private void respond_to_client(OutputStream net_out,
- MessageHeader msh_request,
- RequestHeader rh_request,
- bufferedResponseHandler handler,
- SystemException sysEx
- )
- throws IOException
+ MessageHeader msh_request, RequestHeader rh_request,
+ bufferedResponseHandler handler, SystemException sysEx
+ ) throws IOException
{
// Set the reply header properties.
ReplyHeader reply = handler.reply_header;
@@ -1072,17 +1209,23 @@ public class Functional_ORB
reply.reply_status = ReplyHeader.USER_EXCEPTION;
else
reply.reply_status = ReplyHeader.NO_EXCEPTION;
-
reply.request_id = rh_request.request_id;
- cdrBufOutput out = new cdrBufOutput(50 + handler.getBuffer().buffer.size());
+ cdrBufOutput out =
+ new cdrBufOutput(50 + handler.getBuffer().buffer.size());
out.setOrb(this);
out.setOffset(msh_request.getHeaderSize());
reply.write(out);
- // Write the reply data from the handler.
+ if (msh_request.version.since_inclusive(1, 2))
+ {
+ out.align(8);
+
+ // Write the reply data from the handler. The handler data already
+ // include the necessary heading zeroes for alignment.
+ }
handler.getBuffer().buffer.writeTo(out);
MessageHeader msh_reply = new MessageHeader();
@@ -1098,19 +1241,53 @@ public class Functional_ORB
}
/**
+ * Forward request to another target, as indicated by the passed exception.
+ */
+ private void forward_request(OutputStream net_out,
+ MessageHeader msh_request, RequestHeader rh_request, gnuForwardRequest info
+ ) throws IOException
+ {
+ MessageHeader msh_forward = new MessageHeader();
+ msh_forward.version = msh_request.version;
+
+ ReplyHeader rh_forward = msh_forward.create_reply_header();
+ msh_forward.message_type = MessageHeader.REPLY;
+ rh_forward.reply_status = info.forwarding_code;
+ rh_forward.request_id = rh_request.request_id;
+
+ // The forwarding code is either LOCATION_FORWARD or LOCATION_FORWARD_PERM.
+ cdrBufOutput out = new cdrBufOutput();
+ out.setOrb(this);
+ out.setOffset(msh_forward.getHeaderSize());
+
+ rh_forward.write(out);
+
+ if (msh_forward.version.since_inclusive(1, 2))
+ out.align(8);
+ out.write_Object(info.forward_reference);
+
+ msh_forward.message_size = out.buffer.size();
+
+ // Write the forwarding instruction.
+ msh_forward.write(net_out);
+ out.buffer.writeTo(net_out);
+ net_out.flush();
+ }
+
+ /**
* Contains a single servicing task.
*
- * Normally, each task matches a single remote invocation.
- * However under frequent tandem submissions the same
- * task may span over several invocations.
+ * Normally, each task matches a single remote invocation. However under
+ * frequent tandem submissions the same task may span over several
+ * invocations.
*
* @param serverSocket the ORB server socket.
*
* @throws MARSHAL
* @throws IOException
*/
- private void serve(final portServer p, ServerSocket serverSocket)
- throws MARSHAL, IOException
+ void serve(final portServer p, ServerSocket serverSocket)
+ throws MARSHAL, IOException
{
final Socket service;
service = serverSocket.accept();
@@ -1148,15 +1325,15 @@ public class Functional_ORB
/**
* A single servicing step, when the client socket is alrady open.
*
- * Normally, each task matches a single remote invocation.
- * However under frequent tandem submissions the same
- * task may span over several invocations.
+ * Normally, each task matches a single remote invocation. However under
+ * frequent tandem submissions the same task may span over several
+ * invocations.
*
* @param service the opened client socket.
- * @param no_resources if true, the "NO RESOURCES" exception
- * is thrown to the client.
+ * @param no_resources if true, the "NO RESOURCES" exception is thrown to the
+ * client.
*/
- private void serveStep(Socket service, boolean no_resources)
+ void serveStep(Socket service, boolean no_resources)
{
try
{
@@ -1179,15 +1356,17 @@ public class Functional_ORB
}
if (max_version != null)
- if (!msh_request.version.until_inclusive(max_version.major,
- max_version.minor
- )
- )
- {
- OutputStream out = service.getOutputStream();
- new ErrorMessage(max_version).write(out);
- return;
- }
+ {
+ if (!msh_request.version.until_inclusive(max_version.major,
+ max_version.minor
+ )
+ )
+ {
+ OutputStream out = service.getOutputStream();
+ new ErrorMessage(max_version).write(out);
+ return;
+ }
+ }
byte[] r = new byte[ msh_request.message_size ];
@@ -1221,9 +1400,12 @@ public class Functional_ORB
// in 1.2 and higher, align the current position at
// 8 octet boundary.
if (msh_request.version.since_inclusive(1, 2))
- cin.align(8);
+ {
+ cin.align(8);
+
+ // find the target object.
+ }
- // find the target object.
InvokeHandler target =
(InvokeHandler) find_connected_object(rh_request.object_key);
@@ -1234,7 +1416,9 @@ public class Functional_ORB
// TODO log errors about not existing objects and methods.
bufferedResponseHandler handler =
- new bufferedResponseHandler(this, msh_request, rh_reply);
+ new bufferedResponseHandler(this, msh_request, rh_reply,
+ rh_request
+ );
SystemException sysEx = null;
@@ -1246,6 +1430,18 @@ public class Functional_ORB
throw new OBJECT_NOT_EXIST();
target._invoke(rh_request.operation, cin, handler);
}
+ catch (gnuForwardRequest forwarded)
+ {
+ OutputStream sou = service.getOutputStream();
+ forward_request(sou, msh_request, rh_request, forwarded);
+ if (service != null && !service.isClosed())
+ {
+ // Wait for the subsequent invocations on the
+ // same socket for the TANDEM_REQUEST duration.
+ service.setSoTimeout(TANDEM_REQUESTS);
+ continue Serving;
+ }
+ }
catch (SystemException ex)
{
sysEx = ex;
@@ -1256,8 +1452,11 @@ public class Functional_ORB
}
catch (Exception except)
{
+ except.printStackTrace();
sysEx =
- new UNKNOWN("Unknown", 2, CompletionStatus.COMPLETED_MAYBE);
+ new UNKNOWN("Unknown", 2,
+ CompletionStatus.COMPLETED_MAYBE
+ );
org.omg.CORBA.portable.OutputStream ech =
handler.createExceptionReply();
@@ -1270,28 +1469,26 @@ public class Functional_ORB
{
OutputStream sou = service.getOutputStream();
respond_to_client(sou, msh_request, rh_request, handler,
- sysEx
- );
+ sysEx
+ );
}
}
else if (msh_request.message_type == MessageHeader.CLOSE_CONNECTION ||
- msh_request.message_type == MessageHeader.MESSAGE_ERROR
- )
+ msh_request.message_type == MessageHeader.MESSAGE_ERROR
+ )
{
CloseMessage.close(service.getOutputStream());
service.close();
return;
}
- else
- ;
+ ;
// TODO log error: "Not a request message."
if (service != null && !service.isClosed())
- {
- // Wait for the subsequent invocations on the
- // same socket for the TANDEM_REQUEST duration.
- service.setSoTimeout(TANDEM_REQUESTS);
- }
+
+ // Wait for the subsequent invocations on the
+ // same socket for the TANDEM_REQUEST duration.
+ service.setSoTimeout(TANDEM_REQUESTS);
else
return;
}
@@ -1315,23 +1512,18 @@ public class Functional_ORB
{
if (props.containsKey(LISTEN_ON))
Port = Integer.parseInt(props.getProperty(LISTEN_ON));
-
if (props.containsKey(NS_HOST))
ns_host = props.getProperty(NS_HOST);
-
try
{
if (props.containsKey(NS_PORT))
ns_port = Integer.parseInt(props.getProperty(NS_PORT));
-
if (props.containsKey(START_READING_MESSAGE))
TOUT_START_READING_MESSAGE =
Integer.parseInt(props.getProperty(START_READING_MESSAGE));
-
if (props.containsKey(WHILE_READING))
TOUT_WHILE_READING =
Integer.parseInt(props.getProperty(WHILE_READING));
-
if (props.containsKey(AFTER_RECEIVING))
TOUT_AFTER_RECEIVING =
Integer.parseInt(props.getProperty(AFTER_RECEIVING));
@@ -1339,9 +1531,9 @@ public class Functional_ORB
catch (NumberFormatException ex)
{
throw new BAD_PARAM("Invalid " + NS_PORT +
- "property, unable to parse '" +
- props.getProperty(NS_PORT) + "'"
- );
+ "property, unable to parse '" + props.getProperty(NS_PORT) +
+ "'"
+ );
}
Enumeration en = props.elements();
@@ -1350,33 +1542,31 @@ public class Functional_ORB
String item = (String) en.nextElement();
if (item.equals(REFERENCE))
initial_references.put(item,
- string_to_object(props.getProperty(item))
- );
+ string_to_object(props.getProperty(item))
+ );
}
}
}
/**
- * Get the next instance with a response being received. If all currently
- * sent responses not yet processed, this method pauses till at least one of
- * them is complete. If there are no requests currently sent, the method
- * pauses till some request is submitted and the response is received.
- * This strategy is identical to the one accepted by Suns 1.4 ORB
- * implementation.
+ * Get the next instance with a response being received. If all currently sent
+ * responses not yet processed, this method pauses till at least one of them
+ * is complete. If there are no requests currently sent, the method pauses
+ * till some request is submitted and the response is received. This strategy
+ * is identical to the one accepted by Suns 1.4 ORB implementation.
*
- * The returned response is removed from the list of the currently
- * submitted responses and is never returned again.
+ * The returned response is removed from the list of the currently submitted
+ * responses and is never returned again.
*
* @return the previously sent request that now contains the received
* response.
*
* @throws WrongTransaction If the method was called from the transaction
- * scope different than the one, used to send the request. The exception
- * can be raised only if the request is implicitly associated with some
- * particular transaction.
+ * scope different than the one, used to send the request. The exception can
+ * be raised only if the request is implicitly associated with some particular
+ * transaction.
*/
- public Request get_next_response()
- throws org.omg.CORBA.WrongTransaction
+ public Request get_next_response() throws org.omg.CORBA.WrongTransaction
{
return asynchron.get_next_response();
}
@@ -1385,8 +1575,8 @@ public class Functional_ORB
* Find if any of the requests that have been previously sent with
* {@link #send_multiple_requests_deferred}, have a response yet.
*
- * @return true if there is at least one response to the previously
- * sent request, false otherwise.
+ * @return true if there is at least one response to the previously sent
+ * request, false otherwise.
*/
public boolean poll_next_response()
{
@@ -1394,12 +1584,12 @@ public class Functional_ORB
}
/**
- * Send multiple prepared requests expecting to get a reply. All requests
- * are send in parallel, each in its own separate thread. When the
- * reply arrives, it is stored in the agreed fields of the corresponing
- * request data structure. If this method is called repeatedly,
- * the new requests are added to the set of the currently sent requests,
- * but the old set is not discarded.
+ * Send multiple prepared requests expecting to get a reply. All requests are
+ * send in parallel, each in its own separate thread. When the reply arrives,
+ * it is stored in the agreed fields of the corresponing request data
+ * structure. If this method is called repeatedly, the new requests are added
+ * to the set of the currently sent requests, but the old set is not
+ * discarded.
*
* @param requests the prepared array of requests.
*
@@ -1414,8 +1604,8 @@ public class Functional_ORB
/**
* Send multiple prepared requests one way, do not caring about the answer.
- * The messages, containing requests, will be marked, indicating that
- * the sender is not expecting to get a reply.
+ * The messages, containing requests, will be marked, indicating that the
+ * sender is not expecting to get a reply.
*
* @param requests the prepared array of requests.
*
@@ -1429,8 +1619,7 @@ public class Functional_ORB
/**
* Set the flag, forcing all server threads to terminate.
*/
- protected void finalize()
- throws java.lang.Throwable
+ protected void finalize() throws java.lang.Throwable
{
running = false;
super.finalize();
diff --git a/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java
index 1e0e154..f0f4093 100644
--- a/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java
+++ b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java
@@ -41,13 +41,13 @@ package gnu.CORBA.GIOP;
import gnu.CORBA.CDR.cdrInput;
import gnu.CORBA.CDR.cdrOutput;
-
/**
* The header of the standard reply.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
public abstract class ReplyHeader
+ extends contextSupportingHeader
{
/**
* Reply status, if no exception occured.
@@ -65,9 +65,8 @@ public abstract class ReplyHeader
public static final int SYSTEM_EXCEPTION = 2;
/**
- * Reply status, if the client ORB must re - send
- * the request to another destination. The body
- * contains IOR.
+ * Reply status, if the client ORB must re - send the request to another
+ * destination. The body contains IOR.
*/
public static final int LOCATION_FORWARD = 3;
@@ -84,16 +83,6 @@ public abstract class ReplyHeader
public static final int NEEDS_ADDRESSING_MODE = 5;
/**
- * Empty array, indicating that no service context is available.
- */
- protected static final ServiceContext[] NO_CONTEXT = new ServiceContext[ 0 ];
-
- /**
- * The ORB service data.
- */
- public ServiceContext[] service_context = NO_CONTEXT;
-
- /**
* The status of this reply, holds one of the reply status constants.
*/
public int reply_status;
@@ -110,19 +99,19 @@ public abstract class ReplyHeader
{
switch (reply_status)
{
- case NO_EXCEPTION :
+ case NO_EXCEPTION:
return "ok";
- case USER_EXCEPTION :
+ case USER_EXCEPTION:
return "user exception";
- case SYSTEM_EXCEPTION :
+ case SYSTEM_EXCEPTION:
return "system exception";
- case LOCATION_FORWARD :
+ case LOCATION_FORWARD:
return "moved";
- default :
+ default:
return null;
}
}
diff --git a/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java
index f2de4e2..17cccb8 100644
--- a/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java
+++ b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java
@@ -41,7 +41,6 @@ package gnu.CORBA.GIOP;
import gnu.CORBA.CDR.cdrInput;
import gnu.CORBA.CDR.cdrOutput;
-
import org.omg.CORBA.portable.IDLEntity;
/**
@@ -50,13 +49,13 @@ import org.omg.CORBA.portable.IDLEntity;
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
public abstract class RequestHeader
+ extends contextSupportingHeader
implements IDLEntity
{
/**
- * The currently free request id. This field is incremented
- * each time the new request header is constructed. To facilitate
- * error detection, the first free id is equal to 0x01234567
- * (19088743).
+ * The currently free request id. This field is incremented each time the new
+ * request header is constructed. To facilitate error detection, the first
+ * free id is equal to 0x01234567 (19088743).
*/
private static int freeId = 0x01234567;
@@ -71,23 +70,17 @@ public abstract class RequestHeader
public byte[] object_key;
/**
- * A value identifying the requesting principal.
- * Initialised into a single zero byte.
+ * A value identifying the requesting principal. Initialised into a single
+ * zero byte.
*
* @deprecated by CORBA 2.2.
*/
public byte[] requesting_principal;
/**
- * Contains the ORB service data being passed. Initialised as the
- * zero size array by default.
- */
- public ServiceContext[] service_context = new ServiceContext[ 0 ];
-
- /**
- * This is used to associate the reply message with the
- * previous request message. Initialised each time by the
- * different value, increasing form 1 to Integer.MAX_VALUE.
+ * This is used to associate the reply message with the previous request
+ * message. Initialised each time by the different value, increasing form 1 to
+ * Integer.MAX_VALUE.
*/
public int request_id = getNextId();
@@ -97,10 +90,9 @@ public abstract class RequestHeader
protected boolean response_expected = true;
/**
- * Get next free request id. The value of the free request
- * id starts from 0x02345678, it is incremented each time this
- * function is called and is reset to 1 after reaching
- * Integer.MAX_VALUE.
+ * Get next free request id. The value of the free request id starts from
+ * 0x02345678, it is incremented each time this function is called and is
+ * reset to 1 after reaching Integer.MAX_VALUE.
*
* @return the next free request id.
*/
@@ -126,15 +118,15 @@ public abstract class RequestHeader
public abstract boolean isResponseExpected();
/**
- * Converts an byte array into hexadecimal string values.
- * Used in various toString() methods.
+ * Converts an byte array into hexadecimal string values. Used in various
+ * toString() methods.
*/
public String bytes(byte[] array)
{
StringBuffer b = new StringBuffer();
for (int i = 0; i < array.length; i++)
{
- b.append(Integer.toHexString(array [ i ] & 0xFF));
+ b.append(Integer.toHexString(array[i] & 0xFF));
b.append(" ");
}
return b.toString();
@@ -158,4 +150,5 @@ public abstract class RequestHeader
* @param out a stream to write into.
*/
public abstract void write(cdrOutput out);
+
}
diff --git a/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java
index 7e44bdce..29a8ea8 100644
--- a/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java
+++ b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java
@@ -41,7 +41,9 @@ package gnu.CORBA.GIOP;
import gnu.CORBA.CDR.cdrInput;
import gnu.CORBA.CDR.cdrOutput;
-
+import org.omg.CORBA.BAD_INV_ORDER;
+import org.omg.CORBA.BAD_PARAM;
+import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.portable.IDLEntity;
/**
@@ -53,16 +55,40 @@ public class ServiceContext
implements IDLEntity
{
/**
- * The context data.
+ * Use serialVersionUID for interoperability.
*/
- public byte[] context_data;
+ private static final long serialVersionUID = 1;
/**
- * The context id.
+ * The context id (for instance, 0x1 for code sets context). At the moment of
+ * writing, the OMG defines 16 standard values and provides rules to register
+ * the vendor specific context ids. The range 0-4095 is reserved for the
+ * future standard OMG contexts.
*/
public int context_id;
/**
+ * The context_data.
+ */
+ public byte[] context_data;
+
+ /**
+ * Crete unitialised instance.
+ */
+ public ServiceContext()
+ {
+ }
+
+ /**
+ * Create from omg context.
+ */
+ public ServiceContext(org.omg.IOP.ServiceContext from)
+ {
+ context_id = from.context_id;
+ context_data = from.context_data;
+ }
+
+ /**
* Read the context values from the stream.
*
* @param istream a stream to read from.
@@ -73,13 +99,13 @@ public class ServiceContext
switch (id)
{
- case cxCodeSet.ID :
+ case cxCodeSet.ID:
cxCodeSet codeset = new cxCodeSet();
codeset.readContext(istream);
return codeset;
- default :
+ default:
ServiceContext ctx = new ServiceContext();
ctx.context_id = id;
@@ -94,9 +120,9 @@ public class ServiceContext
public static ServiceContext[] readSequence(cdrInput istream)
{
int size = istream.read_long();
- ServiceContext[] value = new gnu.CORBA.GIOP.ServiceContext[ size ];
+ ServiceContext[] value = new gnu.CORBA.GIOP.ServiceContext[size];
for (int i = 0; i < value.length; i++)
- value [ i ] = read(istream);
+ value[i] = read(istream);
return value;
}
@@ -118,7 +144,99 @@ public class ServiceContext
{
ostream.write_long(value.length);
for (int i = 0; i < value.length; i++)
- value [ i ].write(ostream);
+ value[i].write(ostream);
+ }
+
+ /**
+ * Add context to the given array of contexts.
+ */
+ public static void add(org.omg.IOP.ServiceContext[] cx,
+ org.omg.IOP.ServiceContext service_context, boolean replace)
+ {
+ int exists = -1;
+
+ for (int i = 0; i < cx.length; i++)
+ if (cx[i].context_id == service_context.context_id)
+ exists = i;
+
+ if (exists < 0)
+ {
+ // Add context.
+ org.omg.IOP.ServiceContext[] n = new org.omg.IOP.ServiceContext[cx.length + 1];
+ for (int i = 0; i < cx.length; i++)
+ n[i] = cx[i];
+ n[cx.length] = service_context;
+ }
+ else
+ {
+ // Replace context.
+ if (!replace)
+ throw new BAD_INV_ORDER("Repetetive setting of the context "
+ + service_context.context_id, 15,
+ CompletionStatus.COMPLETED_NO);
+ else
+ cx[exists] = service_context;
+ }
+ }
+
+ /**
+ * Add context to the given array of contexts.
+ */
+ public static ServiceContext[] add(ServiceContext[] cx,
+ org.omg.IOP.ServiceContext service_context, boolean replace)
+ {
+ int exists = -1;
+
+ for (int i = 0; i < cx.length; i++)
+ if (cx[i].context_id == service_context.context_id)
+ exists = i;
+
+ if (exists < 0)
+ {
+ // Add context.
+ ServiceContext[] n = new ServiceContext[cx.length + 1];
+ for (int i = 0; i < cx.length; i++)
+ n[i] = cx[i];
+ n[cx.length] = new ServiceContext(service_context);
+ return n;
+ }
+ else
+ {
+ // Replace context.
+ if (!replace)
+ throw new BAD_INV_ORDER("Repetetive setting of the context "
+ + service_context.context_id, 15,
+ CompletionStatus.COMPLETED_NO);
+ else
+ cx[exists] = new ServiceContext(service_context);
+ return cx;
+ }
+ }
+
+
+ /**
+ * Find context with the given name in the context array.
+ */
+ public static org.omg.IOP.ServiceContext findContext(int ctx_name,
+ org.omg.IOP.ServiceContext[] cx)
+ {
+ for (int i = 0; i < cx.length; i++)
+ if (cx[i].context_id == ctx_name)
+ return cx[i];
+ throw new BAD_PARAM("No context with id " + ctx_name);
+ }
+
+ /**
+ * Find context with the given name in the context array,
+ * converting into org.omg.IOP.ServiceContext.
+ */
+ public static org.omg.IOP.ServiceContext findContext(int ctx_name,
+ ServiceContext[] cx)
+ {
+ for (int i = 0; i < cx.length; i++)
+ if (cx[i].context_id == ctx_name)
+ return new org.omg.IOP.ServiceContext(ctx_name, cx[i].context_data);
+ throw new BAD_PARAM("No context with id " + ctx_name);
}
/**
@@ -126,6 +244,6 @@ public class ServiceContext
*/
public String toString()
{
- return "ctx "+context_id+", size "+context_data.length;
+ return "ctx " + context_id + ", size " + context_data.length;
}
}
diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java
index ffa45c3..7ede4e5 100644
--- a/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java
+++ b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java
@@ -40,11 +40,11 @@ package gnu.CORBA.GIOP.v1_0;
import gnu.CORBA.CDR.cdrInput;
import gnu.CORBA.CDR.cdrOutput;
-
-import org.omg.CORBA.portable.IDLEntity;
import gnu.CORBA.GIOP.ServiceContext;
import gnu.CORBA.GIOP.cxCodeSet;
+import org.omg.CORBA.portable.IDLEntity;
+
/**
* The GIOP 1.0 request message.
*
diff --git a/libjava/classpath/gnu/CORBA/IOR.java b/libjava/classpath/gnu/CORBA/IOR.java
index cedbce4..02e94aa 100644
--- a/libjava/classpath/gnu/CORBA/IOR.java
+++ b/libjava/classpath/gnu/CORBA/IOR.java
@@ -47,22 +47,29 @@ import gnu.CORBA.GIOP.cxCodeSet;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.CompletionStatus;
+import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.ULongSeqHelper;
+import org.omg.IOP.TAG_INTERNET_IOP;
+import org.omg.IOP.TAG_MULTIPLE_COMPONENTS;
+import org.omg.IOP.TaggedComponent;
+import org.omg.IOP.TaggedComponentHelper;
+import org.omg.IOP.TaggedProfile;
+import org.omg.IOP.TaggedProfileHelper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
/**
- * The implementaton of the Interoperable Object Reference (IOR).
- * IOR can be compared with the Internet address for a web page,
- * it provides means to locate the CORBA service on the web.
- * IOR contains the host address, port number, the object identifier
- * (key) inside the server, the communication protocol version,
- * supported charsets and so on.
+ * The implementaton of the Interoperable Object Reference (IOR). IOR can be
+ * compared with the Internet address for a web page, it provides means to
+ * locate the CORBA service on the web. IOR contains the host address, port
+ * number, the object identifier (key) inside the server, the communication
+ * protocol version, supported charsets and so on.
*
- * Ths class provides method for encoding and
- * decoding the IOR information from/to the stringified references,
- * usually returned by {@link org.omg.CORBA.ORB#String object_to_string()}.
+ * Ths class provides method for encoding and decoding the IOR information
+ * from/to the stringified references, usually returned by
+ * {@link org.omg.CORBA.ORB#String object_to_string()}.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*
@@ -72,10 +79,22 @@ import java.io.IOException;
public class IOR
{
/**
- * The code sets profile.
+ * The code sets tagged component, normally part of the Internet profile. This
+ * compone consists of the two componenets itself.
*/
public static class CodeSets_profile
{
+ public CodeSets_profile()
+ {
+ int[] supported = CharSets_OSF.getSupportedCharSets();
+
+ narrow.native_set = CharSets_OSF.NATIVE_CHARACTER;
+ narrow.conversion = supported;
+
+ wide.native_set = CharSets_OSF.NATIVE_WIDE_CHARACTER;
+ wide.conversion = supported;
+ }
+
/**
* The code set component.
*/
@@ -112,7 +131,7 @@ public class IOR
b.append(" conversion ");
for (int i = 0; i < conversion.length; i++)
{
- b.append(name(conversion [ i ]));
+ b.append(name(conversion[i]));
b.append(' ');
}
}
@@ -131,8 +150,8 @@ public class IOR
private String name(int set)
{
- return "0x" + Integer.toHexString(set) + " (" +
- CharSets_OSF.getName(set) + ") ";
+ return "0x" + Integer.toHexString(set) + " ("
+ + CharSets_OSF.getName(set) + ") ";
}
}
@@ -201,7 +220,7 @@ public class IOR
/**
* The internet profile.
*/
- public static class Internet_profile
+ public class Internet_profile
{
/**
* The agreed tag for the Internet profile.
@@ -224,6 +243,18 @@ public class IOR
public int port;
/**
+ * The code sets component in the internet profile of this IOR. This is not
+ * a separate profile.
+ */
+ public CodeSets_profile CodeSets = new CodeSets_profile();
+
+ /**
+ * Reserved for all components of this profile, this array holds the
+ * components other than code set components.
+ */
+ ArrayList components = new ArrayList();
+
+ /**
* Return the human readable representation.
*/
public String toString()
@@ -235,22 +266,63 @@ public class IOR
b.append(" (v");
b.append(version);
b.append(")");
+ if (components.size() > 0)
+ b.append(" " + components.size() + " extra components.");
return b.toString();
}
+
+ /**
+ * Write the internet profile (except the heading tag.
+ */
+ public void write(cdrOutput out)
+ {
+ try
+ {
+ // Need to write the Internet profile into the separate
+ // stream as we must know the size in advance.
+ cdrOutput b = out.createEncapsulation();
+
+ version.write(b);
+ b.write_string(host);
+
+ b.write_ushort((short) (port & 0xFFFF));
+
+ // Write the object key.
+ b.write_long(key.length);
+ b.write(key);
+
+ // Number of the tagged components.
+ b.write_long(1 + components.size());
+
+ b.write_long(CodeSets_profile.TAG_CODE_SETS);
+ CodeSets.write(b);
+
+ TaggedComponent t;
+
+ for (int i = 0; i < components.size(); i++)
+ {
+ t = (TaggedComponent) components.get(i);
+ TaggedComponentHelper.write(b, t);
+ }
+
+ b.close();
+ }
+ catch (Exception e)
+ {
+ MARSHAL m = new MARSHAL("Unable to write Internet profile.");
+ m.initCause(e);
+ throw m;
+ }
+ }
}
/**
- * The standard minor code, indicating that the string to object
- * converstio has failed due non specific reasons.
+ * The standard minor code, indicating that the string to object converstio
+ * has failed due non specific reasons.
*/
public static final int FAILED = 10;
/**
- * The code sets profile of this IOR.
- */
- public CodeSets_profile CodeSets = new CodeSets_profile();
-
- /**
* The internet profile of this IOR.
*/
public Internet_profile Internet = new Internet_profile();
@@ -261,45 +333,35 @@ public class IOR
public String Id;
/**
- * The additional tagged components, encapsulated in
- * the byte arrays. They are only supported by the
- * later versions, than currently implemented.
+ * The object key.
*/
- public byte[][] extra;
+ public byte[] key;
/**
- * The object key.
+ * All tagged profiles of this IOR, except the separately defined Internet
+ * profile.
*/
- public byte[] key;
+ ArrayList profiles = new ArrayList();
/**
- * True if the profile was encoded using the Big Endian or
- * the encoding is not known.
+ * True if the profile was encoded using the Big Endian or the encoding is not
+ * known.
*
* false if it was encoded using the Little Endian.
*/
public boolean Big_Endian = true;
/**
- * Create an empty instance, initialising the code sets to default
- * values.
+ * Create an empty instance, initialising the code sets to default values.
*/
public IOR()
{
- int[] supported = CharSets_OSF.getSupportedCharSets();
-
- CodeSets.narrow.native_set = CharSets_OSF.NATIVE_CHARACTER;
- CodeSets.narrow.conversion = supported;
-
- CodeSets.wide.native_set = CharSets_OSF.NATIVE_WIDE_CHARACTER;
- CodeSets.wide.conversion = supported;
}
/**
* Parse the provided stringifed reference.
*
- * @param stringified_reference, in the form of
- * IOR:nnnnnn.....
+ * @param stringified_reference, in the form of IOR:nnnnnn.....
*
* @return the parsed IOR
*
@@ -308,14 +370,13 @@ public class IOR
* TODO corballoc and other alternative formats.
*/
public static IOR parse(String stringified_reference)
- throws BAD_PARAM
+ throws BAD_PARAM
{
try
{
if (!stringified_reference.startsWith("IOR:"))
throw new BAD_PARAM("The string refernce must start with IOR:",
- FAILED, CompletionStatus.COMPLETED_NO
- );
+ FAILED, CompletionStatus.COMPLETED_NO);
IOR r = new IOR();
@@ -340,8 +401,7 @@ public class IOR
{
ex.printStackTrace();
throw new BAD_PARAM(ex + " while parsing " + stringified_reference,
- FAILED, CompletionStatus.COMPLETED_NO
- );
+ FAILED, CompletionStatus.COMPLETED_NO);
}
}
@@ -352,7 +412,7 @@ public class IOR
* @throws IOException if the stream throws it.
*/
public void _read(cdrInput c)
- throws IOException, BAD_PARAM
+ throws IOException, BAD_PARAM
{
int endian;
@@ -366,23 +426,21 @@ public class IOR
}
/**
- * Read the IOR from the provided input stream, not reading
- * the endian data at the beginning of the stream. The IOR is
- * thansferred in this form in
+ * Read the IOR from the provided input stream, not reading the endian data at
+ * the beginning of the stream. The IOR is thansferred in this form in
* {@link write_Object(org.omg.CORBA.Object)}.
*
* If the stream contains a null value, the Id and Internet fields become
- * equal to null. Otherwise Id contains some string (possibly
- * empty).
+ * equal to null. Otherwise Id contains some string (possibly empty).
*
- * Id is checked for null in cdrInput that then returns
- * null instead of object.
+ * Id is checked for null in cdrInput that then returns null instead of
+ * object.
*
* @param c a stream to read from.
* @throws IOException if the stream throws it.
*/
public void _read_no_endian(cdrInput c)
- throws IOException, BAD_PARAM
+ throws IOException, BAD_PARAM
{
Id = c.read_string();
@@ -407,9 +465,7 @@ public class IOR
Internet.host = profile.read_string();
Internet.port = profile.gnu_read_ushort();
- int lk = profile.read_long();
- key = new byte[ lk ];
- profile.read(key);
+ key = profile.read_sequence();
// Read tagged components.
int n_components = 0;
@@ -425,7 +481,16 @@ public class IOR
if (ctag == CodeSets_profile.TAG_CODE_SETS)
{
- CodeSets.read(profile);
+ Internet.CodeSets.read(profile);
+ }
+ else
+ {
+ // Construct a generic component for codesets
+ // profile.
+ TaggedComponent pc = new TaggedComponent();
+ pc.tag = ctag;
+ pc.component_data = profile.read_sequence();
+ Internet.components.add(pc);
}
}
}
@@ -434,12 +499,21 @@ public class IOR
ex.printStackTrace();
}
}
+ else
+ {
+ // Construct a generic profile.
+ TaggedProfile p = new TaggedProfile();
+ p.tag = tag;
+ p.profile_data = profile.buffer.getBuffer();
+
+ profiles.add(p);
+ }
}
}
/**
- * Write this IOR record to the provided CDR stream.
- * This procedure writes the zero (Big Endian) marker first.
+ * Write this IOR record to the provided CDR stream. This procedure writes the
+ * zero (Big Endian) marker first.
*/
public void _write(cdrOutput out)
{
@@ -451,8 +525,8 @@ public class IOR
/**
* Write a null value to the CDR output stream.
*
- * The null value is written as defined in OMG specification
- * (zero length string, followed by an empty set of profiles).
+ * The null value is written as defined in OMG specification (zero length
+ * string, followed by an empty set of profiles).
*/
public static void write_null(cdrOutput out)
{
@@ -464,47 +538,27 @@ public class IOR
}
/**
- * Write this IOR record to the provided CDR stream. The procedure
- * writed data in Big Endian, but does NOT add any endian marker
- * to the beginning.
+ * Write this IOR record to the provided CDR stream. The procedure writed data
+ * in Big Endian, but does NOT add any endian marker to the beginning.
*/
public void _write_no_endian(cdrOutput out)
{
- try
- {
- // Write repository id.
- out.write_string(Id);
-
- // Always one profile.
- out.write_long(1);
-
- // It is the Internet profile.
- out.write_long(Internet_profile.TAG_INTERNET_IOP);
+ // Write repository id.
+ out.write_string(Id);
- // Need to write the Internet profile into the separate
- // stream as we must know the size in advance.
- cdrOutput b = out.createEncapsulation();
+ out.write_long(1 + profiles.size());
- Internet.version.write(b);
- b.write_string(Internet.host);
+ // Write the Internet profile.
+ out.write_long(Internet_profile.TAG_INTERNET_IOP);
+ Internet.write(out);
- b.write_ushort((short) (Internet.port & 0xFFFF));
+ // Write other profiles.
+ TaggedProfile tp;
- // Write the object key.
- b.write_long(key.length);
- b.write(key);
-
- // One tagged component.
- b.write_long(1);
-
- b.write_long(CodeSets_profile.TAG_CODE_SETS);
- CodeSets.write(b);
-
- b.close();
- }
- catch (IOException ex)
+ for (int i = 0; i < profiles.size(); i++)
{
- Unexpected.error(ex);
+ tp = (TaggedProfile) profiles.get(i);
+ TaggedProfileHelper.write(out, tp);
}
}
@@ -525,11 +579,11 @@ public class IOR
for (int i = 0; i < key.length; i++)
{
- b.append(Integer.toHexString(key [ i ] & 0xFF));
+ b.append(Integer.toHexString(key[i] & 0xFF));
}
b.append(" ");
- b.append(CodeSets);
+ b.append(Internet.CodeSets);
return b.toString();
}
@@ -552,7 +606,7 @@ public class IOR
for (int i = 0; i < binary.length; i++)
{
- s = Integer.toHexString(binary [ i ] & 0xFF);
+ s = Integer.toHexString(binary[i] & 0xFF);
if (s.length() == 1)
b.append('0');
b.append(s);
@@ -560,4 +614,105 @@ public class IOR
return b.toString();
}
+
+ /**
+ * Adds a service-specific component to the IOR profile. The specified
+ * component will be included in all profiles, present in the IOR.
+ *
+ * @param tagged_component a tagged component being added.
+ */
+ public void add_ior_component(TaggedComponent tagged_component)
+ {
+ // Add to the Internet profile.
+ Internet.components.add(tagged_component);
+
+ // Add to others.
+ for (int i = 0; i < profiles.size(); i++)
+ {
+ TaggedProfile profile = (TaggedProfile) profiles.get(i);
+ addComponentTo(profile, tagged_component);
+ }
+ }
+
+ /**
+ * Adds a service-specific component to the IOR profile.
+ *
+ * @param tagged_component a tagged component being added.
+ *
+ * @param profile_id the IOR profile to that the component must be added. The
+ * 0 value ({@link org.omg.IOP.TAG_INTERNET_IOP#value}) adds to the Internet
+ * profile where host and port are stored by default.
+ */
+ public void add_ior_component_to_profile(TaggedComponent tagged_component,
+ int profile_id)
+ {
+ if (profile_id == TAG_INTERNET_IOP.value)
+ // Add to the Internet profile
+ Internet.components.add(tagged_component);
+ else
+ {
+ // Add to others.
+ for (int i = 0; i < profiles.size(); i++)
+ {
+ TaggedProfile profile = (TaggedProfile) profiles.get(i);
+ if (profile.tag == profile_id)
+ addComponentTo(profile, tagged_component);
+ }
+ }
+ }
+
+ /**
+ * Add given component to the given profile that is NOT an Internet profile.
+ *
+ * @param profile the profile, where the component should be added.
+ * @param component the component to add.
+ */
+ private static void addComponentTo(TaggedProfile profile,
+ TaggedComponent component)
+ {
+ if (profile.tag == TAG_MULTIPLE_COMPONENTS.value)
+ {
+ TaggedComponent[] present;
+ if (profile.profile_data.length > 0)
+ {
+ cdrBufInput in = new cdrBufInput(profile.profile_data);
+
+ present = new TaggedComponent[in.read_long()];
+
+ for (int i = 0; i < present.length; i++)
+ {
+ present[i] = TaggedComponentHelper.read(in);
+ }
+ }
+ else
+ present = new TaggedComponent[0];
+
+ cdrBufOutput out = new cdrBufOutput(profile.profile_data.length
+ + component.component_data.length
+ + 8);
+
+ // Write new amount of components.
+ out.write_long(present.length + 1);
+
+ // Write other components.
+ for (int i = 0; i < present.length; i++)
+ TaggedComponentHelper.write(out, present[i]);
+
+ // Write the passed component.
+ TaggedComponentHelper.write(out, component);
+
+ try
+ {
+ out.close();
+ }
+ catch (IOException e)
+ {
+ throw new Unexpected(e);
+ }
+ profile.profile_data = out.buffer.toByteArray();
+ }
+ else
+ // The future supported tagged profiles should be added here.
+ throw new BAD_PARAM("Unsupported profile type " + profile.tag);
+ }
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/IOR_Delegate.java b/libjava/classpath/gnu/CORBA/IOR_Delegate.java
index b06f630..3b64eb5 100644
--- a/libjava/classpath/gnu/CORBA/IOR_Delegate.java
+++ b/libjava/classpath/gnu/CORBA/IOR_Delegate.java
@@ -40,7 +40,9 @@ package gnu.CORBA;
import gnu.CORBA.CDR.cdrBufInput;
import gnu.CORBA.GIOP.ReplyHeader;
+import gnu.CORBA.Poa.activeObjectMap;
+import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.ExceptionList;
@@ -53,6 +55,7 @@ import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.RemarshalException;
+import org.omg.PortableInterceptor.ForwardRequest;
import java.io.IOException;
@@ -67,10 +70,20 @@ import java.net.Socket;
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
-public class IOR_Delegate
- extends Simple_delegate
+public class IOR_Delegate extends Simple_delegate
{
/**
+ * True if the current IOR does not map into the local servant. If false, the
+ * IOR is either local or should be checked.
+ */
+ boolean remote_ior;
+
+ /**
+ * If not null, this field contains data about the local servant.
+ */
+ activeObjectMap.Obj local_ior;
+
+ /**
* Contructs an instance of object using the given IOR.
*/
public IOR_Delegate(ORB an_orb, IOR an_ior)
@@ -92,11 +105,10 @@ public class IOR_Delegate
* @return the created request.
*/
public Request create_request(org.omg.CORBA.Object target, Context context,
- String operation, NVList parameters,
- NamedValue returns
- )
+ String operation, NVList parameters, NamedValue returns
+ )
{
- gnuRequest request = new gnuRequest();
+ gnuRequest request = getRequestInstance(target);
request.setIor(getIor());
request.set_target(target);
@@ -122,12 +134,11 @@ public class IOR_Delegate
* @return the created request.
*/
public Request create_request(org.omg.CORBA.Object target, Context context,
- String operation, NVList parameters,
- NamedValue returns, ExceptionList exceptions,
- ContextList ctx_list
- )
+ String operation, NVList parameters, NamedValue returns,
+ ExceptionList exceptions, ContextList ctx_list
+ )
{
- gnuRequest request = new gnuRequest();
+ gnuRequest request = getRequestInstance(target);
request.setIor(ior);
request.set_target(target);
@@ -144,100 +155,219 @@ public class IOR_Delegate
}
/**
- * Invoke operation on the given object, writing parameters to the given
- * output stream.
+ * Get the instance of request.
+ */
+ protected gnuRequest getRequestInstance(org.omg.CORBA.Object target)
+ {
+ return new gnuRequest();
+ }
+
+ /**
+ * Invoke operation on the given object, als handling temproray and permanent
+ * redirections. The ReplyHeader.LOCATION_FORWARD will cause to resend the
+ * request to the new direction. The ReplyHeader.LOCATION_FORWARD_PERM will
+ * cause additionally to remember the new location by this delegate, so
+ * subsequent calls will be immediately delivered to the new target.
*
* @param target the target object.
* @param output the output stream, previously returned by
* {@link #request(org.omg.CORBA.Object, String, boolean)}.
*
- * @return the input stream, to read the response from or null for a
- * one-way request.
+ * @return the input stream, to read the response from or null for a one-way
+ * request.
*
* @throws SystemException if the SystemException has been thrown on the
- * remote side (the exact type and the minor code matches the data of
- * the remote exception that has been thrown).
+ * remote side (the exact type and the minor code matches the data of the
+ * remote exception that has been thrown).
*
* @throws org.omg.CORBA.portable.ApplicationException as specified.
* @throws org.omg.CORBA.portable.RemarshalException as specified.
*/
public InputStream invoke(org.omg.CORBA.Object target, OutputStream output)
- throws ApplicationException, RemarshalException
+ throws ApplicationException, RemarshalException
{
streamRequest request = (streamRequest) output;
- if (request.response_expected)
+ Forwardings:
+ while (true)
{
- binaryReply response = request.request.submit();
-
- // Read reply header.
- ReplyHeader rh = response.header.create_reply_header();
- cdrBufInput input = response.getStream();
- input.setOrb(orb);
- rh.read(input);
-
- boolean moved_permanently = false;
-
- switch (rh.reply_status)
+ try
{
- case ReplyHeader.NO_EXCEPTION :
- if (response.header.version.since_inclusive(1, 2))
- input.align(8);
- return input;
-
- case ReplyHeader.SYSTEM_EXCEPTION :
- if (response.header.version.since_inclusive(1, 2))
- input.align(8);
- throw ObjectCreator.readSystemException(input);
-
- case ReplyHeader.USER_EXCEPTION :
- if (response.header.version.since_inclusive(1, 2))
- input.align(8);
- input.mark(2000);
-
- String uxId = input.read_string();
- input.reset();
-
- throw new ApplicationException(uxId, input);
-
- case ReplyHeader.LOCATION_FORWARD_PERM :
- moved_permanently = true;
-
- case ReplyHeader.LOCATION_FORWARD :
- if (response.header.version.since_inclusive(1, 2))
- input.align(8);
-
- IOR forwarded = new IOR();
- try
- {
- forwarded._read_no_endian(input);
- }
- catch (IOException ex)
- {
- MARSHAL t = new MARSHAL("Cant read forwarding info");
- t.initCause(ex);
- throw t;
- }
-
- request.request.setIor(forwarded);
-
- // If the object has moved permanently, its IOR is replaced.
- if (moved_permanently)
- setIor(forwarded);
-
- return invoke(target, request);
-
- default :
- throw new MARSHAL("Unknow reply status: " + rh.reply_status);
+ if (request.response_expected)
+ {
+ binaryReply response = request.request.submit();
+
+ // Read reply header.
+ ReplyHeader rh = response.header.create_reply_header();
+ cdrBufInput input = response.getStream();
+ input.setOrb(orb);
+ rh.read(input);
+ request.request.m_rph = rh;
+
+ boolean moved_permanently = false;
+
+ switch (rh.reply_status)
+ {
+ case ReplyHeader.NO_EXCEPTION :
+ if (request.request.m_interceptor != null)
+ request.request.m_interceptor.
+ receive_reply(request.request.m_info);
+ if (response.header.version.since_inclusive(1, 2))
+ input.align(8);
+ return input;
+
+ case ReplyHeader.SYSTEM_EXCEPTION :
+ if (response.header.version.since_inclusive(1, 2))
+ input.align(8);
+ showException(request, input);
+
+ throw ObjectCreator.readSystemException(input);
+
+ case ReplyHeader.USER_EXCEPTION :
+ if (response.header.version.since_inclusive(1, 2))
+ input.align(8);
+ showException(request, input);
+
+ throw new ApplicationException(request.
+ request.m_exception_id, input
+ );
+
+ case ReplyHeader.LOCATION_FORWARD_PERM :
+ moved_permanently = true;
+
+ case ReplyHeader.LOCATION_FORWARD :
+ if (response.header.version.since_inclusive(1, 2))
+ input.align(8);
+
+ IOR forwarded = new IOR();
+ try
+ {
+ forwarded._read_no_endian(input);
+ }
+ catch (IOException ex)
+ {
+ MARSHAL t =
+ new MARSHAL("Cant read forwarding info", 5102,
+ CompletionStatus.COMPLETED_NO
+ );
+ t.initCause(ex);
+ throw t;
+ }
+
+ gnuRequest prev = request.request;
+ gnuRequest r = getRequestInstance(target);
+
+ r.m_interceptor = prev.m_interceptor;
+ r.m_slots = prev.m_slots;
+
+ r.m_args = prev.m_args;
+ r.m_context = prev.m_context;
+ r.m_context_list = prev.m_context_list;
+ r.m_environment = prev.m_environment;
+ r.m_exceptions = prev.m_exceptions;
+ r.m_operation = prev.m_operation;
+ r.m_parameter_buffer = prev.m_parameter_buffer;
+ r.m_parameter_buffer.request = r;
+ r.m_result = prev.m_result;
+ r.m_target = prev.m_target;
+ r.oneWay = prev.oneWay;
+ r.m_forward_ior = forwarded;
+
+ if (r.m_interceptor != null)
+ r.m_interceptor.receive_other(r.m_info);
+
+ r.setIor(forwarded);
+
+ IOR_contructed_object it =
+ new IOR_contructed_object(orb, forwarded);
+
+ r.m_target = it;
+
+ request.request = r;
+
+ IOR prev_ior = getIor();
+
+ setIor(forwarded);
+
+ try
+ {
+ return invoke(it, request);
+ }
+ finally
+ {
+ if (!moved_permanently)
+ setIor(prev_ior);
+ }
+
+ default :
+ throw new MARSHAL("Unknow reply status: " +
+ rh.reply_status, 8000 + rh.reply_status,
+ CompletionStatus.COMPLETED_NO
+ );
+ }
+ }
+ else
+ {
+ request.request.send_oneway();
+ return null;
+ }
+ }
+ catch (ForwardRequest forwarded)
+ {
+ ForwardRequest fw = forwarded;
+ Forwarding2:
+ while (true)
+ {
+ try
+ {
+ gnuRequest prev = request.request;
+ gnuRequest r = getRequestInstance(target);
+
+ r.m_interceptor = prev.m_interceptor;
+ r.m_args = prev.m_args;
+ r.m_context = prev.m_context;
+ r.m_context_list = prev.m_context_list;
+ r.m_environment = prev.m_environment;
+ r.m_exceptions = prev.m_exceptions;
+ r.m_operation = prev.m_operation;
+ r.m_parameter_buffer = prev.m_parameter_buffer;
+ r.m_parameter_buffer.request = r;
+ r.m_result = prev.m_result;
+ r.m_target = prev.m_target;
+ r.oneWay = prev.oneWay;
+
+ r.m_forwarding_target = fw.forward;
+
+ if (r.m_interceptor != null)
+ r.m_interceptor.receive_other(r.m_info);
+
+ r.m_target = fw.forward;
+ request.request = r;
+ break Forwarding2;
+ }
+ catch (ForwardRequest e)
+ {
+ forwarded = e;
+ }
+ }
}
- }
- else
- {
- request.request.send_oneway();
- return null;
}
}
/**
+ * Show exception to interceptor.
+ */
+ void showException(streamRequest request, cdrBufInput input)
+ throws ForwardRequest
+ {
+ input.mark(2048);
+ request.request.m_exception_id = input.read_string();
+ input.reset();
+
+ if (request.request.m_interceptor != null)
+ request.request.m_interceptor.receive_exception(request.request.m_info);
+ }
+
+ /**
* Create a request to invoke the method of this CORBA object.
*
* @param target the CORBA object, to that this operation must be applied.
@@ -247,7 +377,7 @@ public class IOR_Delegate
*/
public Request request(org.omg.CORBA.Object target, String operation)
{
- gnuRequest request = new gnuRequest();
+ gnuRequest request = getRequestInstance(target);
request.setIor(ior);
request.set_target(target);
@@ -269,27 +399,28 @@ public class IOR_Delegate
* @return the stream where the method arguments should be written.
*/
public OutputStream request(org.omg.CORBA.Object target, String operation,
- boolean response_expected
- )
+ boolean response_expected
+ )
{
- gnuRequest request = new gnuRequest();
+ gnuRequest request = getRequestInstance(target);
request.setIor(ior);
request.set_target(target);
request.setOperation(operation);
- request.getParameterStream().response_expected = response_expected;
+ streamRequest out = request.getParameterStream();
+ out.response_expected = response_expected;
request.setORB(orb);
- return request.getParameterStream();
+ return out;
}
/**
- * If there is an opened cache socket to access this object, close
- * that socket.
+ * If there is an opened cache socket to access this object, close that
+ * socket.
*
- * @param target The target is not used, this delegate requires a
- * single instance per object.
+ * @param target The target is not used, this delegate requires a single
+ * instance per object.
*/
public void release(org.omg.CORBA.Object target)
{
@@ -308,4 +439,28 @@ public class IOR_Delegate
// do nothing, then.
}
}
+
+ /**
+ * Reset the remote_ior flag, forcing to check if the object is local on the
+ * next getRequestInstance call.
+ */
+ public void setIor(IOR an_ior)
+ {
+ super.setIor(an_ior);
+ remote_ior = false;
+ local_ior = null;
+ }
+
+ /**
+ * Checks if the ior is local so far it is easy.
+ */
+ public boolean is_local(org.omg.CORBA.Object self)
+ {
+ if (remote_ior)
+ return false;
+ else if (local_ior != null)
+ return true;
+ else
+ return super.is_local(self);
+ }
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java
index fda46ad..e46bed7 100644
--- a/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java
+++ b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package gnu.CORBA.NamingService;
import gnu.CORBA.Functional_ORB;
+import gnu.CORBA.IOR;
import org.omg.CosNaming.NamingContextExt;
@@ -47,15 +48,14 @@ import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/**
- * The server for the gnu classpath naming service. This is an executable
- * class that must be started to launch the GNU Classpath CORBA
- * transient naming service.
- *
+ * The server for the gnu classpath naming service. This is an executable class
+ * that must be started to launch the GNU Classpath CORBA transient naming
+ * service.
+ *
* GNU Classpath currently works with this naming service and is also
- * interoperable with the Sun Microsystems naming services from
- * releases 1.3 and 1.4, both transient <i>tnameserv</i> and persistent
- * <i>orbd</i>.
- *
+ * interoperable with the Sun Microsystems naming services from releases 1.3 and
+ * 1.4, both transient <i>tnameserv</i> and persistent <i>orbd</i>.
+ *
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
public class NamingServiceTransient
@@ -67,9 +67,9 @@ public class NamingServiceTransient
public static final int PORT = 900;
/**
- * Get the object key for the naming service. The default
- * key is the string "NameService" in ASCII.
- *
+ * Get the object key for the naming service. The default key is the string
+ * "NameService" in ASCII.
+ *
* @return the byte array.
*/
public static byte[] getDefaultKey()
@@ -85,15 +85,14 @@ public class NamingServiceTransient
}
/**
- * Start the naming service on the current host at the given port.
- * The parameter -org.omg.CORBA.ORBInitialPort NNN or
- * -ORBInitialPort NNN, if present, specifies the port, on that
- * the service must be started. If this key is not specified,
- * the service starts at the port 900.
- *
- * The parameter -ior FILE_NAME, if present, forces to store the ior string
- * of this naming service to the specified file.
- *
+ * Start the naming service on the current host at the given port. The
+ * parameter -org.omg.CORBA.ORBInitialPort NNN or -ORBInitialPort NNN, if
+ * present, specifies the port, on that the service must be started. If this
+ * key is not specified, the service starts at the port 900.
+ *
+ * The parameter -ior FILE_NAME, if present, forces to store the ior string of
+ * this naming service to the specified file.
+ *
* @param args the parameter string.
*/
public static void main(String[] args)
@@ -108,21 +107,24 @@ public class NamingServiceTransient
if (args.length > 1)
for (int i = 0; i < args.length - 1; i++)
{
- if (args [ i ].endsWith("ORBInitialPort"))
- port = Integer.parseInt(args [ i + 1 ]);
+ if (args[i].endsWith("ORBInitialPort"))
+ port = Integer.parseInt(args[i + 1]);
- if (args [ i ].equals("-ior"))
- iorf = args [ i + 1 ];
+ if (args[i].equals("-ior"))
+ iorf = args[i + 1];
}
Functional_ORB.setPort(port);
// Create the servant and register it with the ORB
NamingContextExt namer = new Ext(new TransientContext());
- orb.connect(namer, getDefaultKey());
+
+ // Case with the key "NameService".
+ orb.connect(namer, "NameService".getBytes());
// Storing the IOR reference.
String ior = orb.object_to_string(namer);
+ IOR iorr = IOR.parse(ior);
if (iorf != null)
{
FileOutputStream f = new FileOutputStream(iorf);
@@ -131,22 +133,23 @@ public class NamingServiceTransient
p.close();
}
- System.out.println("GNU Classpath, transient naming service. " +
- "Copyright (C) 2005 Free Software Foundation\n" +
- "This tool comes with ABSOLUTELY NO WARRANTY. " +
- "This is free software, and you are\nwelcome to " +
- "redistribute it under conditions, defined in " +
- "GNU Classpath license.\n\n" + ior
- );
+ System.out.println("GNU Classpath transient naming service "
+ + "started at " + iorr.Internet.host + ":" + iorr.Internet.port
+ + " key 'NameService'.\n\n"
+ + "Copyright (C) 2005 Free Software Foundation\n"
+ + "This tool comes with ABSOLUTELY NO WARRANTY. "
+ + "This is free software, and you are\nwelcome to "
+ + "redistribute it under conditions, defined in "
+ + "GNU Classpath license.\n\n" + ior);
new Thread()
+ {
+ public void run()
{
- public void run()
- {
- // Wait for invocations from clients.
- orb.run();
- }
- }.start();
+ // Wait for invocations from clients.
+ orb.run();
+ }
+ }.start();
}
catch (Exception e)
{
@@ -154,7 +157,8 @@ public class NamingServiceTransient
e.printStackTrace(System.out);
}
- // Restore the default value for allocating ports for the subsequent objects.
+ // Restore the default value for allocating ports for the subsequent
+ // objects.
Functional_ORB.setPort(Functional_ORB.DEFAULT_INITIAL_PORT);
}
}
diff --git a/libjava/classpath/gnu/CORBA/ObjectCreator.java b/libjava/classpath/gnu/CORBA/ObjectCreator.java
index b99c46b..81c1d06 100644
--- a/libjava/classpath/gnu/CORBA/ObjectCreator.java
+++ b/libjava/classpath/gnu/CORBA/ObjectCreator.java
@@ -1,4 +1,4 @@
-/* ExceptionCreator.java --
+/* ObjectCreator.java --
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,10 +38,15 @@ exception statement from your version. */
package gnu.CORBA;
+import gnu.CORBA.CDR.cdrBufOutput;
+
+import org.omg.CORBA.Any;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.CompletionStatusHelper;
import org.omg.CORBA.MARSHAL;
+import org.omg.CORBA.StructMember;
import org.omg.CORBA.SystemException;
+import org.omg.CORBA.TCKind;
import org.omg.CORBA.UNKNOWN;
import org.omg.CORBA.UserException;
import org.omg.CORBA.portable.InputStream;
@@ -51,9 +56,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
- * Creates java objects from the agreed IDL names for the simple
- * case when the CORBA object is directly mapped into the locally
- * defined java class.
+ * Creates java objects from the agreed IDL names for the simple case when the
+ * CORBA object is directly mapped into the locally defined java class.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
@@ -70,20 +74,17 @@ public class ObjectCreator
public static final String JAVA_PREFIX = "org.omg.";
/**
- * The prefix for classes that are placed instide the
- * gnu.CORBA namespace.
+ * The prefix for classes that are placed instide the gnu.CORBA namespace.
*/
public static final String CLASSPATH_PREFIX = "gnu.CORBA.";
/**
- * Try to instantiate an object with the given IDL name.
- * The object must be mapped to the local java class.
- * The omg.org domain must be mapped into the object in either
- * org/omg or gnu/CORBA namespace.
+ * Try to instantiate an object with the given IDL name. The object must be
+ * mapped to the local java class. The omg.org domain must be mapped into the
+ * object in either org/omg or gnu/CORBA namespace.
*
* @param IDL name
- * @return instantiated object instance or null if no such
- * available.
+ * @return instantiated object instance or null if no such available.
*/
public static java.lang.Object createObject(String idl, String suffix)
{
@@ -109,16 +110,15 @@ public class ObjectCreator
/**
* Create the system exception with the given idl name.
*
- * @param idl the exception IDL name, must match the syntax
- * "IDL:<class/name>:1.0".
+ * @param idl the exception IDL name, must match the syntax "IDL:<class/name>:1.0".
* @param minor the exception minor code.
* @param completed the exception completion status.
*
* @return the created exception.
*/
public static SystemException createSystemException(String idl, int minor,
- CompletionStatus completed
- )
+ CompletionStatus completed
+ )
{
try
{
@@ -127,20 +127,18 @@ public class ObjectCreator
Constructor constructor =
exClass.getConstructor(new Class[]
- {
- String.class, int.class,
- CompletionStatus.class
- }
- );
+ {
+ String.class, int.class, CompletionStatus.class
+ }
+ );
Object exception =
constructor.newInstance(new Object[]
- {
- " Remote exception " + idl + ", minor " +
- minor + ", " + completed + ".",
- new Integer(minor), completed
- }
- );
+ {
+ " Remote exception " + idl + ", minor " + minor + ", " +
+ completed + ".", new Integer(minor), completed
+ }
+ );
return (SystemException) exception;
}
@@ -153,9 +151,10 @@ public class ObjectCreator
/**
* Read the system exception from the given stream.
+ *
* @param input the CDR stream to read from.
- * @return the exception that has been stored in the stream
- * (IDL name, minor code and completion status).
+ * @return the exception that has been stored in the stream (IDL name, minor
+ * code and completion status).
*/
public static SystemException readSystemException(InputStream input)
{
@@ -170,8 +169,8 @@ public class ObjectCreator
}
/**
- * Reads the user exception, having the given Id, from the
- * input stream. The id is expected to be in the form like
+ * Reads the user exception, having the given Id, from the input stream. The
+ * id is expected to be in the form like
* 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0'
*
* @param idl the exception idl name.
@@ -189,11 +188,8 @@ public class ObjectCreator
Method read =
helperClass.getMethod("read",
- new Class[]
- {
- org.omg.CORBA.portable.InputStream.class
- }
- );
+ new Class[] { org.omg.CORBA.portable.InputStream.class }
+ );
return (UserException) read.invoke(null, new Object[] { input });
}
@@ -236,8 +232,8 @@ public class ObjectCreator
* @param ex an exception to write.
*/
public static void writeSystemException(OutputStream output,
- SystemException ex
- )
+ SystemException ex
+ )
{
String exIDL = toIDL(ex.getClass().getName());
output.write_string(exIDL);
@@ -266,14 +262,14 @@ public class ObjectCreator
}
/**
- * Converts the given IDL name to class name and tries to load the
- * matching class. The OMG prefix (omg.org) is replaced by
- * the java prefix org.omg. No other prefixes are added.
+ * Converts the given IDL name to class name and tries to load the matching
+ * class. The OMG prefix (omg.org) is replaced by the java prefix org.omg. No
+ * other prefixes are added.
*
* @param IDL the idl name.
*
- * TODO Cache the returned classes, avoiding these string manipulations
- * each time the conversion is required.
+ * TODO Cache the returned classes, avoiding these string manipulations each
+ * time the conversion is required.
*
* @return the matching class or null if no such is available.
*/
@@ -301,10 +297,10 @@ public class ObjectCreator
}
/**
- * Converts the given IDL name to class name, tries to load the
- * matching class and create an object instance with parameterless
- * constructor. The OMG prefix (omg.org) is replaced by
- * the java prefix org.omg. No other prefixes are added.
+ * Converts the given IDL name to class name, tries to load the matching class
+ * and create an object instance with parameterless constructor. The OMG
+ * prefix (omg.org) is replaced by the java prefix org.omg. No other prefixes
+ * are added.
*
* @param IDL the idl name.
*
@@ -341,8 +337,111 @@ public class ObjectCreator
cn = OMG_PREFIX + cn.substring(JAVA_PREFIX.length()).replace('.', '/');
else if (cn.startsWith(CLASSPATH_PREFIX))
cn =
- OMG_PREFIX + cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/');
+ OMG_PREFIX +
+ cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/');
return "IDL:" + cn + ":1.0";
}
+
+ /**
+ * Insert the passed parameter into the given Any, assuming that the helper
+ * class is available. The helper class must have the "Helper" suffix and be
+ * in the same package as the class of the object being inserted.
+ *
+ * @param into the target to insert.
+ *
+ * @param object the object to insert. It can be any object as far as the
+ * corresponding helper is provided.
+ *
+ * @return true on success, false otherwise.
+ */
+ public static boolean insertWithHelper(Any into, Object object)
+ {
+ try
+ {
+ String helperClassName = object.getClass().getName() + "Helper";
+ Class helperClass = Class.forName(helperClassName);
+
+ Method insert =
+ helperClass.getMethod("insert",
+ new Class[] { Any.class, object.getClass() }
+ );
+
+ insert.invoke(null, new Object[] { into, object });
+
+ return true;
+ }
+ catch (Exception exc)
+ {
+ // Failed due some reason.
+ return false;
+ }
+ }
+
+ /**
+ * Insert the system exception into the given Any.
+ */
+ public static boolean insertSysException(Any into, SystemException exception)
+ {
+ try
+ {
+ cdrBufOutput output = new cdrBufOutput();
+
+ String m_exception_id = toIDL(exception.getClass().getName());
+ output.write_string(m_exception_id);
+ output.write_ulong(exception.minor);
+ CompletionStatusHelper.write(output, exception.completed);
+
+ String name = getDefaultName(m_exception_id);
+
+ universalHolder h = new universalHolder(output);
+
+ into.insert_Streamable(h);
+
+ recordTypeCode r = new recordTypeCode(TCKind.tk_except);
+ r.setId(m_exception_id);
+ r.setName(name);
+ into.type(r);
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+
+ /**
+ * Get the type name from the IDL string.
+ */
+ public static String getDefaultName(String idl)
+ {
+ int f1 = idl.lastIndexOf("/");
+ int p1 = (f1 < 0) ? 0 : f1;
+ int p2 = idl.indexOf(":", p1);
+ if (p2 < 0)
+ p2 = idl.length();
+
+ String name = idl.substring(f1 + 1, p2);
+ return name;
+ }
+
+ /**
+ * Insert this exception into the given Any. On failure, insert the UNKNOWN
+ * exception.
+ */
+ public static void insertException(Any into, Throwable exception)
+ {
+ boolean ok = false;
+ if (exception instanceof SystemException)
+ ok = insertSysException(into, (SystemException) exception);
+ else if (exception instanceof UserException)
+ ok = insertWithHelper(into, exception);
+
+ if (!ok)
+ ok = insertSysException(into, new UNKNOWN());
+ if (!ok)
+ throw new InternalError("Exception wrapping broken");
+ }
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/Restricted_ORB.java b/libjava/classpath/gnu/CORBA/Restricted_ORB.java
index 801154e..247cd20 100644
--- a/libjava/classpath/gnu/CORBA/Restricted_ORB.java
+++ b/libjava/classpath/gnu/CORBA/Restricted_ORB.java
@@ -58,6 +58,9 @@ import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA.UnionMember;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ValueFactory;
+import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
+import org.omg.PortableInterceptor.IORInterceptorOperations;
+import org.omg.PortableInterceptor.ServerRequestInterceptorOperations;
import java.applet.Applet;
@@ -66,22 +69,20 @@ import java.util.Properties;
/**
* This class implements so-called Singleton ORB, a highly restricted version
- * that cannot communicate over network. This ORB is provided
- * for the potentially malicious applets with heavy security restrictions.
- * It, however, supports some basic features that might be needed even
- * when the network access is not granted.
+ * that cannot communicate over network. This ORB is provided for the
+ * potentially malicious applets with heavy security restrictions. It, however,
+ * supports some basic features that might be needed even when the network
+ * access is not granted.
*
- * This ORB can only create typecodes,
- * {@link Any}, {@link ContextList}, {@link NVList} and
- * {@link org.omg.CORBA.portable.OutputStream} that writes to an
- * internal buffer.
+ * This ORB can only create typecodes, {@link Any}, {@link ContextList},
+ * {@link NVList} and {@link org.omg.CORBA.portable.OutputStream} that writes to
+ * an internal buffer.
*
* All other methods throw the {@link NO_IMPLEMENT} exception.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
-public class Restricted_ORB
- extends org.omg.CORBA_2_3.ORB
+public class Restricted_ORB extends org.omg.CORBA_2_3.ORB
{
/**
* The singleton instance of this ORB.
@@ -89,13 +90,41 @@ public class Restricted_ORB
public static final ORB Singleton = new Restricted_ORB();
/**
+ * The cumulated listener for all IOR interceptors. Interceptors are used by
+ * {@link gnu.CORBA.Poa.ORB_1_4}.
+ */
+ public IORInterceptorOperations iIor;
+
+ /**
+ * The cumulated listener for all server request interceptors. Interceptors
+ * are used by {@link gnu.CORBA.Poa.ORB_1_4}.
+ */
+ public ServerRequestInterceptorOperations iServer;
+
+ /**
+ * The cumulated listener for all client request interceptros. Interceptors
+ * are used by {@link gnu.CORBA.Poa.ORB_1_4}.
+ */
+ public ClientRequestInterceptorOperations iClient;
+
+ /**
+ * The required size of the interceptor slot array.
+ */
+ public int icSlotSize = 0;
+
+ /**
* The value factories.
*/
protected Hashtable factories = new Hashtable();
/**
- * Create a new instance of the RestrictedORB. This is used
- * in derived classes only.
+ * The policy factories.
+ */
+ protected Hashtable policyFactories = new Hashtable();
+
+ /**
+ * Create a new instance of the RestrictedORB. This is used in derived classes
+ * only.
*/
protected Restricted_ORB()
{
@@ -159,8 +188,8 @@ public class Restricted_ORB
/** {@inheritDoc} */
public TypeCode create_exception_tc(String id, String name,
- StructMember[] members
- )
+ StructMember[] members
+ )
{
recordTypeCode r = new recordTypeCode(TCKind.tk_except);
r.setId(id);
@@ -224,8 +253,8 @@ public class Restricted_ORB
/** {@inheritDoc} */
public TypeCode create_struct_tc(String id, String name,
- StructMember[] members
- )
+ StructMember[] members
+ )
{
recordTypeCode r = new recordTypeCode(TCKind.tk_struct);
r.setId(id);
@@ -240,13 +269,15 @@ public class Restricted_ORB
}
/** {@inheritDoc} */
- public TypeCode create_union_tc(String id, String name, TypeCode type,
- UnionMember[] members
- )
+ public TypeCode create_union_tc(String id, String name,
+ TypeCode discriminator_type, UnionMember[] members
+ )
{
recordTypeCode r = new recordTypeCode(TCKind.tk_union);
r.setId(id);
r.setName(name);
+ r.setDiscriminator_type(discriminator_type);
+ r.setDefaultIndex(0);
for (int i = 0; i < members.length; i++)
{
@@ -274,8 +305,8 @@ public class Restricted_ORB
catch (BadKind ex)
{
throw new BAD_PARAM("This is not a primitive type code: " +
- tcKind.value()
- );
+ tcKind.value()
+ );
}
}
@@ -304,13 +335,13 @@ public class Restricted_ORB
/**
* This method is not allowed for a RestrictedORB.
*
- * @throws InvalidName never in this class, but it is thrown
- * in the derived classes.
+ * @throws InvalidName never in this class, but it is thrown in the derived
+ * classes.
*
* @throws NO_IMPLEMENT, always.
*/
public org.omg.CORBA.Object resolve_initial_references(String name)
- throws InvalidName
+ throws InvalidName
{
no();
throw new InternalError();
@@ -366,8 +397,8 @@ public class Restricted_ORB
}
/**
- * Throws an exception, stating that the given method is not supported
- * by the Restricted ORB.
+ * Throws an exception, stating that the given method is not supported by the
+ * Restricted ORB.
*/
private final void no()
{
@@ -381,8 +412,7 @@ public class Restricted_ORB
*
* @throws NO_IMPLEMENT, always.
*/
- public Request get_next_response()
- throws org.omg.CORBA.WrongTransaction
+ public Request get_next_response() throws org.omg.CORBA.WrongTransaction
{
no();
throw new InternalError();
@@ -423,8 +453,8 @@ public class Restricted_ORB
* Register the value factory under the given repository id.
*/
public ValueFactory register_value_factory(String repository_id,
- ValueFactory factory
- )
+ ValueFactory factory
+ )
{
factories.put(repository_id, factory);
return factory;
@@ -440,9 +470,9 @@ public class Restricted_ORB
/**
* Look for the value factory for the value, having the given repository id.
- * The implementation checks for the registered value factories first.
- * If none found, it tries to load and instantiate the class, mathing the
- * given naming convention. If this faild, null is returned.
+ * The implementation checks for the registered value factories first. If none
+ * found, it tries to load and instantiate the class, mathing the given naming
+ * convention. If this faild, null is returned.
*
* @param repository_id a repository id.
*
@@ -452,12 +482,43 @@ public class Restricted_ORB
{
ValueFactory f = (ValueFactory) factories.get(repository_id);
if (f != null)
- return f;
+ {
+ return f;
+ }
- f = (ValueFactory) ObjectCreator.createObject(repository_id, "DefaultFactory");
+ f = (ValueFactory) ObjectCreator.createObject(repository_id,
+ "DefaultFactory"
+ );
if (f != null)
- factories.put(repository_id, f);
-
+ {
+ factories.put(repository_id, f);
+ }
return f;
}
+
+ /**
+ * Destroy the interceptors, if they are present.
+ */
+ public void destroy()
+ {
+ if (iIor != null)
+ {
+ iIor.destroy();
+ iIor = null;
+ }
+
+ if (iServer != null)
+ {
+ iServer.destroy();
+ iServer = null;
+ }
+
+ if (iClient != null)
+ {
+ iClient.destroy();
+ iClient = null;
+ }
+
+ super.destroy();
+ }
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java
index 0b69881..7f40fc8 100644
--- a/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java
+++ b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java
@@ -53,10 +53,11 @@ import org.omg.CORBA.portable.ResponseHandler;
import org.omg.CORBA.portable.Streamable;
/**
- * This class exists to handle obsolete invocation style using
- * ServerRequest.
- *
- * @deprecated The method {@link ObjectImpl#_invoke} is much faster.
+ * This class supports invocation using ServerRequest. When possible,
+ * it is better to use the {@link ObjectImpl#_invoke} rather than
+ * working via ServerRequest. However since 1.4 the ServerRequest is
+ * involved into POA machinery making this type of call is sometimes
+ * inavoidable.
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
@@ -86,13 +87,13 @@ public class ServiceRequestAdapter
}
/**
- * The old style invocation using the currently deprecated server
- * request class.
+ * Make an invocation.
*
* @param request a server request, containg the invocation information.
* @param target the invocation target
- * @param result the result holder with the set suitable streamable to read
- * the result or null for void.
+ * @param result the result holder with the set suitable streamable.
+ * Using this parameter only increase the performance. It can be
+ * null if the return type is void or unknown.
*/
public static void invoke(ServerRequest request, InvokeHandler target,
Streamable result
@@ -133,12 +134,20 @@ public class ServiceRequestAdapter
else
{
if (result != null)
- {
- result._read(in);
- gnuAny r = new gnuAny();
- r.insert_Streamable(result);
- request.set_result(r);
- };
+ {
+ // Use the holder for the return value, if provided.
+ result._read(in);
+
+ gnuAny r = new gnuAny();
+ r.insert_Streamable(result);
+ request.set_result(r);
+ }
+ else
+ {
+ // Use the universal holder otherwise.
+ gnuAny r = new gnuAny();
+ r.insert_Streamable(new streamReadyHolder(in));
+ }
// Unpack the arguments
for (int i = 0; i < args.count(); i++)
diff --git a/libjava/classpath/gnu/CORBA/Simple_delegate.java b/libjava/classpath/gnu/CORBA/Simple_delegate.java
index d0b2ad2..5eabc7d 100644
--- a/libjava/classpath/gnu/CORBA/Simple_delegate.java
+++ b/libjava/classpath/gnu/CORBA/Simple_delegate.java
@@ -195,13 +195,40 @@ public class Simple_delegate
}
/**
- * Only returns true if the objects are equal ('==').
+ * Returns true if the objects are the same of have
+ * the same delegate set. All objects in this implementation
+ * have a separate delegate.
*/
public boolean is_equivalent(org.omg.CORBA.Object target,
org.omg.CORBA.Object other
)
{
- return target == other;
+ if (target == other)
+ return true;
+ if ((target instanceof ObjectImpl) && other instanceof ObjectImpl)
+ {
+ try
+ {
+ org.omg.CORBA.portable.Delegate a =
+ ((ObjectImpl) target)._get_delegate();
+ org.omg.CORBA.portable.Delegate b =
+ ((ObjectImpl) other)._get_delegate();
+ if (a == b)
+ {
+ return true;
+ }
+ if (a != null && b != null)
+ {
+ return a.equals(b);
+ }
+ }
+ catch (Exception ex)
+ {
+ // Unable to get one of the delegates.
+ return false;
+ }
+ }
+ return false;
}
/**
@@ -246,4 +273,4 @@ public class Simple_delegate
{
throw new InternalError();
}
-}
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/SocketRepository.java b/libjava/classpath/gnu/CORBA/SocketRepository.java
index 70bcead..a6b9920 100644
--- a/libjava/classpath/gnu/CORBA/SocketRepository.java
+++ b/libjava/classpath/gnu/CORBA/SocketRepository.java
@@ -39,6 +39,7 @@ exception statement from your version. */
package gnu.CORBA;
import java.net.Socket;
+import java.net.SocketException;
import java.util.HashMap;
@@ -70,16 +71,18 @@ public class SocketRepository
/**
* Get a socket.
- *
+ *
* @param key a socket key.
- *
- * @return an opened socket for reuse, null if no such
- * available or it is closed.
+ *
+ * @return an opened socket for reuse, null if no such available or it is
+ * closed.
*/
public static Socket get_socket(Object key)
{
Socket s = (Socket) sockets.get(key);
- if (s != null && s.isClosed())
+ if (s == null)
+ return null;
+ else if (s.isClosed())
{
sockets.remove(key);
return null;
@@ -87,6 +90,15 @@ public class SocketRepository
else
{
sockets.remove(key);
+ try
+ {
+ // Set one minute time out that will be changed later.
+ s.setSoTimeout(60*1000);
+ }
+ catch (SocketException e)
+ {
+ s = null;
+ }
return s;
}
}
diff --git a/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java b/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java
index e7f00ba..0fe945c 100644
--- a/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java
+++ b/libjava/classpath/gnu/CORBA/bufferedResponseHandler.java
@@ -41,6 +41,7 @@ package gnu.CORBA;
import gnu.CORBA.CDR.cdrBufOutput;
import gnu.CORBA.GIOP.MessageHeader;
import gnu.CORBA.GIOP.ReplyHeader;
+import gnu.CORBA.GIOP.RequestHeader;
import gnu.CORBA.GIOP.cxCodeSet;
import org.omg.CORBA.ORB;
@@ -48,31 +49,33 @@ import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
/**
- * Provides the CDR output streams for writing the response to the given
- * buffer.
+ * Provides the CDR output streams for writing the response to the given buffer.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
-class bufferedResponseHandler
+public class bufferedResponseHandler
implements ResponseHandler
{
/**
- * The message header.
- * This field is used to compute the size and alignments.
+ * The message header. This field is used to compute the size and alignments.
* It is, however, never directly written to the buffer stream.
*/
- final MessageHeader message_header;
+ public final MessageHeader message_header;
/**
* The associated orb.
*/
- final ORB orb;
+ public final ORB orb;
/**
- * The reply header. This field is used to compute the size and alignments.
- * It is, however, never directly written to the buffer stream.
+ * The reply header.
+ */
+ public final ReplyHeader reply_header;
+
+ /**
+ * The request header.
*/
- final ReplyHeader reply_header;
+ public final RequestHeader request_header;
/**
* True if the stream was obtained by invoking {@link #createExceptionReply()},
@@ -86,28 +89,27 @@ class bufferedResponseHandler
private cdrBufOutput buffer;
/**
- * Create a new buffered response handler that uses the given message
- * headers. The headers are used to compute sizes and check the versions.
- * They are not written into a stream inside this class.
+ * Create a new buffered response handler that uses the given message headers.
+ * The headers are used to compute sizes and check the versions. They are not
+ * written into a stream inside this class.
*
* @param m_header a message header.
* @param r_header a reply header.
*/
bufferedResponseHandler(ORB an_orb, MessageHeader m_header,
- ReplyHeader r_header
- )
+ ReplyHeader r_header, RequestHeader rq_header)
{
message_header = m_header;
reply_header = r_header;
+ request_header = rq_header;
orb = an_orb;
prepareStream();
}
/**
- * 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.
+ * 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.
*/
@@ -121,8 +123,8 @@ class bufferedResponseHandler
/**
* 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.
+ * 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.
*/
@@ -135,27 +137,26 @@ class bufferedResponseHandler
}
/**
- * 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.
+ * 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
+ * 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.
*/
- cdrBufOutput getBuffer()
+ public cdrBufOutput getBuffer()
{
return buffer;
}
/**
- * True if the stream was obtained by invoking
- * {@link #createExceptionReply()}, false otherwise
- * (usually no-exception reply).
+ * True if the stream was obtained by invoking {@link #createExceptionReply()},
+ * false otherwise (usually no-exception reply).
*/
- boolean isExceptionReply()
+ public boolean isExceptionReply()
{
return exceptionReply;
}
@@ -167,21 +168,22 @@ class bufferedResponseHandler
{
buffer = new cdrBufOutput();
buffer.setOrb(orb);
- buffer.setOffset(message_header.getHeaderSize());
-
- // Get the position after the reply header would be written.
- reply_header.write(buffer);
+ buffer.setVersion(message_header.version);
+ buffer.setCodeSet(cxCodeSet.find(reply_header.service_context));
- int new_offset = message_header.getHeaderSize() + buffer.buffer.size();
+ // Since 1.2, the data section is always aligned on the 8 byte boundary.
+ // In older versions, it is necessary to set the offset correctly.
+ if (message_header.version.until_inclusive(1, 1))
+ {
+ buffer.setOffset(message_header.getHeaderSize());
- buffer.buffer.reset();
- buffer.setOffset(new_offset);
+ // Get the position after the reply header would be written.
+ reply_header.write(buffer);
- if (message_header.version.since_inclusive(1, 2))
- buffer.align(8);
+ int new_offset = message_header.getHeaderSize() + buffer.buffer.size();
- buffer.setVersion(message_header.version);
-
- buffer.setCodeSet(cxCodeSet.find(reply_header.service_context));
+ buffer.buffer.reset();
+ buffer.setOffset(new_offset);
+ }
}
}
diff --git a/libjava/classpath/gnu/CORBA/fixedTypeCode.java b/libjava/classpath/gnu/CORBA/fixedTypeCode.java
index ec88c22..eb61041 100644
--- a/libjava/classpath/gnu/CORBA/fixedTypeCode.java
+++ b/libjava/classpath/gnu/CORBA/fixedTypeCode.java
@@ -109,16 +109,12 @@ public class fixedTypeCode
return number.unscaledValue().abs().toString().length();
}
- public boolean equals(Object other)
+ /**
+ * Compare with other type code for equality.
+ */
+ public boolean equal(TypeCode other)
{
- if (other == this)
- {
- return true;
- }
- if (!(other instanceof TypeCode))
- {
- return false;
- }
+ if (other == this) return true;
try
{
TypeCode that = (TypeCode) other;
diff --git a/libjava/classpath/gnu/CORBA/gnuAny.java b/libjava/classpath/gnu/CORBA/gnuAny.java
index a48c50d..7e5ef33 100644
--- a/libjava/classpath/gnu/CORBA/gnuAny.java
+++ b/libjava/classpath/gnu/CORBA/gnuAny.java
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.CORBA;
+import gnu.CORBA.CDR.Vio;
import gnu.CORBA.CDR.cdrBufInput;
import gnu.CORBA.CDR.cdrBufOutput;
@@ -63,6 +64,7 @@ import org.omg.CORBA.TypeCode;
import org.omg.CORBA.TypeCodeHolder;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA.ValueBaseHolder;
+import org.omg.CORBA.portable.BoxedValueHelper;
import org.omg.CORBA.portable.Streamable;
import java.io.IOException;
@@ -499,20 +501,33 @@ public class gnuAny
}
/** {@inheritDoc} */
- public void insert_Value(Serializable x, TypeCode typecode)
+ public void insert_Value(Serializable x, TypeCode c_typecode)
{
- type(typecode);
- insert_Value(x);
+ if (typecode != null && typecode.kind() == TCKind.tk_value_box)
+ {
+ has = new gnuValueHolder(x, typecode);
+ }
+ else
+ {
+ type(typecode);
+ insert_Value(x);
+ }
}
/** {@inheritDoc} */
public void insert_Value(Serializable x)
{
- resetTypes();
- if (has instanceof ValueBaseHolder)
- ((ValueBaseHolder) has).value = x;
+ if (typecode != null && typecode.kind() == TCKind.tk_value_box)
+ {
+ has = new gnuValueHolder(x, typecode);
+ }
else
- has = new ValueBaseHolder(x);
+ {
+ if (has instanceof ValueBaseHolder)
+ ((ValueBaseHolder) has).value = x;
+ else
+ has = new ValueBaseHolder(x);
+ }
}
/**
@@ -748,15 +763,38 @@ public class gnuAny
}
}
type(a_type);
- has._read(input);
- }
- catch (BadKind ex)
- {
- throw new MARSHAL("Bad kind: " + ex.getMessage());
+
+ if (!(has instanceof universalHolder) &&
+ (kind == TCKind._tk_value_box))
+ {
+ // The streamable only contains operations for
+ // reading the value, not the value header.
+ Field vField = has.getClass().getField("value");
+
+ BoxedValueHelper helper;
+
+ try
+ {
+ Class helperClass =
+ Class.forName(ObjectCreator.toHelperName(a_type.id()));
+ helper = (BoxedValueHelper) helperClass.newInstance();
+ }
+ catch (Exception ex)
+ {
+ helper = null;
+ }
+
+ Object content = Vio.read(input, helper);
+ vField.set(has, content);
+ }
+ else
+ has._read(input);
}
- catch (IOException ex)
+ catch (Exception ex)
{
- throw new MARSHAL("IO exception: " + ex.getMessage());
+ MARSHAL m = new MARSHAL();
+ m.initCause(ex);
+ throw m;
}
}
@@ -790,6 +828,12 @@ public class gnuAny
{
if (has != null)
has._write(output);
+ else
+ // These kinds support null.
+ if (xKind == TCKind._tk_null || xKind == TCKind._tk_objref ||
+ xKind == TCKind._tk_value || xKind == TCKind._tk_value_box
+ )
+ output.write_long(0);
}
/**
@@ -806,16 +850,26 @@ public class gnuAny
if (xKind >= 0)
{
if (xKind != kind)
- throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
- " when stored " + typeNamer.nameIt(xKind)
- );
+ if (!(
+ xKind == TCKind._tk_alias &&
+ has._type().kind().value() == kind
+ )
+ )
+ throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
+ " when stored " + typeNamer.nameIt(xKind)
+ );
}
else
{
if (type().kind().value() != kind)
- throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
- " stored " + typeNamer.nameIt(type())
- );
+ if (!(
+ type().kind().value() == TCKind._tk_alias &&
+ has._type().kind().value() == kind
+ )
+ )
+ throw new BAD_OPERATION("Extracting " + typeNamer.nameIt(kind) +
+ " stored " + typeNamer.nameIt(type())
+ );
}
}
diff --git a/libjava/classpath/gnu/CORBA/gnuCodecFactory.java b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java
index 8b71baf..067de49 100644
--- a/libjava/classpath/gnu/CORBA/gnuCodecFactory.java
+++ b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java
@@ -38,12 +38,12 @@ exception statement from your version. */
package gnu.CORBA;
-import org.omg.CORBA.*;
import org.omg.CORBA.LocalObject;
-import org.omg.IOP.*;
+import org.omg.CORBA.ORB;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecFactory;
import org.omg.IOP.CodecFactoryPackage.UnknownEncoding;
+import org.omg.IOP.ENCODING_CDR_ENCAPS;
import org.omg.IOP.Encoding;
/**
@@ -52,9 +52,7 @@ import org.omg.IOP.Encoding;
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
-public class gnuCodecFactory
- extends LocalObject
- implements CodecFactory
+public class gnuCodecFactory extends LocalObject implements CodecFactory
{
/**
* The associated ORB.
@@ -78,18 +76,15 @@ public class gnuCodecFactory
*
* @throws UnknownEncoding if the encoding is not a ENCODING_CDR_ENCAPS.
*/
- public Codec create_codec(Encoding for_encoding)
- throws UnknownEncoding
+ public Codec create_codec(Encoding for_encoding) throws UnknownEncoding
{
if (for_encoding.format != ENCODING_CDR_ENCAPS.value)
throw new UnknownEncoding("Only ENCODING_CDR_ENCAPS is " +
- "supported by this factory."
- );
+ "supported by this factory."
+ );
return new cdrEncapsCodec(orb,
- new Version(for_encoding.major_version,
- for_encoding.minor_version
- )
- );
+ new Version(for_encoding.major_version, for_encoding.minor_version)
+ );
}
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/gnuRequest.java b/libjava/classpath/gnu/CORBA/gnuRequest.java
index a47410e..7d756ed 100644
--- a/libjava/classpath/gnu/CORBA/gnuRequest.java
+++ b/libjava/classpath/gnu/CORBA/gnuRequest.java
@@ -40,32 +40,47 @@ package gnu.CORBA;
import gnu.CORBA.CDR.cdrBufInput;
import gnu.CORBA.CDR.cdrBufOutput;
-import gnu.CORBA.GIOP.CloseMessage;
import gnu.CORBA.GIOP.MessageHeader;
import gnu.CORBA.GIOP.ReplyHeader;
import gnu.CORBA.GIOP.RequestHeader;
import gnu.CORBA.GIOP.cxCodeSet;
+import gnu.CORBA.Interceptor.gnuClientRequestInfo;
+import gnu.CORBA.Poa.ORB_1_4;
import org.omg.CORBA.ARG_IN;
import org.omg.CORBA.ARG_INOUT;
import org.omg.CORBA.ARG_OUT;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_INV_ORDER;
+import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.Bounds;
+import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.Context;
import org.omg.CORBA.ContextList;
import org.omg.CORBA.Environment;
import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.INV_POLICY;
import org.omg.CORBA.MARSHAL;
+import org.omg.CORBA.NO_IMPLEMENT;
import org.omg.CORBA.NO_RESOURCES;
import org.omg.CORBA.NVList;
import org.omg.CORBA.NamedValue;
import org.omg.CORBA.ORB;
+import org.omg.CORBA.Policy;
import org.omg.CORBA.Request;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.UnknownUserException;
-import org.omg.CORBA.UserException;
+import org.omg.CORBA.portable.ObjectImpl;
+import org.omg.IOP.ServiceContext;
+import org.omg.IOP.TAG_CODE_SETS;
+import org.omg.IOP.TAG_INTERNET_IOP;
+import org.omg.IOP.TaggedComponent;
+import org.omg.IOP.TaggedProfile;
+import org.omg.PortableInterceptor.ClientRequestInfo;
+import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
+import org.omg.PortableInterceptor.ForwardRequest;
+import org.omg.PortableInterceptor.InvalidSlot;
import java.io.IOException;
import java.io.InputStream;
@@ -74,14 +89,14 @@ import java.io.OutputStream;
import java.net.BindException;
import java.net.Socket;
+import java.util.ArrayList;
+
/**
* The implementation of the CORBA request.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
-public class gnuRequest
- extends Request
- implements Cloneable
+public class gnuRequest extends Request implements Cloneable
{
/**
* The maximal supported GIOP version.
@@ -89,25 +104,34 @@ public class gnuRequest
public static Version MAX_SUPPORTED = new Version(1, 2);
/**
- * The initial pause that the Request makes when
- * the required port is not available.
+ * The initial pause that the Request makes when the required port is not
+ * available.
*/
public static int PAUSE_INITIAL = 50;
/**
- * The number of repretetive attempts to get a required
- * port, if it is not immediately available.
+ * The number of repretetive attempts to get a required port, if it is not
+ * immediately available.
*/
public static int PAUSE_STEPS = 12;
/**
- * The maximal pausing interval between two repetetive attempts.
- * The interval doubles after each unsuccessful attempt, but
- * will not exceed this value.
+ * The maximal pausing interval between two repetetive attempts. The interval
+ * doubles after each unsuccessful attempt, but will not exceed this value.
*/
public static int PAUSE_MAX = 1000;
/**
+ * The interceptor, listening the major request submission points.
+ */
+ ClientRequestInterceptorOperations m_interceptor;
+
+ /**
+ * The request info, used by interceptor.
+ */
+ ClientRequestInfo m_info = new gnuClientRequestInfo(this);
+
+ /**
* The empty byte array.
*/
private static final binaryReply EMPTY =
@@ -124,14 +148,13 @@ public class gnuRequest
protected ContextList m_context_list;
/**
- * The request environment for holding the exception
- * the has possibly been thrown by the method being invoked.
+ * The request environment for holding the exception the has possibly been
+ * thrown by the method being invoked.
*/
protected Environment m_environment = new gnuEnvironment();
/**
- * The list of all exceptions that can be thrown by the
- * method being invoked.
+ * The list of all exceptions that can be thrown by the method being invoked.
*/
protected ExceptionList m_exceptions = new gnuExceptionList();
@@ -141,6 +164,16 @@ public class gnuRequest
protected NamedValue m_result = new gnuNamedValue();
/**
+ * The exception id, received from the server, null if none.
+ */
+ protected String m_exception_id;
+
+ /**
+ * The thrown system exception.
+ */
+ protected SystemException m_sys_ex;
+
+ /**
* The invocation target.
*/
protected org.omg.CORBA.Object m_target;
@@ -151,20 +184,32 @@ public class gnuRequest
protected String m_operation;
/**
- * The flag, indicating that the request has been sent
- * and the result is already received.
+ * This field temporary remembers the value of the forwarded ior reference. If
+ * it is not null, the request was forwarded and the effective target is not
+ * the same as the default target.
+ */
+ public IOR m_forward_ior;
+
+ /**
+ * Is set when object, and not IOR is directly available.
+ */
+ public org.omg.CORBA.Object m_forwarding_target;
+
+ /**
+ * The flag, indicating that the request has been sent and the result is
+ * already received.
*/
protected boolean complete;
/**
- * The flag, indicating that the response to this request must be
- * ignored (used with {@link #send_oneway()}).
+ * The flag, indicating that the response to this request must be ignored
+ * (used with {@link #send_oneway()}).
*/
protected boolean oneWay;
/**
- * The flag, indicating that the request has been sent
- * and no result is yet received.
+ * The flag, indicating that the request has been sent and no result is yet
+ * received.
*/
protected boolean running;
@@ -174,12 +219,27 @@ public class gnuRequest
protected gnuNVList m_args = new gnuNVList();
/**
- * The request arguments in the case when they are directly written into
- * the parameter buffer.
+ * The request arguments in the case when they are directly written into the
+ * parameter buffer.
*/
protected streamRequest m_parameter_buffer;
/**
+ * The array of slots.
+ */
+ protected Any[] m_slots;
+
+ /**
+ * The request header currently in use.
+ */
+ protected RequestHeader m_rqh;
+
+ /**
+ * The reply header currently in use.
+ */
+ protected ReplyHeader m_rph;
+
+ /**
* The IOR of the target.
*/
private IOR ior;
@@ -192,17 +252,16 @@ public class gnuRequest
/**
* The encoding, used to send the message.
*
- * The default encoding is inherited from the set IOR
- * (that string reference can be encoded in either Big or
- * Little endian). If the IOR encoding is not known
- * (for example, by obtaining the reference from the naming
- * service), the Big Endian is used.
+ * The default encoding is inherited from the set IOR (that string reference
+ * can be encoded in either Big or Little endian). If the IOR encoding is not
+ * known (for example, by obtaining the reference from the naming service),
+ * the Big Endian is used.
*/
private boolean Big_endian = true;
/**
- * Set the IOR data, sufficient to find the invocation target.
- * This also sets default endian encoding for invocations.
+ * Set the IOR data, sufficient to find the invocation target. This also sets
+ * default endian encoding for invocations.
*
* @see IOR.parse(String)
*/
@@ -213,6 +272,11 @@ public class gnuRequest
}
/**
+ * Used when redirecting request to another target.
+ */
+ gnuRequest redirected;
+
+ /**
* Get the IOR data, sufficient to find the invocation target.
*
* @return the IOR data.
@@ -228,18 +292,26 @@ public class gnuRequest
public void setORB(ORB an_orb)
{
orb = an_orb;
+
+ // Take the interceptor from the ORB.
+ if (orb instanceof Restricted_ORB)
+ m_interceptor = ((Restricted_ORB) orb).iClient;
+
+ if (m_interceptor != null && orb instanceof ORB_1_4)
+ {
+ m_slots = ((ORB_1_4) orb).ic_current.clone_slots();
+ }
}
/**
- * Set the encoding that will be used to send the message.
- * The default encoding is inherited from the set IOR
- * (that string reference can be encoded in either Big or
- * Little endian). If the IOR encoding is not known
- * (for example, by obtaining the reference from the naming
- * service), the Big Endian is used.
+ * Set the encoding that will be used to send the message. The default
+ * encoding is inherited from the set IOR (that string reference can be
+ * encoded in either Big or Little endian). If the IOR encoding is not known
+ * (for example, by obtaining the reference from the naming service), the Big
+ * Endian is used.
*
- * @param use_big_endian true to use the Big Endian, false
- * to use the Little Endian encoding.
+ * @param use_big_endian true to use the Big Endian, false to use the Little
+ * Endian encoding.
*/
public void setBigEndian(boolean use_big_endian)
{
@@ -257,17 +329,32 @@ public class gnuRequest
}
/**
- * Get the parameter stream, where the invocation arguments should
- * be written if they are written into the stream directly.
+ * Get the parameter stream, where the invocation arguments should be written
+ * if they are written into the stream directly.
*/
public streamRequest getParameterStream()
{
m_parameter_buffer = new streamRequest();
m_parameter_buffer.request = this;
m_parameter_buffer.setVersion(ior.Internet.version);
- m_parameter_buffer.setCodeSet(cxCodeSet.negotiate(ior.CodeSets));
+ m_parameter_buffer.setCodeSet(cxCodeSet.negotiate(ior.Internet.CodeSets));
m_parameter_buffer.setOrb(orb);
m_parameter_buffer.setBigEndian(Big_endian);
+
+ // For the old iiop versions, it is important to set the size
+ // correctly.
+ if (ior.Internet.version.until_inclusive(1, 1))
+ {
+ cdrBufOutput measure = new cdrBufOutput();
+ measure.setOffset(12);
+ if (m_rqh == null)
+ m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader();
+ m_rqh.operation = m_operation;
+ m_rqh.object_key = ior.key;
+ m_rqh.write(measure);
+ m_parameter_buffer.setOffset(12 + measure.buffer.size());
+ }
+
return m_parameter_buffer;
}
@@ -380,33 +467,29 @@ public class gnuRequest
}
/** {@inheritDoc} */
- public void get_response()
- throws org.omg.CORBA.WrongTransaction
+ public void get_response() throws org.omg.CORBA.WrongTransaction
{
/**
- * The response is ready after it is received.
- * FIXME implement context checks and any other functionality,
- * if required.
+ * The response is ready after it is received. FIXME implement context
+ * checks and any other functionality, if required.
*/
}
/**
- * Submit the request, suspending the current thread until the
- * answer is received.
+ * Submit the request, suspending the current thread until the answer is
+ * received.
*
- * This implementation requires to set the IOR property
- * ({@link #setIOR(IOR)} before calling this method.
+ * This implementation requires to set the IOR property ({@link #setIOR(IOR)}
+ * before calling this method.
*
- * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been
- * previously set.
+ * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously
+ * set.
*
- * @throws SystemException if this exception has been thrown on
- * remote side. The exact exception type and the minor code are
- * the same as they have been for the exception, thrown on remoted
- * side.
+ * @throws SystemException if this exception has been thrown on remote side.
+ * The exact exception type and the minor code are the same as they have been
+ * for the exception, thrown on remoted side.
*/
- public synchronized void invoke()
- throws BAD_INV_ORDER
+ public synchronized void invoke() throws BAD_INV_ORDER
{
waitWhileBusy();
complete = false;
@@ -417,7 +500,32 @@ public class gnuRequest
try
{
- p_invoke();
+ Forwardings:
+ while (true)
+ {
+ try
+ {
+ p_invoke();
+ break Forwardings;
+ }
+ catch (ForwardRequest e)
+ {
+ try
+ {
+ ObjectImpl impl = (ObjectImpl) e.forward;
+ Simple_delegate delegate =
+ (Simple_delegate) impl._get_delegate();
+ ior = delegate.getIor();
+ }
+ catch (Exception ex)
+ {
+ BAD_PARAM bad =
+ new BAD_PARAM("Unsupported forwarding target");
+ bad.initCause(ex);
+ throw bad;
+ }
+ }
+ }
}
finally
{
@@ -452,7 +560,8 @@ public class gnuRequest
return m_result;
}
- /** {@inheritDoc}
+ /**
+ * {@inheritDoc}
*
*/
public Any return_value()
@@ -474,9 +583,8 @@ public class gnuRequest
}
/**
- * Send a request and forget about it, not waiting for a response.
- * This can be done also for methods that normally are expected
- * to return some values.
+ * Send a request and forget about it, not waiting for a response. This can be
+ * done also for methods that normally are expected to return some values.
*
* TODO It is generally recommended to reuse the threads. Reuse?
*/
@@ -495,9 +603,8 @@ public class gnuRequest
}
/**
- * Set the argument list.
- * This field is initialised as empty non null instance by default,
- * so the method is only used in cases when the direct replacement
+ * Set the argument list. This field is initialised as empty non null instance
+ * by default, so the method is only used in cases when the direct replacement
* is desired.
*
* @param a_args the argument list.
@@ -525,8 +632,8 @@ public class gnuRequest
}
/**
- * Set the context list that is later returned by the
- * method {@link #contexts()}.
+ * Set the context list that is later returned by the method
+ * {@link #contexts()}.
*
* @param a_context_list a new context list.
*/
@@ -536,10 +643,9 @@ public class gnuRequest
}
/**
- * Set the exception container.
- * This field is initialised as empty non null instance by default,
- * so the method is only used in cases when the direct replacement
- * is desired.
+ * Set the exception container. This field is initialised as empty non null
+ * instance by default, so the method is only used in cases when the direct
+ * replacement is desired.
*
* @param a_environment the new exception container.
*/
@@ -549,10 +655,9 @@ public class gnuRequest
}
/**
- * Set the list of exceptions.
- * This field is initialised as empty non null instance by default,
- * so the method is only used in cases when the direct replacement
- * is desired.
+ * Set the list of exceptions. This field is initialised as empty non null
+ * instance by default, so the method is only used in cases when the direct
+ * replacement is desired.
*
* @param a_exceptions a list of exceptions.
*/
@@ -572,10 +677,9 @@ public class gnuRequest
}
/**
- * Set the named value, returned as result.
- * This field is initialised as empty non null instance by default,
- * so the method is only used in cases when the direct replacement
- * is desired.
+ * Set the named value, returned as result. This field is initialised as empty
+ * non null instance by default, so the method is only used in cases when the
+ * direct replacement is desired.
*
* @param a_result the result keeper.
*/
@@ -585,8 +689,8 @@ public class gnuRequest
}
/**
- * Set the type of the named value, returned as a result.
- * Instantiates a new instance of the result value.
+ * Set the type of the named value, returned as a result. Instantiates a new
+ * instance of the result value.
*/
public void set_return_type(TypeCode returns)
{
@@ -608,17 +712,16 @@ public class gnuRequest
}
/**
- * Do the actual invocation.
- * This implementation requires to set the IOR property
- * ({@link #setIOR(IOR)} before calling this method.
+ * Do the actual invocation. This implementation requires to set the IOR
+ * property ({@link #setIOR(IOR)} before calling this method.
*
- * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been
- * previously set or if the direct argument addition is mixed with
- * the direct argument writing into the output stream.
+ * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set
+ * or if the direct argument addition is mixed with the direct argument
+ * writing into the output stream.
*
* @return the server response in binary form.
*/
- public synchronized binaryReply submit()
+ public synchronized binaryReply submit() throws ForwardRequest
{
gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader();
@@ -629,32 +732,36 @@ public class gnuRequest
header.version = useVersion(ior.Internet.version);
RequestHeader rh = header.create_request_header();
-
- rh.object_key = ior.key;
rh.operation = m_operation;
+ rh.object_key = ior.key;
+
+ // Update interceptor.
+ m_rqh = rh;
+
+ if (m_interceptor != null)
+ m_interceptor.send_request(m_info);
// Prepare the submission.
cdrBufOutput request_part = new cdrBufOutput();
request_part.setOffset(header.getHeaderSize());
request_part.setVersion(header.version);
- request_part.setCodeSet(cxCodeSet.negotiate(ior.CodeSets));
+ request_part.setCodeSet(cxCodeSet.negotiate(ior.Internet.CodeSets));
request_part.setOrb(orb);
request_part.setBigEndian(header.isBigEndian());
// This also sets the stream encoding to the encoding, specified
// in the header.
rh.write(request_part);
-
+
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."
- );
+ "write them into stream, but not both " + "at once."
+ );
}
if (m_parameter_buffer != null)
@@ -710,8 +817,8 @@ public class gnuRequest
if (socket == null)
throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port +
- " in use"
- );
+ " in use"
+ );
socket.setKeepAlive(true);
OutputStream socketOutput = socket.getOutputStream();
@@ -745,8 +852,9 @@ public class gnuRequest
{
MARSHAL m =
new MARSHAL("Unable to open a socket at " + ior.Internet.host + ":" +
- ior.Internet.port
- );
+ ior.Internet.port, 10000 + ior.Internet.port,
+ CompletionStatus.COMPLETED_NO
+ );
m.initCause(io_ex);
throw m;
}
@@ -776,9 +884,9 @@ public class gnuRequest
}
/**
- * Get the used version. Normally, it is better to respond using the
- * same version as it is specified in IOR, but not above the maximal
- * supported version.
+ * Get the used version. Normally, it is better to respond using the same
+ * version as it is specified in IOR, but not above the maximal supported
+ * version.
*/
public Version useVersion(Version desired)
{
@@ -790,12 +898,11 @@ public class gnuRequest
/**
* Wait while the response to request, submitted using
- * {@link #send_deferred()} or {@link #invoke()} (from other thread)
- * is returned.
+ * {@link #send_deferred()} or {@link #invoke()} (from other thread) is
+ * returned.
*
- * FIXME It is possible to rewrite this using
- * Object.wait() and Object.notify(), but be sure to prepare the test
- * as well.
+ * FIXME It is possible to rewrite this using Object.wait() and
+ * Object.notify(), but be sure to prepare the test as well.
*/
public synchronized void waitWhileBusy()
{
@@ -819,26 +926,25 @@ public class gnuRequest
}
/**
- * Do actual invocation. This method recursively calls itself if
- * the redirection is detected.
+ * Do actual invocation. This method recursively calls itself if the
+ * redirection is detected.
*/
- private void p_invoke()
- throws SystemException
+ private void p_invoke() throws SystemException, ForwardRequest
{
binaryReply response = submit();
- ReplyHeader rh = response.header.create_reply_header();
+ if (m_rph == null)
+ m_rph = response.header.create_reply_header();
+
cdrBufInput input = response.getStream();
input.setOrb(orb);
- rh.read(input);
+ m_rph.read(input);
// The stream must be aligned sinve v1.2, but only once.
boolean align = response.header.version.since_inclusive(1, 2);
- boolean moved_permanently = false;
-
- switch (rh.reply_status)
+ switch (m_rph.reply_status)
{
case ReplyHeader.NO_EXCEPTION :
@@ -881,6 +987,9 @@ public class gnuRequest
}
}
+ if (m_interceptor != null)
+ m_interceptor.receive_reply(m_info);
+
break;
case ReplyHeader.SYSTEM_EXCEPTION :
@@ -889,12 +998,15 @@ public class gnuRequest
input.align(8);
align = false;
}
+ readExceptionId(input);
- SystemException exception = ObjectCreator.readSystemException(input);
+ m_sys_ex = ObjectCreator.readSystemException(input);
+ m_environment.exception(m_sys_ex);
- m_environment.exception(exception);
+ if (m_interceptor != null)
+ m_interceptor.receive_exception(m_info);
- throw exception;
+ throw m_sys_ex;
case ReplyHeader.USER_EXCEPTION :
if (align)
@@ -902,15 +1014,20 @@ public class gnuRequest
input.align(8);
align = false;
}
+ readExceptionId(input);
// Prepare an Any that will hold the exception.
gnuAny exc = new gnuAny();
+ exc.setOrb(orb);
exc.insert_Streamable(new streamReadyHolder(input));
UnknownUserException unuex = new UnknownUserException(exc);
m_environment.exception(unuex);
+ if (m_interceptor != null)
+ m_interceptor.receive_exception(m_info);
+
break;
case ReplyHeader.LOCATION_FORWARD_PERM :
@@ -925,21 +1042,40 @@ public class gnuRequest
}
catch (IOException ex)
{
- throw new MARSHAL(ex + " while reading the forwarding info");
+ new MARSHAL("Cant read forwarding info", 5103,
+ CompletionStatus.COMPLETED_NO
+ );
}
setIor(forwarded);
+ m_forward_ior = forwarded;
+
+ if (m_interceptor != null)
+ m_interceptor.receive_other(m_info);
+
// Repeat with the forwarded information.
p_invoke();
return;
default :
- throw new MARSHAL("Unknow reply status: " + rh.reply_status);
+ throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status,
+ CompletionStatus.COMPLETED_NO
+ );
}
}
/**
+ * Read exception id without changing the stream pointer position.
+ */
+ void readExceptionId(cdrBufInput input)
+ {
+ input.mark(2048);
+ m_exception_id = input.read_string();
+ input.reset();
+ }
+
+ /**
* Write the operation parameters.
*
* @param header the message header
@@ -947,10 +1083,9 @@ public class gnuRequest
*
* @throws MARSHAL if the attempt to write the parameters has failde.
*/
- private void write_parameter_buffer(MessageHeader header,
- cdrBufOutput request_part
- )
- throws MARSHAL
+ protected void write_parameter_buffer(MessageHeader header,
+ cdrBufOutput request_part
+ ) throws MARSHAL
{
try
{
@@ -974,8 +1109,9 @@ public class gnuRequest
*
* @throws MARSHAL if the attempt to write the parameters has failde.
*/
- private void write_parameters(MessageHeader header, cdrBufOutput request_part)
- throws MARSHAL
+ protected void write_parameters(MessageHeader header,
+ cdrBufOutput request_part
+ ) throws MARSHAL
{
// Align after 1.2, but only once.
boolean align = header.version.since_inclusive(1, 2);
@@ -988,7 +1124,7 @@ public class gnuRequest
{
para = m_args.item(i);
- //This bit is set both for ARG_IN and ARG_INOUT
+ // This bit is set both for ARG_IN and ARG_INOUT
if ((para.flags() & ARG_IN.value) != 0)
{
if (align)
@@ -1002,7 +1138,277 @@ public class gnuRequest
}
catch (Bounds ex)
{
- throw new MARSHAL("Unable to write method arguments to CDR output.");
+ InternalError ierr = new InternalError();
+ ierr.initCause(ex);
+ throw ierr;
}
}
+
+ /* **************Implementation of the request info operations. ***** */
+
+ /**
+ * Add context to request.
+ */
+ public void add_request_service_context(ServiceContext service_context,
+ boolean replace
+ )
+ {
+ m_rqh.addContext(service_context, replace);
+ }
+
+ /**
+ * Get the Internet profile as an effective profile.
+ */
+ public TaggedProfile effective_profile()
+ {
+ cdrBufOutput buf = new cdrBufOutput(512);
+ buf.setOrb(orb);
+ ior.Internet.write(buf);
+
+ TaggedProfile p = new TaggedProfile();
+ p.tag = TAG_INTERNET_IOP.value;
+ p.profile_data = buf.buffer.toByteArray();
+ return p;
+ }
+
+ /**
+ * Return either target or forwarded targed.
+ */
+ public org.omg.CORBA.Object effective_target()
+ {
+ return new IOR_contructed_object(orb, ior);
+ }
+
+ /**
+ * Get effective component with the give id from the Internet profile.
+ */
+ public TaggedComponent get_effective_component(int id)
+ throws BAD_PARAM
+ {
+ if (id == TAG_CODE_SETS.value)
+ {
+ // Codesets are encoded separately.
+ cdrBufOutput buf = new cdrBufOutput(512);
+ buf.setOrb(orb);
+ ior.Internet.CodeSets.write(buf);
+
+ TaggedComponent t = new TaggedComponent();
+ t.tag = TAG_CODE_SETS.value;
+ t.component_data = buf.buffer.toByteArray();
+ return t;
+ }
+ else
+ {
+ for (int i = 0; i < ior.Internet.components.size(); i++)
+ {
+ TaggedComponent c =
+ (TaggedComponent) ior.Internet.components.get(i);
+ if (c.tag == id)
+ return c;
+ }
+ }
+ throw new BAD_PARAM("No component " + id + " in the Internet profile", 28,
+ CompletionStatus.COMPLETED_MAYBE
+ );
+ }
+
+ /**
+ * Get all components with the given id from the internet profile.
+ */
+ public TaggedComponent[] get_effective_components(int id)
+ throws BAD_PARAM
+ {
+ if (id == TAG_CODE_SETS.value)
+ return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) };
+ else
+ {
+ ArrayList components = new ArrayList(ior.Internet.components.size());
+ for (int i = 0; i < ior.Internet.components.size(); i++)
+ {
+ TaggedComponent c =
+ (TaggedComponent) ior.Internet.components.get(i);
+ if (c.tag == id)
+ components.add(c);
+ }
+ if (components.size() == 0)
+ throw new BAD_PARAM("No component " + id +
+ " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE
+ );
+ else
+ {
+ TaggedComponent[] t = new TaggedComponent[ components.size() ];
+ for (int i = 0; i < t.length; i++)
+ t [ i ] = (TaggedComponent) components.get(i);
+ return t;
+ }
+ }
+ }
+
+ /**
+ * This should be not implemented up till jdk 1.5 inclusive.
+ */
+ public Policy get_request_policy(int type) throws INV_POLICY
+ {
+ throw new NO_IMPLEMENT();
+ }
+
+ /** @inheritDoc */
+ public String received_exception_id()
+ {
+ return m_exception_id;
+ }
+
+ /** @inheritDoc */
+ public Any received_exception()
+ {
+ if (m_exception_id == null)
+ return null;
+
+ if (m_sys_ex != null)
+ {
+ Any a = orb.create_any();
+ ObjectCreator.insertSysException(a, m_sys_ex);
+ return a;
+ }
+
+ Exception mex = m_environment.exception();
+
+ UnknownUserException ex = (UnknownUserException) mex;
+ if (ex == null)
+ return null;
+ else
+ return ex.except;
+ }
+
+ /**
+ * Return the forwarded reference, null if none.
+ */
+ public org.omg.CORBA.Object forward_reference()
+ {
+ if (m_forwarding_target != null)
+ return m_forwarding_target;
+
+ if (m_forward_ior != null)
+ return new IOR_contructed_object(orb, m_forward_ior);
+ else
+ return null;
+ }
+
+ /**
+ * Get the slot from the slot array inside this request.
+ */
+ public Any get_slot(int id) throws InvalidSlot
+ {
+ try
+ {
+ return m_slots [ id ];
+ }
+ catch (Exception e)
+ {
+ throw new InvalidSlot("slot id " + id + ":" + e);
+ }
+ }
+
+ /**
+ * Get the reply status.
+ */
+ public short reply_status()
+ {
+ if (m_rph == null)
+ throw new BAD_INV_ORDER("Request not yet sent", 14,
+ CompletionStatus.COMPLETED_NO
+ );
+ return (short) m_rph.reply_status;
+ }
+
+ /**
+ * Get the request id.
+ */
+ public int request_id()
+ {
+ return m_rqh.request_id;
+ }
+
+ /**
+ * Return true if the response is expected.
+ */
+ public boolean response_expected()
+ {
+ return !oneWay;
+ }
+
+ /**
+ * Determines how far the request shall progress before control is returned to
+ * the client. However up till JDK 1.5 inclusive this method always returns
+ * SYNC_WITH_TRANSPORT.
+ *
+ * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
+ *
+ * @specnote as defined in the Suns 1.5 JDK API.
+ */
+ public short sync_scope()
+ {
+ return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
+ }
+
+ /** @inheritDoc */
+ public ServiceContext get_request_service_context(int ctx_name)
+ throws BAD_PARAM
+ {
+ return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
+ m_rqh.service_context
+ );
+ }
+
+ /** @inheritDoc */
+ public ServiceContext get_reply_service_context(int ctx_name)
+ throws BAD_PARAM
+ {
+ if (m_rph == null)
+ throw new BAD_INV_ORDER("Reply context not yet available");
+ return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
+ m_rph.service_context
+ );
+ }
+
+ /** @inheritDoc */
+ public String[] operation_context()
+ {
+ return ice_contexts();
+ }
+
+ /**
+ * Get contexts as required by interceptor.
+ */
+ public String[] ice_contexts()
+ {
+ if (m_context_list == null)
+ return new String[ 0 ];
+ else
+ {
+ try
+ {
+ String[] cn = new String[ m_context_list.count() ];
+ for (int i = 0; i < cn.length; i++)
+ cn [ i ] = m_context_list.item(i);
+ return cn;
+ }
+ catch (Bounds e)
+ {
+ throw new Unexpected(e);
+ }
+ }
+ }
+
+ /**
+ * Check if the call is done via DII.
+ */
+ public void checkDii()
+ {
+ if (m_parameter_buffer != null)
+ throw new NO_RESOURCES("The invocation method provides " +
+ "no access to this resource. DII call required.", 1,
+ CompletionStatus.COMPLETED_MAYBE
+ );
+ }
} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/holderFactory.java b/libjava/classpath/gnu/CORBA/holderFactory.java
index 177797a..159d223 100644
--- a/libjava/classpath/gnu/CORBA/holderFactory.java
+++ b/libjava/classpath/gnu/CORBA/holderFactory.java
@@ -68,74 +68,76 @@ import org.omg.CORBA.UShortSeqHolder;
import org.omg.CORBA.WCharSeqHolder;
import org.omg.CORBA.WStringSeqHolder;
import org.omg.CORBA.portable.Streamable;
+import org.omg.CORBA.ObjectHolder;
/**
- * Creates the suitable holder for storing the value of the given
- * type.
+ * Creates the suitable holder for storing the value of the given final_type.
*
* @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
*/
public class holderFactory
{
/**
- * The array, sufficiently large to use any {@link TCKind}._tk* constant
- * as an index.
+ * The array, sufficiently large to use any {@link TCKind}._tk* constant as
+ * an index.
*/
private static final Class[] holders;
+
private static final Class[] seqHolders;
static
- {
- holders = new Class[ 32 ];
- holders [ TCKind._tk_Principal ] = PrincipalHolder.class;
- holders [ TCKind._tk_TypeCode ] = TypeCodeHolder.class;
- holders [ TCKind._tk_any ] = AnyHolder.class;
- holders [ TCKind._tk_boolean ] = BooleanHolder.class;
- holders [ TCKind._tk_char ] = CharHolder.class;
- holders [ TCKind._tk_double ] = DoubleHolder.class;
- holders [ TCKind._tk_float ] = FloatHolder.class;
- holders [ TCKind._tk_fixed ] = FixedHolder.class;
- holders [ TCKind._tk_long ] = IntHolder.class;
- holders [ TCKind._tk_longdouble ] = DoubleHolder.class;
- holders [ TCKind._tk_longlong ] = LongHolder.class;
- holders [ TCKind._tk_octet ] = OctetHolder.class;
- holders [ TCKind._tk_short ] = ShortHolder.class;
- holders [ TCKind._tk_string ] = StringHolder.class;
- holders [ TCKind._tk_ulong ] = IntHolder.class;
- holders [ TCKind._tk_ulonglong ] = LongHolder.class;
- holders [ TCKind._tk_ushort ] = ShortHolder.class;
- holders [ TCKind._tk_wchar ] = WCharHolder.class;
- holders [ TCKind._tk_wstring ] = WStringHolder.class;
-
- seqHolders = new Class[ 32 ];
-
- seqHolders [ TCKind._tk_ulonglong ] = ULongLongSeqHolder.class;
- seqHolders [ TCKind._tk_short ] = ShortSeqHolder.class;
- seqHolders [ TCKind._tk_octet ] = OctetSeqHolder.class;
- seqHolders [ TCKind._tk_any ] = AnySeqHolder.class;
- seqHolders [ TCKind._tk_long ] = LongSeqHolder.class;
- seqHolders [ TCKind._tk_longlong ] = LongLongSeqHolder.class;
- seqHolders [ TCKind._tk_float ] = FloatSeqHolder.class;
- seqHolders [ TCKind._tk_double ] = DoubleSeqHolder.class;
- seqHolders [ TCKind._tk_char ] = CharSeqHolder.class;
- seqHolders [ TCKind._tk_boolean ] = BooleanSeqHolder.class;
- seqHolders [ TCKind._tk_wchar ] = WCharSeqHolder.class;
- seqHolders [ TCKind._tk_ushort ] = UShortSeqHolder.class;
- seqHolders [ TCKind._tk_ulong ] = ULongSeqHolder.class;
- seqHolders [ TCKind._tk_string ] = StringSeqHolder.class;
- seqHolders [ TCKind._tk_wstring ] = WStringSeqHolder.class;
- }
+ {
+ holders = new Class[32];
+ holders[TCKind._tk_Principal] = PrincipalHolder.class;
+ holders[TCKind._tk_TypeCode] = TypeCodeHolder.class;
+ holders[TCKind._tk_any] = AnyHolder.class;
+ holders[TCKind._tk_boolean] = BooleanHolder.class;
+ holders[TCKind._tk_char] = CharHolder.class;
+ holders[TCKind._tk_double] = DoubleHolder.class;
+ holders[TCKind._tk_float] = FloatHolder.class;
+ holders[TCKind._tk_fixed] = FixedHolder.class;
+ holders[TCKind._tk_long] = IntHolder.class;
+ holders[TCKind._tk_longdouble] = DoubleHolder.class;
+ holders[TCKind._tk_longlong] = LongHolder.class;
+ holders[TCKind._tk_octet] = OctetHolder.class;
+ holders[TCKind._tk_short] = ShortHolder.class;
+ holders[TCKind._tk_string] = StringHolder.class;
+ holders[TCKind._tk_ulong] = IntHolder.class;
+ holders[TCKind._tk_ulonglong] = LongHolder.class;
+ holders[TCKind._tk_ushort] = ShortHolder.class;
+ holders[TCKind._tk_wchar] = WCharHolder.class;
+ holders[TCKind._tk_wstring] = WStringHolder.class;
+ holders[TCKind._tk_objref] = ObjectHolder.class;
+
+ seqHolders = new Class[32];
+
+ seqHolders[TCKind._tk_ulonglong] = ULongLongSeqHolder.class;
+ seqHolders[TCKind._tk_short] = ShortSeqHolder.class;
+ seqHolders[TCKind._tk_octet] = OctetSeqHolder.class;
+ seqHolders[TCKind._tk_any] = AnySeqHolder.class;
+ seqHolders[TCKind._tk_long] = LongSeqHolder.class;
+ seqHolders[TCKind._tk_longlong] = LongLongSeqHolder.class;
+ seqHolders[TCKind._tk_float] = FloatSeqHolder.class;
+ seqHolders[TCKind._tk_double] = DoubleSeqHolder.class;
+ seqHolders[TCKind._tk_char] = CharSeqHolder.class;
+ seqHolders[TCKind._tk_boolean] = BooleanSeqHolder.class;
+ seqHolders[TCKind._tk_wchar] = WCharSeqHolder.class;
+ seqHolders[TCKind._tk_ushort] = UShortSeqHolder.class;
+ seqHolders[TCKind._tk_ulong] = ULongSeqHolder.class;
+ seqHolders[TCKind._tk_string] = StringSeqHolder.class;
+ seqHolders[TCKind._tk_wstring] = WStringSeqHolder.class;
+ }
/**
- * Create a holder for storing the value of the given built-in type.
- * This function returns the defined holders for the built-in primitive
- * types and they sequences.
+ * Create a holder for storing the value of the given built-in final_type. This
+ * function returns the defined holders for the built-in primitive types and
+ * they sequences.
*
* @param t the typecode
*
- * @return an instance of the corresponding built-in holder of null
- * if no such is defined for this type. The holder is created with a
- * parameterless constructor.
+ * @return an instance of the corresponding built-in holder of null if no such
+ * is defined for this final_type. The holder is created with a parameterless
+ * constructor.
*/
public static Streamable createHolder(TypeCode t)
{
@@ -145,24 +147,23 @@ public class holderFactory
int componentKind;
Streamable holder = null;
- Streamable component;
- if (kind < holders.length && holders [ kind ] != null)
- holder = (Streamable) holders [ kind ].newInstance();
+ if (kind < holders.length && holders[kind] != null)
+ holder = (Streamable) holders[kind].newInstance();
if (holder != null)
return holder;
switch (kind)
{
- case TCKind._tk_sequence :
- componentKind = t.content_type().kind().value();
- if (componentKind < seqHolders.length)
- return (Streamable) seqHolders [ componentKind ].newInstance();
- break;
-
- default :
- break;
+ case TCKind._tk_sequence:
+ componentKind = t.content_type().kind().value();
+ if (componentKind < seqHolders.length)
+ return (Streamable) seqHolders[componentKind].newInstance();
+ break;
+
+ default:
+ break;
}
}
catch (Exception ex)
diff --git a/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java b/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java
index 7e2beeb..fc020be 100644
--- a/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java
+++ b/libjava/classpath/gnu/CORBA/primitiveArrayTypeCode.java
@@ -1,39 +1,39 @@
/* primitiveArrayTypeCode.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. */
+ 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;
@@ -61,10 +61,10 @@ public class primitiveArrayTypeCode
private int length;
/**
- * Create a primitive array type code, defining the sequence
- * {@link TCKind.tk_sequence)} with
+ * Create a primitive array type code, defining the sequence
+ * {@link TCKind.tk_sequence)} with
* the given member type.
- *
+ *
* @param array_of the sequence member type.
*/
public primitiveArrayTypeCode(TCKind array_of)
@@ -76,7 +76,7 @@ public class primitiveArrayTypeCode
/**
* Create a primitive array type code, defining the array, sequence
* or other type with the given member type.
- *
+ *
* @param this_type the type of this type (normally either
* sequence of array).
* @param array_of the sequence member type.
diff --git a/libjava/classpath/gnu/CORBA/primitiveTypeCode.java b/libjava/classpath/gnu/CORBA/primitiveTypeCode.java
index 1fa5cd0..4bf97d0 100644
--- a/libjava/classpath/gnu/CORBA/primitiveTypeCode.java
+++ b/libjava/classpath/gnu/CORBA/primitiveTypeCode.java
@@ -1,40 +1,41 @@
/* primitiveTypeCode.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. */
-
+ 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;
diff --git a/libjava/classpath/gnu/CORBA/typeNamer.java b/libjava/classpath/gnu/CORBA/typeNamer.java
index 8b70101..f790dc9 100644
--- a/libjava/classpath/gnu/CORBA/typeNamer.java
+++ b/libjava/classpath/gnu/CORBA/typeNamer.java
@@ -83,7 +83,7 @@ public class typeNamer
new primitiveTypeCode(TCKind.tk_any),
new primitiveTypeCode(TCKind.tk_TypeCode),
new primitiveTypeCode(TCKind.tk_Principal),
- new primitiveTypeCode(TCKind.tk_objref),
+ new recordTypeCode(TCKind.tk_objref),
new primitiveTypeCode(TCKind.tk_struct),
new primitiveTypeCode(TCKind.tk_union),
new primitiveTypeCode(TCKind.tk_enum),
@@ -104,6 +104,15 @@ public class typeNamer
new primitiveTypeCode(TCKind.tk_abstract_interface)
};
+ static
+ {
+ // The Id of the "abstract object" is defined as empty string.
+ recordTypeCode object =
+ (recordTypeCode) primitveCodes [ TCKind._tk_objref ];
+ object.setId("");
+ object.setName("Object");
+ }
+
/**
* Get the primitive type code.
*
@@ -168,4 +177,4 @@ public class typeNamer
return "type of kind '" + type.kind().value() + "'";
}
}
-}
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/CORBA/universalHolder.java b/libjava/classpath/gnu/CORBA/universalHolder.java
index 6d8b774..c20dac44 100644
--- a/libjava/classpath/gnu/CORBA/universalHolder.java
+++ b/libjava/classpath/gnu/CORBA/universalHolder.java
@@ -60,7 +60,7 @@ import java.io.IOException;
*
* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
*/
-class universalHolder
+public class universalHolder
implements Streamable
{
/**
@@ -71,7 +71,7 @@ class universalHolder
/**
* Create the universal holder that uses the given buffer to store the data.
*/
- universalHolder(cdrBufOutput buffer)
+ public universalHolder(cdrBufOutput buffer)
{
value = buffer;
}
@@ -154,4 +154,21 @@ class universalHolder
{
return value.create_input_stream();
}
-}
+
+ /**
+ * Clone.
+ */
+ public universalHolder Clone()
+ {
+ try
+ {
+ cdrBufOutput nb = new cdrBufOutput(value.buffer.size());
+ value.buffer.writeTo(nb);
+ return new universalHolder(nb);
+ }
+ catch (IOException ex)
+ {
+ throw new Unexpected(ex);
+ }
+ }
+} \ No newline at end of file