diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/CORBA | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/CORBA')
163 files changed, 43440 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/CORBA/Asynchron.java b/libjava/classpath/gnu/CORBA/Asynchron.java new file mode 100644 index 000000000..275b57091 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Asynchron.java @@ -0,0 +1,185 @@ +/* Asynchron.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Request; +import org.omg.CORBA.WrongTransaction; + +import java.util.Iterator; +import java.util.LinkedList; + +/** + * Handles the asynchronous dynamic invocations. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Asynchron +{ + LinkedList sent = new LinkedList(); + + /** + * 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. + * + * @param requests the prepared array of requests. + * + * @see Request#send_oneway() + */ + public void send_multiple_requests_oneway(Request[] requests) + { + for (int i = 0; i < requests.length; i++) + { + requests [ i ].send_oneway(); + } + } + + /** + * 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. + * + * @see #poll_next_response() + * @see #get_next_response() + * @see Request#send_deferred() + */ + public void send_multiple_requests_deferred(Request[] requests) + { + synchronized (sent) + { + for (int i = 0; i < requests.length; i++) + { + sent.add(requests [ i ]); + + // TODO Reuse threads that are instantiated in the method below, + // one thread per call. + requests [ i ].send_deferred(); + } + } + } + + /** + * 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. + */ + public boolean poll_next_response() + { + synchronized (sent) + { + Iterator iter = sent.iterator(); + Request r; + while (iter.hasNext()) + { + r = (Request) iter.next(); + if (r.poll_response()) + return true; + } + } + return false; + } + + /** + * 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. + * + * @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. + */ + public Request get_next_response() + throws WrongTransaction + { + // The hard-coded waiting times for the incremental waiter. + // TODO it is possible to write more tricky system where the + // requests notify the Asynchron when they are complete. + // Wait for 5 ms intially. + int wait = 8; + + // Double the waiting time + int INC = 2; + + // Do not increase if the waiting time is already over 500 ms. + int MAX = 500; + while (true) + { + synchronized (sent) + { + Iterator iter = sent.iterator(); + Request r; + while (iter.hasNext()) + { + r = (Request) iter.next(); + if (r.poll_response()) + { + sent.remove(r); + return r; + } + } + } + try + { + Thread.sleep(wait); + if (wait < MAX) + wait = wait * INC; + } + catch (InterruptedException ex) + { + } + } + } +} diff --git a/libjava/classpath/gnu/CORBA/BigDecimalHelper.java b/libjava/classpath/gnu/CORBA/BigDecimalHelper.java new file mode 100644 index 000000000..c5c8f99ab --- /dev/null +++ b/libjava/classpath/gnu/CORBA/BigDecimalHelper.java @@ -0,0 +1,191 @@ +/* BigDecimalHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.java.lang.CPStringBuilder; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * Reads and writes BigDecimal as CORBA <code>fixed</code>. + * The format, described in CORBA specification, requires to store + * data in hexadecimal format, two digits per byte (oceted), most + * significant digit first. The last half-byte in the representation + * stores the sign, being 0xD for negative numbers and 0xC for + * zero and positive numbers. To have the even number of half bytes, + * 0x0 is appended to the beginning, if required. The position of the + * decimal point is not stored. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class BigDecimalHelper +{ + { + } + + /** + * @todo remove from the release version. + */ + public static void main(String[] args) + { + try + { + ByteArrayOutputStream b = new ByteArrayOutputStream(); + BigDecimal d = new BigDecimal("12234.54689"); + + write(b, d); + + byte[] a = b.toByteArray(); + + for (int i = 0; i < a.length; i++) + { + int k = a [ i ] & 0xFF; + System.out.print(Integer.toHexString(k) + " "); + } + + System.out.println("Now reading"); + + ByteArrayInputStream bin = new ByteArrayInputStream(a); + + BigDecimal r = read(bin, d.scale()); + + System.out.println(r); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + /** + * Read the CORBA fixed, autodetecting the number of bytes + * and assuming the given scale. + */ + public static BigDecimal read(java.io.InputStream in, int scale) + throws IOException + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + int f; + + do + { + f = in.read(); + if (f >= 0) + bout.write(f); + } + // The last byte has 0xC or 0xD in the last halfbyte. + while ((f & 0xF) <= 0x9); + + return createFixed(scale, bout.toByteArray()); + } + + /** + * Write the big decimal as CORBA <code>fixed<.code>. + * The scale will not be stored. + * + * @param out a stream to write into. + * @param x a big decimal to write. + * + * @throws IOException if the stream write method throws one. + * @throws BadKind if this BigDecimal has more digits than + * specified. + */ + public static void write(java.io.OutputStream out, BigDecimal x) + throws IOException, BadKind + { + CPStringBuilder v = new CPStringBuilder(x.unscaledValue().toString()); + + boolean negative = v.charAt(0) == '-'; + + if (negative) + v = v.deleteCharAt(0); + + if ( (v.length() & 1) == 0) + v.insert(0, '0'); + + int c; + + for (int i = 0; i < v.length() - 1; i = i + 2) + { + c = ((v.charAt(i) - '0') << 4) | (v.charAt(i + 1) - '0'); + out.write(c); + } + + c = ((v.charAt(v.length() - 1) - '0') << 4) | (negative ? 0xD : 0xC); + + out.write(c); + } + + /** + * Convert the loaded byte array, representing + * CORBA <code>fixed</code>, into an instance of + * the {@link BigDecimal} + */ + private static BigDecimal createFixed(int scale, byte[] d) + { + CPStringBuilder s = new CPStringBuilder(2 * d.length); + + int last = d.length - 1; + + if ((d [ last ] & 0xF) == 0xD) + s.append('-'); + + if (last > 0) + for (int i = 0; i < last; i++) + { + s.append((char) (((d [ i ] >> 4) & 0xF) + '0')); + s.append((char) (((d [ i ]) & 0xF) + '0')); + } + + s.append((char) (((d [ last ] >> 4) & 0xF) + '0')); + + BigInteger b = new BigInteger(s.toString()); + BigDecimal dec = new BigDecimal(b, scale); + + return dec; + } +} diff --git a/libjava/classpath/gnu/CORBA/ByteArrayComparator.java b/libjava/classpath/gnu/CORBA/ByteArrayComparator.java new file mode 100644 index 000000000..e601399df --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ByteArrayComparator.java @@ -0,0 +1,90 @@ +/* ByteArrayComparator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.util.Comparator; + +/** + * A byte array comparator for mapping with CORBA object keys. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ByteArrayComparator + implements Comparator +{ + /** + * Compare arrays first by absolute equality, then by length + * and then (byte to byte) by content. + * + * @return 0 if arrays are equal, some comparison value otherwise. + */ + public int compare(Object an_a, Object a_b) + { + if (an_a == a_b) + return 0; + + byte[] a = null; + byte[] b = null; + try + { + a = (byte[]) an_a; + b = (byte[]) a_b; + } + catch (Exception ex) + { + throw new InternalError(an_a.getClass().getName() + "," + + a_b.getClass().getName() + ); + } + + if (a.length != b.length) + return a.length - b.length; + else + { + // The array sizes must be equal. + for (int i = 0; i < b.length; i++) + { + if (a [ i ] != b [ i ]) + return a [ i ] - b [ i ]; + } + } + + return 0; + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java new file mode 100644 index 000000000..fae16eed9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java @@ -0,0 +1,1768 @@ +/* AbstractCdrInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.BigDecimalHelper; +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.GIOP.CharSets_OSF; +import gnu.CORBA.GIOP.CodeSetServiceContext; +import gnu.CORBA.IOR; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.Minor; +import gnu.CORBA.TypeCodeHelper; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; +import gnu.CORBA.gnuAny; +import gnu.CORBA.StubLocator; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnySeqHolder; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BooleanSeqHolder; +import org.omg.CORBA.CharSeqHolder; +import org.omg.CORBA.DoubleSeqHolder; +import org.omg.CORBA.FloatSeqHolder; +import org.omg.CORBA.LongLongSeqHolder; +import org.omg.CORBA.LongSeqHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.OctetSeqHolder; +import org.omg.CORBA.ShortSeqHolder; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.ULongLongSeqHolder; +import org.omg.CORBA.ULongSeqHolder; +import org.omg.CORBA.UShortSeqHolder; +import org.omg.CORBA.WCharSeqHolder; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.ObjectImpl; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Serializable; + +import java.math.BigDecimal; + +/** + * A simple CORBA CDR (common data representation) input stream, reading data + * from the given {@link java.io.InputStream}. The primitive types are aligned + * on they natural boundaries by implementing the abstract method + * {@link #align(int boundary)}. + * + * The same class also implements {@link org.omg.CORBA.DataInputStream} to read + * the object content in a user defined way. + * + * TODO This class uses 16 bits per Unicode character only, as it was until jdk + * 1.4 inclusive. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class AbstractCdrInput + extends org.omg.CORBA_2_3.portable.InputStream + implements org.omg.CORBA.DataInputStream +{ + /** + * The runtime, associated with this stream. This field is only used when + * reading and writing value types and filled-in in gnu.CORBA.CDR.Vio. + */ + public transient gnuRuntime runtime; + + /** + * The message, explaining that the exception has been thrown due unexpected + * end of the input stream. This usually happens the server and client + * disagree on communication or data representation rules. + */ + protected static final String UNEXP_EOF = "Unexpected end of stream"; + + /** + * This instance is used to convert primitive data types into the byte + * sequences. + */ + protected AbstractDataInput b; + + /** + * The input stream, from where the data are actually being read. + */ + protected java.io.InputStream actual_stream; + + /** + * The associated orb, if any. + */ + protected ORB orb; + + /** + * The GIOP version. + */ + protected Version giop = new Version(1, 2); + + /** + * The code set information. + */ + protected CodeSetServiceContext codeset = CodeSetServiceContext.STANDARD; + + /** + * The name of the currently used narrow charset, null if the native narrow + * charset is used. + */ + private String narrow_charset = null; + + /** + * The name of the currently used wide charset, null if the native wide + * charset is used. + */ + private String wide_charset = null; + + /** + * True if the native code set is used for narrow characters. If the set is + * native, no the intermediate Reader object is instantiated when writing + * characters. + */ + private boolean narrow_native; + + /** + * True if the native code set is used for wide characters. If the set is + * native, no the intermediate Reader object is instantiated when writing + * characters. + */ + private boolean wide_native; + + /** + * If true, the stream expect the multi-byte data in the form "less + * significant byte first" (Little Endian). This is the opposite to the java + * standard (Big Endian). + */ + private boolean little_endian; + + /** + * Creates the stream. The stream reads Big Endian by default. + * + * @param readFrom a stream to read CORBA input from. + */ + public AbstractCdrInput(java.io.InputStream readFrom) + { + setInputStream(readFrom); + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Creates the stream, requiring the subsequent call of + * {@link #setInputStream(java.io.InputStream)}. + */ + public AbstractCdrInput() + { + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Set the Big Endian or Little Endian encoding. The stream reads Big Endian + * by default. + * + * @param use_big_endian if true, the stream expect the multi-byte data in + * the form "most significant byte first" (Big Endian). This is the + * java standard. + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setInputStream(actual_stream); + } + + /** + * Get the used encoding. + * + * @return true for Big Endian, false for Little Endian. + */ + public boolean isBigEndian() + { + return !little_endian; + } + + /** + * Clone all important settings to another stream. + */ + public void cloneSettings(AbstractCdrInput stream) + { + stream.setBigEndian(isBigEndian()); + stream.setCodeSet(getCodeSet()); + stream.setVersion(giop); + stream.setOrb(orb); + } + + /** + * Set the input stream that receives the CORBA input. + * + * @param readFrom the stream. + */ + public void setInputStream(java.io.InputStream readFrom) + { + if (little_endian) + b = new LittleEndianInputStream(readFrom); + else + b = new BigEndianInputStream(readFrom); + + actual_stream = readFrom; + } + + /** + * Set the alignment offset, if the index of the first byte in the stream is + * different from 0. + */ + public abstract void setOffset(int offset); + + /** + * Set the orb, associated with this stream. + * + * @param an_orb + */ + public void setOrb(ORB an_orb) + { + orb = an_orb; + } + + /** + * Set the GIOP version. Some data types are written differently for the + * different versions. The default version is 1.0 . + */ + public void setVersion(Version giop_version) + { + giop = giop_version; + } + + /** + * Align the curretn position at the given natural boundary. + */ + public abstract void align(int boundary); + + /** + * Reads the CORBA unsigned long (java int), returning the value in the + * sufficiently large java long. + */ + public long gnu_read_ulong() + { + try + { + long l = b.readInt(); + l &= 0xFFFFFFF; + return l; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the unsigned short integer value and return it as java int, + * sufficiently large to hold all values. + */ + public int gnu_read_ushort() + { + try + { + align(2); + return b.readUnsignedShort(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Return the associated {@link ORB}. + * + * @return the associated {@link ORB} or null is no such is set. + */ + public ORB orb() + { + return orb; + } + + /** + * Read a single byte directly from the buffer. + */ + public int read() + throws java.io.IOException + { + try + { + return b.read(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read bytes directly from the buffer. + */ + public int read(byte[] x, int ofs, int len) + throws java.io.IOException + { + try + { + return b.read(x, ofs, len); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read bytes directly from the buffer. + */ + public int read(byte[] x) + throws java.io.IOException + { + try + { + return b.read(x); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read the CORBA object. The object to read is represented in the form of the + * plain (not a string-encoded) IOR profile without the heading endian + * indicator. The responsible method for reading such data is + * {@link IOR.read_no_endian}. + * + * The returned object is usually casted into the given type using the .narrow + * method of its helper, despite in some cases the direct cast would also + * work. + * + * The null objects are recognised from the empty profile set. For such + * objects, null is returned. + * + * @return the loaded and constructed object. + */ + public org.omg.CORBA.Object read_Object() + { + try + { + IOR ior = new IOR(); + ior._read_no_endian(this); + + if (ior.Id == null) + return null; + + // Check maybe this is a remote reference to the local object. + // This is only possible if we access the repository of the + // connected object. + if (orb instanceof OrbFunctional) + { + OrbFunctional forb = (OrbFunctional) orb; + org.omg.CORBA.Object local = forb.find_local_object(ior); + if (local != null) + return local; + } + + // Search for the available stubs. + ObjectImpl impl = StubLocator.search(orb, ior); + try + { + if (impl._get_delegate() == null) + impl._set_delegate(new IorDelegate(orb, ior)); + } + catch (BAD_OPERATION ex) + { + // Some colaborants may throw this exception + // in response to the attempt to get the unset delegate. + impl._set_delegate(new IorDelegate(orb, ior)); + } + + return impl; + } + catch (IOException ex) + { + MARSHAL bad = new MARSHAL(); + bad.minor = Minor.IOR; + bad.initCause(ex); + throw bad; + } + } + + /** + * Read the type code. The type code format is defined in the CORBA + * documenation. + */ + public TypeCode read_TypeCode() + { + try + { + return TypeCodeHelper.read(this); + } + + catch (Bounds ex) + { + throw new Unexpected(); + } + catch (BadKind ex) + { + throw new Unexpected(); + } + } + + /** + * Read the CORBA {@link Any}. This method first reads the type code, then + * delegates the functionality to {@link Any#read_value}. + */ + public Any read_any() + { + TypeCode ty = read_TypeCode(); + gnuAny any = new gnuAny(); + any.read_value(this, ty); + return any; + } + + /** + * Read the boolean, treating any non zero byte as true, zero byte as false. + */ + public boolean read_boolean() + { + try + { + return b.read() == 0 ? false : true; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the array of boolean. + */ + public void read_boolean_array(boolean[] x, int offs, int len) + { + try + { + for (int i = offs; i < offs + len; i++) + { + x[i] = b.read() == 0 ? false : true; + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a character using narrow charset encoding. Depending form which + * encoding is set, this still can be Unicode or ever wider. + */ + public char read_char() + { + try + { + if (narrow_native) + return (char) b.read(); + else + return (char) new InputStreamReader((InputStream) b, narrow_charset).read(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a character array, using narrow charset encoding. + */ + public void read_char_array(char[] x, int offset, int length) + { + try + { + if (narrow_native) + { + for (int i = offset; i < offset + length; i++) + x[i] = (char) b.read(); + } + else + { + InputStreamReader reader = new InputStreamReader((InputStream) b, + narrow_charset); + reader.read(x, offset, length); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the double value, IEEE 754 format. + */ + public double read_double() + { + try + { + align(8); + return b.readDouble(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(); + } + } + + /** + * Read the array of double values, IEEE 754 format. + */ + public void read_double_array(double[] x, int offs, int len) + { + try + { + align(8); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readDouble(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the encapsulated stream. If the encapsulated sequence appears to be in + * the Little endian format, the flag of the returned stream is set to read + * Little endian. + */ + public BufferredCdrInput read_encapsulation() + { + try + { + int l = read_long(); + + byte[] r = new byte[l]; + int n = 0; + while (n < r.length) + { + n += read(r, n, r.length - n); + } + + BufferredCdrInput capsule = new BufferredCdrInput(r); + capsule.setOrb(orb); + + int endian = capsule.read_octet(); + + if (endian != 0) + { + capsule.setBigEndian(false); + } + + return capsule; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA fixed (the end of the <code>fixed</code> can be determined + * by its last byte). The scale is always assumed to be zero. + */ + public BigDecimal read_fixed() + { + try + { + return BigDecimalHelper.read(this, 0); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the float value, IEEE 754 format. + */ + public float read_float() + { + try + { + align(4); + return b.readFloat(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of float values, IEEE 754 format. + */ + public void read_float_array(float[] x, int offs, int len) + { + try + { + align(4); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readFloat(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA long (java int), high byte first. + */ + public int read_long() + { + try + { + align(4); + return b.readInt(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of CORBA longs (java ints). + */ + public void read_long_array(int[] x, int offs, int len) + { + try + { + align(4); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readInt(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA long long (java long). + */ + public long read_longlong() + { + try + { + align(8); + return b.readLong(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of CORBA long longs (java longs). + */ + public void read_longlong_array(long[] x, int offs, int len) + { + try + { + align(8); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readLong(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a single byte. + */ + public byte read_octet() + { + try + { + return b.readByte(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the byte array. + */ + public void read_octet_array(byte[] x, int offs, int len) + { + try + { + b.read(x, offs, len); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the length of the byte array as CORBA long and then the array itseld. + */ + public byte[] read_sequence() + { + try + { + int l = read_long(); + byte[] buf = new byte[l]; + if (l > 0) + { + b.readFully(buf); + } + return buf; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA short integer. + */ + public short read_short() + { + try + { + align(2); + return b.readShort(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the array of CORBA short integer values. + */ + public void read_short_array(short[] x, int offs, int len) + { + try + { + align(2); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readShort(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a singe byte string. The method firs reads the byte array and then + * calls a constructor to create a string from this array. The character + * encoding, if previously set, is taken into consideration. + * + * @return a loaded string. + */ + public String read_string() + { + int n = 0; + try + { + align(4); + + n = b.readInt(); + byte[] s = new byte[n]; + b.read(s); + + // Discard the null terminator. + if (narrow_charset == null) + return new String(s, 0, n - 1); + else + return new String(s, 0, n - 1, narrow_charset); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(); + } + catch (NegativeArraySizeException nex) + { + MARSHAL m = new MARSHAL("Input stream broken, got " + n + "(0x" + + Integer.toHexString(n) + ") as a string size"); + m.minor = Minor.Negative; + throw m; + } + } + + /** + * Reads the CORBA unsigned long (java int), delegating functionality to + * {@link #read_long}. + */ + public int read_ulong() + { + return read_long(); + } + + /** + * Reads the array of CORBA unsigned long (java integer) values, delegating + * functionality to {@link #real_long_array}. + */ + public void read_ulong_array(int[] x, int offs, int len) + { + read_long_array(x, offs, len); + } + + /** + * Read the CORBA unsigned long long value, delegating functionality to + * {@link #read_longlong}. There is no way to return values over the limit of + * the java signed long in other way than returning the negative value. + */ + public long read_ulonglong() + { + return read_longlong(); + } + + /** + * Reads the array of CORBA long long (java long) values, delegating + * functionality to {@link #real_longlong_array}. + */ + public void read_ulonglong_array(long[] x, int offs, int len) + { + read_longlong_array(x, offs, len); + } + + /** + * Read the unsigned short integer value. Due strange specification, the + * returned value must be the short type as well, so the the best solution + * seems just to delegete functionality to read_short. + */ + public short read_ushort() + { + return read_short(); + } + + /** + * Read an array of unsigned short values, delegating the functionality to + * {@link read_short_array}. + */ + public void read_ushort_array(short[] x, int offs, int len) + { + read_short_array(x, offs, len); + } + + /** + * Reads the wide character using the encoding, specified in the wide_charset. + */ + public char read_wchar() + { + try + { + if (giop.until_inclusive(1, 1)) + { + align(2); + + if (wide_native) + return (char) b.readShort(); + else + return (char) new InputStreamReader((InputStream) b, wide_charset).read(); + } + else + { + int l = b.read(); + if (l == 2 && wide_native) + return b.readChar(); + else if (l <= 0) + { + MARSHAL m = new MARSHAL("wchar size " + l); + m.minor = Minor.Negative; + throw m; + } + else + { + byte[] bytes = new byte[l]; + b.readFully(bytes); + String cs; + + if (bytes.length > 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) + cs = new String(bytes, 2, bytes.length - 2, wide_charset); + else if (bytes.length > 2 && bytes[0] == 0xFF + && bytes[1] == 0xFE) + { + // Litle endian detected - swap bytes. + byte t; + for (int i = 3; i < bytes.length; i = i + 2) + { + t = bytes[i]; + bytes[i - 1] = bytes[i]; + bytes[i] = t; + } + cs = new String(bytes, 2, bytes.length - 2, wide_charset); + } + else + cs = new String(bytes, wide_charset); + + return cs.charAt(0); + } + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(); + } + } + + /** + * Read an array of "wide chars", each representing a two byte Unicode + * character, high byte first. + */ + public void read_wchar_array(char[] x, int offset, int length) + { + try + { + if (giop.until_inclusive(1, 1)) + align(2); + + if (wide_native) + { + for (int i = offset; i < offset + length; i++) + x[i] = (char) b.readShort(); + } + else + { + InputStreamReader reader = new InputStreamReader((InputStream) b, + wide_charset); + reader.read(x, offset, length); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Reads the string in wide character format (ussually UTF-16, Unicode). Takes + * the currently set charset into consideration. + * + * If the native (UTF-16) encoding is used of the GIOP protocol is before 1.2, + * delegates functionality to "plain" {@link #read_wstring_UTF_16}. + */ + public String read_wstring() + { + // Native encoding or word oriented data. + if (wide_native || giop.until_inclusive(1, 1)) + return read_wstring_UTF_16(); + try + { + align(4); + + int n = b.readInt(); + byte[] s = new byte[n]; + b.read(s); + + return new String(s, 0, n, wide_charset); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Reads first length of the string and the all characters as an Unicode + * (UTF-16) characters. Mind that GIOP 1.1 has the extra null character at the + * end that must be discarded. + */ + public String read_wstring_UTF_16() + { + try + { + int p = 0; + int n = read_long(); + + if (n<0) + { + MARSHAL m = new MARSHAL("Negative string size"); + m.minor = Minor.Negative; + throw m; + } + + // The null terminator that is no longer present since 1.2 . + int nt = giop.since_inclusive(1, 2) ? 0 : 1; + + // Convert bytes to shorts. + n = n / 2; + + // Empty string. + if (n == 0) + return ""; + + char[] s = new char[n]; + + for (int i = 0; i < s.length; i++) + s[i] = (char) b.readShort(); + + // Check for the byte order marker here. + if (s[0] == 0xFEFF) + { + // Big endian encoding - do nothing, but move the pointer + // one position forward. + p = 1; + } + else if (s[0] == 0xFFFE) + { + // Little endian encoding, swap the bytes and move one + // position forward. + p = 1; + + for (int i = p; i < s.length; i++) + s[i] = swap(s[i]); + } + + // Discard the null terminator and, if needed, the endian marker. + String r = new String(s, p, n - nt - p); + return r; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Swap bytes in the character. + */ + public static char swap(char x) + { + int hi; + int lo; + + lo = x & 0xFF; + hi = (x >> 8) & 0xFF; + + return (char) ((lo << 8) | hi); + } + + /** + * Set the current code set context. + */ + public void setCodeSet(CodeSetServiceContext a_codeset) + { + this.codeset = a_codeset; + narrow_charset = CharSets_OSF.getName(codeset.char_data); + wide_charset = CharSets_OSF.getName(codeset.wide_char_data); + + narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; + wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; + } + + /** + * Get the current code set context. + */ + public CodeSetServiceContext getCodeSet() + { + return codeset; + } + + /** + * Read the object that is an instance of the given class. The current + * implementation delegates functionality to the parameterless + * {@link readObject()}. + * + * @param klass a class of that this object the instance is. + * + * @return the returned object. + */ + public org.omg.CORBA.Object read_Object(Class klass) + { + return read_Object(); + } + + /** + * Read a value type structure from the stream. + * + * OMG specification states the writing format is outside the scope of GIOP + * definition. This implementation uses java serialization mechanism, calling + * {@link ObjectInputStream#readObject} + * + * @return an value type structure, unmarshaled from the stream + */ + public Serializable read_Value() + { + return read_value(); + } + + /** + * Read the abstract interface. An abstract interface can be either CORBA + * value type or CORBA object and is returned as an abstract java.lang.Object. + * + * As specified in OMG specification, this reads a single boolean and then + * delegates either to {@link #read_Object()} (for false) or to + * {@link #read_Value()} (for true). + * + * @return an abstract interface, unmarshaled from the stream + */ + public java.lang.Object read_Abstract() + { + return read_abstract_interface(); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_char_array(CharSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_char_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_wchar_array(WCharSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_wchar_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the char array to fit the newly read + * values. + * + * @param holder_value the existing char array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private char[] ensureArray(char[] holder_value, int offset, int length) + { + if (holder_value == null) + return new char[offset + length]; + else if (holder_value.length < offset + length) + { + char[] value = new char[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_ulong_array(ULongSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulong_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_long_array(LongSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulong_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the int array to fit the newly read values. + * + * @param holder_value the existing int array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private int[] ensureArray(int[] holder_value, int offset, int length) + { + if (holder_value == null) + return new int[offset + length]; + else if (holder_value.length < offset + length) + { + int[] value = new int[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_float_array(FloatSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_float_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the float array to fit the newly read + * values. + * + * @param holder_value the existing float array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private float[] ensureArray(float[] holder_value, int offset, int length) + { + if (holder_value == null) + return new float[offset + length]; + else if (holder_value.length < offset + length) + { + float[] value = new float[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_double_array(DoubleSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_double_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the double array to fit the newly read + * values. + * + * @param holder_value the existing double array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private double[] ensureArray(double[] holder_value, int offset, int length) + { + if (holder_value == null) + return new double[offset + length]; + else if (holder_value.length < offset + length) + { + double[] value = new double[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_short_array(ShortSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_short_array(holder.value, offset, length); + } + + /** {@inheritDoc} */ + public void read_ushort_array(UShortSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ushort_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the short array to fit the newly read + * values. + * + * @param holder_value the existing short array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private short[] ensureArray(short[] holder_value, int offset, int length) + { + if (holder_value == null) + return new short[offset + length]; + else if (holder_value.length < offset + length) + { + short[] value = new short[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_octet_array(OctetSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_octet_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the byte array to fit the newly read + * values. + * + * @param holder_value the existing byte array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private byte[] ensureArray(byte[] holder_value, int offset, int length) + { + if (holder_value == null) + return new byte[offset + length]; + else if (holder_value.length < offset + length) + { + byte[] value = new byte[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_longlong_array(LongLongSeqHolder holder, int offset, + int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_longlong_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, + int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulonglong_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the array of longs to fit the newly read + * values. + * + * @param holder_value the existing array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private long[] ensureArray(long[] holder_value, int offset, int length) + { + if (holder_value == null) + return new long[offset + length]; + else if (holder_value.length < offset + length) + { + long[] value = new long[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_boolean_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the array of booleans to fit the newly read + * values. + * + * @param holder_value the existing array of booleans, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private boolean[] ensureArray(boolean[] holder_value, int offset, int length) + { + if (holder_value == null) + return new boolean[offset + length]; + else if (holder_value.length < offset + length) + { + boolean[] value = new boolean[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_any_array(AnySeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + for (int i = offset; i < offset + length; i++) + { + holder.value[i] = read_any(); + } + } + + /** + * If required, allocate or resize the array of Anys to fit the newly read + * values. + * + * @param holder_value the existing array of Anys, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private Any[] ensureArray(Any[] holder_value, int offset, int length) + { + if (holder_value == null) + return new Any[offset + length]; + else if (holder_value.length < offset + length) + { + Any[] value = new Any[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * This method is required to represent the DataInputStream as a value type + * object. + * + * @return a single entity "IDL:omg.org/CORBA/DataInputStream:1.0", always. + */ + public String[] _truncatable_ids() + { + return new String[] { "IDL:omg.org/CORBA/DataInputStream:1.0" }; + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java new file mode 100644 index 000000000..ab0b982ab --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java @@ -0,0 +1,1047 @@ +/* AbstractCdrOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.BigDecimalHelper; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.Minor; +import gnu.CORBA.TypeCodeHelper; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; +import gnu.CORBA.GIOP.CharSets_OSF; +import gnu.CORBA.GIOP.CodeSetServiceContext; +import gnu.CORBA.typecodes.PrimitiveTypeCode; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.DataInputStream; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UserException; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * A simple CORBA CDR (common data representation) + * output stream, writing data into the + * given {@link java.io.OutputStream}. + * + * The same class also implements the {@link DataInputStream}, + * providing support for writing the value type objects + * in a user defined way. + * + * TODO This class uses 16 bits per Unicode character only, as it was until + * jdk 1.4 inclusive. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class AbstractCdrOutput + extends org.omg.CORBA_2_3.portable.OutputStream + implements org.omg.CORBA.DataOutputStream +{ + /** + * The runtime, associated with this stream. This field is only used when + * reading and writing value types and filled-in in gnu.CORBA.CDR.Vio. + */ + public transient gnuRuntime runtime; + + /** + * This instance is used to convert primitive data types into the + * byte sequences. + */ + protected AbstractDataOutput b; + + /** + * The associated orb, if any. + */ + protected ORB orb; + + /** + * The GIOP version. + */ + protected Version giop = new Version(1, 2); + + /** + * The code set information. + */ + protected CodeSetServiceContext codeset; + + /** + * The name of the currently used narrow charset. + */ + private String narrow_charset; + + /** + * The name of the currently used wide charset, null if + * the native wide charset is used. + */ + private String wide_charset; + + /** + * True if the native code set is used for narrow characters. + * If the set is native, no the intermediate Reader object + * is instantiated when writing characters. + */ + private boolean narrow_native; + + /** + * True if the native code set is used for wide characters. + * If the set is native, no the intermediate Reader object + * is instantiated when writing characters. + */ + private boolean wide_native; + + /** + * If true, the Little Endian encoding is used to write the + * data. Otherwise, the Big Endian encoding is used. + */ + private boolean little_endian; + + /** + * The stream whre the data are actually written. + */ + private java.io.OutputStream actual_stream; + + /** + * Creates the stream. + * + * @param writeTo a stream to write CORBA output to. + */ + public AbstractCdrOutput(java.io.OutputStream writeTo) + { + setOutputStream(writeTo); + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Creates the stream, requiring the subsequent call + * of {@link #setOutputStream(java.io.OutputStream)}. + */ + public AbstractCdrOutput() + { + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public abstract void setOffset(int an_offset); + + /** + * Clone all important settings to another stream. + */ + public void cloneSettings(AbstractCdrOutput stream) + { + stream.setBigEndian(!little_endian); + stream.setCodeSet(getCodeSet()); + stream.setVersion(giop); + stream.setOrb(orb); + } + + /** + * Set the current code set context. + */ + public void setCodeSet(CodeSetServiceContext a_codeset) + { + this.codeset = a_codeset; + narrow_charset = CharSets_OSF.getName(codeset.char_data); + wide_charset = CharSets_OSF.getName(codeset.wide_char_data); + + narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; + wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; + } + + /** + * Get the current code set context. + */ + public CodeSetServiceContext getCodeSet() + { + return codeset; + } + + /** + * Set the orb, associated with this stream. + * @param an_orb + */ + public void setOrb(ORB an_orb) + { + orb = an_orb; + } + + /** + * Set the output stream that receives the CORBA output. + * + * @param writeTo the stream. + */ + public void setOutputStream(java.io.OutputStream writeTo) + { + if (little_endian) + b = new LittleEndianOutputStream(writeTo); + else + b = new BigEndianOutputStream(writeTo); + + actual_stream = writeTo; + } + + /** + * Set the GIOP version. Some data types are written differently + * for the different versions. The default version is 1.0 . + */ + public void setVersion(Version giop_version) + { + giop = giop_version; + } + + /** + * Specify if the stream should use the Big Endian (usual for java) + * or Little Encoding. The default is Big Endian. + * + * @param use_big_endian if true, use Big Endian, if false, + * use Little Endian. + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setOutputStream(actual_stream); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public abstract void align(int boundary); + + /** + * Create the encapsulation stream, associated with the current + * stream. The encapsulated stream must be closed. When being + * closed, the encapsulation stream writes its buffer into + * this stream using the CORBA CDR encapsulation rules. + * + * It is not allowed to write to the current stream directly + * before the encapsulation stream is closed. + * + * The encoding (Big/Little Endian) inside the encapsulated + * sequence is the same as used into the parent stream. + * + * @return the encapsulated stream. + */ + public AbstractCdrOutput createEncapsulation() + { + return new EncapsulationStream(this, !little_endian); + } + + /** + * Return the associated {@link ORB}. + * @return the associated {@link ORB} or null is no such is set. + */ + public ORB orb() + { + return orb; + } + + /** + * Write a single byte. + * @param n byte to write (low 8 bits are written). + */ + public void write(int n) + { + try + { + b.write(n); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Write bytes directly into the underlying stream. + */ + public void write(byte[] x) + throws java.io.IOException + { + b.write(x); + } + + /** + * Write bytes directly into the underlying stream. + */ + public void write(byte[] x, int ofs, int len) + throws java.io.IOException + { + b.write(x, ofs, len); + } + + /** + * Following the specification, this is not implemented. + * Override to get the functionality. + */ + public void write_Context(Context context, ContextList contexts) + { + throw new NO_IMPLEMENT(); + } + + /** + * Read the CORBA object. The object is written form of the plain (not a + * string-encoded) IOR profile without the heading endian indicator. The + * responsible method for reading such data is {@link IOR.write_no_endian}. + * + * The null value is written as defined in OMG specification (zero length + * string, followed by an empty set of profiles). + */ + public void write_Object(org.omg.CORBA.Object x) + { + ORB w_orb = orb; + if (x instanceof IorProvider) + { + ((IorProvider) x).getIor()._write_no_endian(this); + return; + } + else if (x == null) + { + IOR.write_null(this); + return; + } + else if (x instanceof ObjectImpl) + { + Delegate d = ((ObjectImpl) x)._get_delegate(); + + if (d instanceof IorProvider) + { + ((IorProvider) d).getIor()._write_no_endian(this); + return; + } + else + { + ORB d_orb = d.orb(x); + if (d_orb != null) + w_orb = d_orb; + } + } + + // Either this is not an ObjectImpl or it has the + // unexpected delegate. Try to convert via ORBs + // object_to_string(). + if (w_orb != null) + { + IOR ior = IOR.parse(w_orb.object_to_string(x)); + ior._write_no_endian(this); + return; + } + else + throw new BAD_OPERATION( + "Please set the ORB for this stream, cannot write " + + x.getClass().getName()); + } + + /** + * Write the TypeCode. This implementation delegates functionality + * to {@link cdrTypeCode}. + * + * @param x a TypeCode to write. + */ + public void write_TypeCode(TypeCode x) + { + try + { + TypeCodeHelper.write(this, x); + } + catch (UserException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes an instance of the CORBA {@link Any}. + * This method writes the typecode, followed + * by value itself. In Any contains null + * (value not set), the {@link TCKind#tk_null} + * is written. + * + * @param x the {@link Any} to write. + */ + public void write_any(Any x) + { + Streamable value = x.extract_Streamable(); + if (value != null) + { + write_TypeCode(x.type()); + value._write(this); + } + else + { + PrimitiveTypeCode p = new PrimitiveTypeCode(TCKind.tk_null); + write_TypeCode(p); + } + } + + /** + * Writes a single byte, 0 for <code>false</code>, + * 1 for <code>true</code>. + * + * @param x the value to write + */ + public void write_boolean(boolean x) + { + try + { + b.write(x ? 1 : 0); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the boolean array. + * + * @param x array + * @param ofs offset + * @param len length. + */ + public void write_boolean_array(boolean[] x, int ofs, int len) + { + try + { + for (int i = ofs; i < ofs + len; i++) + { + b.write(x [ i ] ? 1 : 0); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the lower byte of the passed parameter. + * @param x the char to write + * + * It is effective to write more characters at once. + */ + public void write_char(char x) + { + try + { + if (narrow_native) + b.write(x); + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); + ow.write(x); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the lower bytes of the passed array members. + * + * @param chars an array + * @param offset offset + * @param length length + */ + public void write_char_array(char[] chars, int offset, int length) + { + try + { + if (narrow_native) + { + for (int i = offset; i < offset + length; i++) + { + b.write(chars [ i ]); + } + } + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); + ow.write(chars, offset, length); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the double value (IEEE 754 format). + */ + public void write_double(double x) + { + try + { + align(8); + b.writeDouble(x); + } + catch (Exception ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of double values. + */ + public void write_double_array(double[] x, int ofs, int len) + { + try + { + align(8); + for (int i = ofs; i < ofs + len; i++) + { + b.writeDouble(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes CORBA fixed, storing all digits but not the scale. + * The end of the record on <code>fixed</code> can + * be determined from its last byte. + */ + public void write_fixed(BigDecimal fixed) + { + try + { + BigDecimalHelper.write(this, fixed); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + catch (BadKind ex) + { + Unexpected.error(ex); + } + } + + /** + * Write the float value (IEEE 754 format). + */ + public void write_float(float x) + { + try + { + align(4); + b.writeFloat(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes an array of the float values. + */ + public void write_float_array(float[] x, int ofs, int len) + { + try + { + align(4); + for (int i = ofs; i < ofs + len; i++) + { + b.writeFloat(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the integer value (CORBA long, four bytes, high byte first). + * @param x the value to write. + */ + public void write_long(int x) + { + try + { + align(4); + b.writeInt(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of integer (CORBA long) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_long_array(int[] x, int ofs, int len) + { + try + { + align(4); + for (int i = ofs; i < ofs + len; i++) + { + b.writeInt(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the long (CORBA long long) value, 8 bytes, + * high byte first. + * + * @param x the value to write. + */ + public void write_longlong(long x) + { + try + { + align(8); + b.writeLong(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of longs (CORBA long longs) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_longlong_array(long[] x, int ofs, int len) + { + try + { + align(8); + for (int i = ofs; i < ofs + len; i++) + { + b.writeLong(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes this byte. + * @param x + */ + public void write_octet(byte x) + { + try + { + b.writeByte(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of bytes (CORBA octets) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_octet_array(byte[] x, int ofs, int len) + { + try + { + b.write(x, ofs, len); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes first the size of array, and then the byte array using + * the {@link java.io.OutputStream#write(byte[]) }. The sequence + * being written is preceeded by the int, representing the array + * length. + */ + public void write_sequence(byte[] buf) + { + try + { + write_long(buf.length); + write(buf); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.CDR; + t.initCause(ex); + throw t; + } + } + + /** + * Writes the contents of the provided stream. + * The sequence being written is preceeded by the int, + * representing the stream buffer length (the number of + * bytes being subsequently written). + */ + public void write_sequence(BufferedCdrOutput from) + { + try + { + write_long(from.buffer.size()); + from.buffer.writeTo(this); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.CDR; + t.initCause(ex); + throw t; + } + } + + /** + * Writes the two byte integer (short), high byte first. + * + * @param x the integer to write. + */ + public void write_short(short x) + { + try + { + align(2); + b.writeShort(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of short (two byte integer) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_short_array(short[] x, int ofs, int len) + { + try + { + align(2); + for (int i = ofs; i < ofs + len; i++) + { + b.writeShort(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the string. This implementation first calls + * String.getBytes() and then writes the length of the returned + * array (as CORBA ulong) and the returned array itself. + * + * The encoding information, if previously set, is taken + * into consideration. + * + * @param x the string to write. + */ + public void write_string(String x) + { + try + { + byte[] ab = x.getBytes(narrow_charset); + write_long(ab.length + 1); + write(ab); + + // write null terminator. + write(0); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the CORBA unsigned long in the same way as CORBA long. + */ + public void write_ulong(int x) + { + write_long(x); + } + + /** + * Writes the array of CORBA unsigned longs in the same way as + * array of ordinary longs. + */ + public void write_ulong_array(int[] x, int ofs, int len) + { + write_long_array(x, ofs, len); + } + + /** + * Write the unsigned long long in the same way as an ordinary long long. + * + * @param x a value to write. + */ + public void write_ulonglong(long x) + { + write_longlong(x); + } + + /** + * Write the array of unsingel long longs in the same way + * an an array of the ordinary long longs. + */ + public void write_ulonglong_array(long[] x, int ofs, int len) + { + write_longlong_array(x, ofs, len); + } + + /** + * Write the unsigned short in the same way as an ordinary short. + */ + public void write_ushort(short x) + { + write_short(x); + } + + /** + * Write an array of unsigned short integersin the same way + * as an array of ordinary short integers. + */ + public void write_ushort_array(short[] x, int ofs, int len) + { + write_short_array(x, ofs, len); + } + + /** + * Writes the character as two byte short integer (Unicode value), high byte + * first. Writes in Big Endian, but never writes the endian indicator. + * + * The character is always written using the native UTF-16BE charset because + * its size under arbitrary encoding is not evident. + */ + public void write_wchar(char x) + { + try + { + if (giop.until_inclusive(1, 1)) + { + align(2); + + if (wide_native) + b.writeShort(x); + else + { + OutputStreamWriter ow = new OutputStreamWriter( + (OutputStream) b, wide_charset); + ow.write(x); + ow.flush(); + } + } + else if (wide_native) + { + b.writeByte(2); + b.writeChar(x); + } + else + { + String encoded = new String(new char[] { x }); + byte[] bytes = encoded.getBytes(wide_charset); + b.write(bytes.length + 2); + b.write(bytes); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Write the array of wide chars. + * + * @param chars the array of wide chars + * @param offset offset + * @param length length + * + * The char array is always written using the native UTF-16BE charset because + * the character size under arbitrary encoding is not evident. + */ + public void write_wchar_array(char[] chars, int offset, int length) + { + try + { + if (giop.until_inclusive(1, 1)) + align(2); + + if (wide_native) + { + for (int i = offset; i < offset + length; i++) + { + b.writeShort(chars [ i ]); + } + } + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, wide_charset); + ow.write(chars, offset, length); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the length of the string in bytes (not characters) and + * then all characters as two byte unicode chars. Adds the + * Big Endian indicator, 0xFFFE, at the beginning and null wide char at + * the end. + * + * @param x the string to write. + */ + public void write_wstring(String x) + { + try + { + if (giop.since_inclusive(1, 2)) + { + byte[] bytes = x.getBytes(wide_charset); + write_sequence(bytes); + } + else + { + // Encoding with null terminator always in UTF-16. + // The wide null terminator needs extra two bytes. + write_long(2 * x.length() + 2); + + for (int i = 0; i < x.length(); i++) + { + b.writeShort(x.charAt(i)); + } + + // Write null terminator. + b.writeShort(0); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** {@inheritDoc} */ + public void write_any_array(Any[] anys, int offset, int length) + { + for (int i = offset; i < offset + length; i++) + { + write_any(anys [ i ]); + } + } + + public String[] _truncatable_ids() + { + /**@todo Implement this org.omg.CORBA.portable.ValueBase abstract method*/ + throw new java.lang.UnsupportedOperationException("Method _truncatable_ids() not yet implemented."); + } + + /** {@inheritDoc} */ + public void write_Abstract(java.lang.Object value) + { + write_abstract_interface(value); + } + + /** {@inheritDoc} */ + public void write_Value(Serializable value) + { + write_value(value); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java new file mode 100644 index 000000000..0ad98bed7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java @@ -0,0 +1,392 @@ +/* AbstractDataInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * Some data input stream that can be either Big or + * Little Endian. + * + * This class reuses code from GNU Classpath DataInputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface AbstractDataInput +{ + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to fill the buffer completely, but + * may return a short count if there is insufficient data remaining to be + * read to fill the buffer. + * + * @param b The buffer into which bytes will be read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b) + throws IOException; + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to read <code>len</code> bytes and + * will start storing them at position <code>off</code> into the buffer. + * This method can return a short count if there is insufficient data + * remaining to be read to complete the desired read length. + * + * @param b The buffer into which bytes will be read. + * @param off The offset into the buffer to start storing bytes. + * @param len The requested number of bytes to read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b, int off, int len) + throws IOException; + + /** + * This method reads a Java boolean value from an input stream. It does + * so by reading a single byte of data. If that byte is zero, then the + * value returned is <code>false</code>. If the byte is non-zero, then + * the value returned is <code>true</code>. + * <p> + * This method can read a <code>boolean</code> written by an object + * implementing the <code>writeBoolean()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>boolean</code> value read + * + * @exception EOFException If end of file is reached before reading + * the boolean + * @exception IOException If any other error occurs + * + * @see DataOutput#writeBoolean + */ + boolean readBoolean() + throws IOException; + + /** + * This method reads a Java byte value from an input stream. The value + * is in the range of -128 to 127. + * <p> + * This method can read a <code>byte</code> written by an object + * implementing the <code>writeByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>byte</code> value read + * + * @exception EOFException If end of file is reached before reading the byte + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + byte readByte() + throws IOException; + + /** + * This method reads a Java <code>char</code> value from an input stream. + * It operates by reading two bytes from the stream and converting them to + * a single 16-bit Java <code>char</code>. The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>char</code> in + * the following manner: + * <p> + * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code> + * <p> + * This method can read a <code>char</code> written by an object + * implementing the <code>writeChar()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>char</code> value read + * + * @exception EOFException If end of file is reached before reading the char + * @exception IOException If any other error occurs + * + * @see DataOutput#writeChar + */ + char readChar() + throws IOException; + + /** + * This method reads a Java double value from an input stream. It operates + * by first reading a <code>long</code> value from the stream by calling the + * <code>readLong()</code> method in this interface, then converts + * that <code>long</code> to a <code>double</code> using the + * <code>longBitsToDouble</code> method in the class + * <code>java.lang.Double</code> + * <p> + * This method can read a <code>double</code> written by an object + * implementing the <code>writeDouble()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>double</code> value read + * + * @exception EOFException If end of file is reached before reading + * the double + * @exception IOException If any other error occurs + * + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble + */ + double readDouble() + throws IOException; + + /** + * This method reads a Java float value from an input stream. It + * operates by first reading an <code>int</code> value from the + * stream by calling the <code>readInt()</code> method in this + * interface, then converts that <code>int</code> to a + * <code>float</code> using the <code>intBitsToFloat</code> method + * in the class <code>java.lang.Float</code> + * <p> + * This method can read a <code>float</code> written by an object + * implementing the <code>writeFloat()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>float</code> value read + * + * @exception EOFException If end of file is reached before reading the float + * @exception IOException If any other error occurs + * + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat + */ + float readFloat() + throws IOException; + + /** + * This method reads raw bytes into the passed array until the array is + * full. Note that this method blocks until the data is available and + * throws an exception if there is not enough data left in the stream to + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. + * + * @param b The buffer into which to read the data + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + void readFully(byte[] b) + throws IOException; + + /** + * This method reads a Java <code>int</code> value from an input stream + * It operates by reading four bytes from the stream and converting them to + * a single Java <code>int</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte4</code> represent + * the first four bytes read from the stream, they will be + * transformed to an <code>int</code> in the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code> + * <p> + * The value returned is in the range of -2147483648 to 2147483647. + * <p> + * This method can read an <code>int</code> written by an object + * implementing the <code>writeInt()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>int</code> value read + * + * @exception EOFException If end of file is reached before reading the int + * @exception IOException If any other error occurs + * + * @see DataOutput#writeInt + */ + int readInt() + throws IOException; + + /** + * This method reads a Java <code>long</code> value from an input stream + * It operates by reading eight bytes from the stream and converting them to + * a single Java <code>long</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte8</code> represent + * the first eight bytes read from the stream, they will be + * transformed to an <code>long</code> in the following manner: + * <p> + * <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) + * </code> + * <p> + * The value returned is in the range of -9223372036854775808 to + * 9223372036854775807. + * <p> + * This method can read an <code>long</code> written by an object + * implementing the <code>writeLong()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>long</code> value read + * + * @exception EOFException If end of file is reached before reading the long + * @exception IOException If any other error occurs + * + * @see DataOutput#writeLong + */ + long readLong() + throws IOException; + + /** + * This method reads a signed 16-bit value into a Java in from the + * stream. It operates by reading two bytes from the stream and + * converting them to a single 16-bit Java <code>short</code>. The + * two bytes are stored most significant byte first (i.e., "big + * endian") regardless of the native host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>short</code>. in + * the following manner: + * <p> + * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of -32768 to 32767. + * <p> + * This method can read a <code>short</code> written by an object + * implementing the <code>writeShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>short</code> value read + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + short readShort() + throws IOException; + + /** + * This method reads 8 unsigned bits into a Java <code>int</code> + * value from the stream. The value returned is in the range of 0 to + * 255. + * <p> + * This method can read an unsigned byte written by an object + * implementing the <code>writeUnsignedByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned bytes value read as a Java <code>int</code>. + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + int readUnsignedByte() + throws IOException; + + /** + * This method reads 16 unsigned bits into a Java int value from the stream. + * It operates by reading two bytes from the stream and converting them to + * a single Java <code>int</code> The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to an <code>int</code> in + * the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of 0 to 65535. + * <p> + * This method can read an unsigned short written by an object + * implementing the <code>writeUnsignedShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned short value read as a Java <code>int</code> + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + int readUnsignedShort() + throws IOException; + + /** + * Read a single byte. + * + * @return a byte, extracted from the stream or -1 if + * EOF has been reached. + * @throws IOException + */ + public int read() + throws IOException; + + /** + * This method attempts to skip and discard the specified number of bytes + * in the input stream. It may actually skip fewer bytes than requested. + * This method will not skip any bytes if passed a negative number of bytes + * to skip. + * + * @param n The requested number of bytes to skip. + * + * @return The requested number of bytes to skip. + * + * @exception IOException If an error occurs. + * @specnote The JDK docs claim that this returns the number of bytes + * actually skipped. The JCL claims that this method can throw an + * EOFException. Neither of these appear to be true in the JDK 1.3's + * implementation. This tries to implement the actual JDK behaviour. + */ + int skipBytes(int n) + throws IOException; +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java new file mode 100644 index 000000000..e41ec598a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java @@ -0,0 +1,185 @@ +/* AbstractDataOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * An abstract data output stream that could write data in either + * Big Endian or Little Endian format. + * + * This class reuses code from GNU Classpath DataOutputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface AbstractDataOutput +{ + /** + * This method flushes any unwritten bytes to the underlying stream. + * + * @exception IOException If an error occurs. + */ + void flush() + throws IOException; + + /** + * This method writes the specified byte (passed as an <code>int</code>) + * to the underlying output stream. + * + * @param value The <code>byte</code> to write, passed as an <code>int</code>. + * + * @exception IOException If an error occurs. + */ + void write(int value) + throws IOException; + + /** + * This method writes <code>len</code> bytes from the specified byte array + * <code>buf</code> starting at position <code>offset</code> into the + * buffer to the underlying output stream. + * + * @param buf The byte array to write from. + * @param offset The index into the byte array to start writing from. + * @param len The number of bytes to write. + * + * @exception IOException If an error occurs. + */ + void write(byte[] buf, int offset, int len) + throws IOException; + + /** + * Write the complete byte array. + * @throws IOException + */ + void write(byte[] buf) + throws IOException; + + /** + * This method writes a Java boolean value to an output stream. If + * <code>value</code> is <code>true</code>, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the <code>readBoolean</code> + * method in <code>DataInput</code>. + * + * @param value The <code>boolean</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeBoolean(boolean value) + throws IOException; + + /** + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * <code>int</code> value passed. + * + * The value written can be read using the <code>readByte</code> or + * <code>readUnsignedByte</code> methods in <code>DataInput</code>. + * + * @param value The <code>byte</code> to write to the stream, passed as + * the low eight bits of an <code>int</code>. + * + * @exception IOException If an error occurs + */ + void writeByte(int value) + throws IOException; + + /** + * This method writes a Java short value to an output stream. The + * char to be written will be in the lowest 16 bits of the <code>int</code> + * value passed. + * + * @exception IOException If an error occurs + */ + void writeShort(int value) + throws IOException; + + /** + * This method writes a Java char value to an output stream. The + * char to be written will be in the lowest 16 bits of the <code>int</code> + * value passed. + * + * @exception IOException If an error occurs + */ + void writeChar(int value) + throws IOException; + + /** + * This method writes a Java int value to an output stream. + * + * @param value The <code>int</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeInt(int value) + throws IOException; + + /** + * This method writes a Java long value to an output stream. + * + * @param value The <code>long</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeLong(long value) + throws IOException; + + /** + * This method writes a Java <code>float</code> value to the stream. + * @param value The <code>float</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeFloat(float value) + throws IOException; + + /** + * This method writes a Java <code>double</code> value to the stream. + * + * @param value The <code>double</code> value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeDouble(double value) + throws IOException; +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AligningInput.java b/libjava/classpath/gnu/CORBA/CDR/AligningInput.java new file mode 100644 index 000000000..8d438ab06 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AligningInput.java @@ -0,0 +1,131 @@ +/* AligningInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayInputStream; + +import org.omg.CORBA.BAD_PARAM; + +/** + * The input stream with the possibility to align on the + * word (arbitrary size) boundary. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class AligningInput + extends ByteArrayInputStream +{ + /** + * The alignment offset. + */ + private int offset = 0; + + /** + * Create a stream, reading form the given buffer. + * + * @param a_buffer a buffer to read from. + */ + public AligningInput(byte[] a_buffer) + { + super(a_buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + offset = an_offset; + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + * + * @throws BAD_PARAM, minor code 0, the alignment is not possible, + * usually due the wrong parameter value. + */ + public void align(int alignment) + { + try + { + int d = (pos + offset) % alignment; + if (d > 0) + { + skip(alignment - d); + } + } + catch (Exception ex) + { + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; + } + } + + /** + * Get the byte buffer, from where the data are read. + */ + public byte[] getBuffer() + { + return buf; + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return pos + offset; + } + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position) + { + if (position < offset || position > (count+offset)) + throw new ArrayIndexOutOfBoundsException(position + + " is out of valid ["+offset+".." + (count+offset) + "[ range"); + pos = position - offset; + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java b/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java new file mode 100644 index 000000000..b0c569ec8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java @@ -0,0 +1,148 @@ +/* AligningOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayOutputStream; + +import org.omg.CORBA.BAD_PARAM; + +/** + * The input stream with the possibility to align on the + * word (arbitrary size) boundary. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class AligningOutput + extends ByteArrayOutputStream +{ + /** + * The alignment offset. + */ + private int offset = 0; + + /** + * Create a stream with the default intial buffer size. + */ + public AligningOutput() + { + } + + /** + * Create a stream with the given intial buffer size. + */ + public AligningOutput(int initial_size) + { + super(initial_size); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + offset = an_offset; + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + * + * @throws BAD_PARAM, minor code 0, the alignment is not possible, + * usually due the wrong parameter value. + */ + public void align(int alignment) + { + try + { + int d = (count + offset) % alignment; + if (d > 0) + { + skip(alignment - d); + } + } + catch (Exception ex) + { + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; + } + } + + /** + * Write the specified number of zero bytes. + * + * @param bytes the number of zero bytes to write. + */ + public void skip(int bytes) + { + for (int i = 0; i < bytes; i++) + { + write(0); + } + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return size()+offset; + } + + /** + * Seek to the given position (not in use). + */ + public void seek(int position) + { + count = position - offset; + } + + /** + * Get the buffer without copying it. Use with care. + */ + public byte[] getBuffer() + { + return buf; + } + + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java b/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java new file mode 100644 index 000000000..0578f13b8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java @@ -0,0 +1,254 @@ +/* ArrayValueHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.ObjectCreator; + +import org.omg.CORBA.BooleanSeqHelper; +import org.omg.CORBA.CharSeqHelper; +import org.omg.CORBA.DoubleSeqHelper; +import org.omg.CORBA.FloatSeqHelper; +import org.omg.CORBA.LongLongSeqHelper; +import org.omg.CORBA.LongSeqHelper; +import org.omg.CORBA.OctetSeqHelper; +import org.omg.CORBA.ShortSeqHelper; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.rmi.Remote; + +import javax.rmi.CORBA.Util; +import javax.rmi.CORBA.ValueHandler; + +/** + * Writes arrays as a boxed value types. A single instance is used to write a + * single array. This class is only used with RMI/IIOP, to handle array boxed + * values. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +class ArrayValueHelper + implements BoxedValueHelper +{ + /** + * The value handler (one for all instances). + */ + static ValueHandler handler = Util.createValueHandler(); + + /** + * A class of the array being written. + */ + Class arrayClass; + + /** + * The array component class. + */ + Class component; + + /** + * The array component repository Id. + */ + String componentId; + + /** + * If true, the array members are written as objects rather than as values. + * True for Remotes and CORBA objects. + */ + boolean written_as_object() + { + return org.omg.CORBA.Object.class.isAssignableFrom(component) + || Remote.class.isAssignableFrom(component); + } + + /** + * Creates the instance of the helper to write this specific array class. + */ + ArrayValueHelper(Class an_arrayClass) + { + arrayClass = an_arrayClass; + } + + /** + * Get the array repository Id that will be the RMI repository id. + */ + public String get_id() + { + return ObjectCreator.getRepositoryId(arrayClass); + } + + /** + * Read the array from the input stream. + */ + public Serializable read_value(InputStream input) + { + if (input instanceof HeadlessInput) + { + ((HeadlessInput) input).subsequentCalls = true; + } + + component = arrayClass.getComponentType(); + + if (component.equals(byte.class)) + return OctetSeqHelper.read(input); + else if (component.equals(String.class)) + { + // String array is optimized because this may be frequent. + String[] s = new String[input.read_long()]; + + for (int i = 0; i < s.length; i++) + s[i] = (String) Vio.read(input, Vio.m_StringValueHelper); + return s; + } + else if (component.equals(int.class)) + return LongSeqHelper.read(input); + else if (component.equals(long.class)) + return LongLongSeqHelper.read(input); + else if (component.equals(double.class)) + return DoubleSeqHelper.read(input); + else if (component.equals(float.class)) + return FloatSeqHelper.read(input); + else if (component.equals(boolean.class)) + return BooleanSeqHelper.read(input); + else if (component.equals(short.class)) + return ShortSeqHelper.read(input); + else if (component.equals(char.class)) + return CharSeqHelper.read(input); + else + { + // Read others, use reflection. + int n = input.read_long(); + + gnuValueStream s = null; + + Serializable array = (Serializable) Array.newInstance(component, n); + if (written_as_object()) + for (int i = 0; i < n; i++) + { + gnuRuntime g; + int position; + if (input instanceof gnuValueStream) + { + s = (gnuValueStream) input; + g = s.getRunTime(); + position = s.getPosition(); + } + else + { + g = null; + position = -1; + } + + if (input instanceof HeadlessInput) + ((HeadlessInput) input).subsequentCalls = true; + + Object o = handler.readValue(input, position, component, null, g); + Array.set(array, i, o); + } + else + for (int i = 0; i < n; i++) + Array.set(array, i, Vio.read(input, component)); + return array; + } + } + + /** + * Write the array to the input stream. + */ + public void write_value(OutputStream output, Serializable value) + { + if (output instanceof gnuValueStream) + { + gnuRuntime r = ((gnuValueStream) output).getRunTime(); + if (r != null) + r.target = null; + } + + if (value instanceof byte[]) + OctetSeqHelper.write(output, (byte[]) value); + else if (value instanceof String[]) + { + String[] s = (String[]) value; + output.write_long(s.length); + for (int i = 0; i < s.length; i++) + Vio.write(output, s[i], Vio.m_StringValueHelper); + } + else if (value instanceof int[]) + LongSeqHelper.write(output, (int[]) value); + else if (value instanceof long[]) + LongLongSeqHelper.write(output, (long[]) value); + else if (value instanceof double[]) + DoubleSeqHelper.write(output, (double[]) value); + else if (value instanceof float[]) + FloatSeqHelper.write(output, (float[]) value); + else if (value instanceof boolean[]) + BooleanSeqHelper.write(output, (boolean[]) value); + else if (value instanceof short[]) + ShortSeqHelper.write(output, (short[]) value); + else if (value instanceof char[]) + CharSeqHelper.write(output, (char[]) value); + else + { + // Write others, use reflection. + component = arrayClass.getComponentType(); + + int n = Array.getLength(value); + output.write_long(n); + if (written_as_object()) + for (int i = 0; i < n; i++) + { + Object o = Array.get(value, i); + if (o == null) + output.write_Object(null); + else + // CORBA objects have another notation. + handler.writeValue(output, (Serializable) o); + } + else + { + for (int i = 0; i < n; i++) + Vio.write(output, (Serializable) Array.get(value, i), + component); + } + + } + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java b/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java new file mode 100644 index 000000000..5579789a5 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java @@ -0,0 +1,61 @@ +/* BigEndianInputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.DataInputStream; +import java.io.InputStream; + +/** + * As java uses Big Endian by default, this class is directly derived + * form DataInputStream. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class BigEndianInputStream + extends DataInputStream + implements AbstractDataInput +{ + /** + * Delegates to the parent constructor. + */ + public BigEndianInputStream(InputStream in) + { + super(in); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java new file mode 100644 index 000000000..dda14a03a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java @@ -0,0 +1,62 @@ +/* BigEndianOutputStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.DataOutputStream; +import java.io.OutputStream; + +/** + * A stream to read the data in Big Endian format. This class is + * directly derived from DataOutputStream that uses the Big + * Endian. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class BigEndianOutputStream + extends DataOutputStream + implements AbstractDataOutput +{ + /** + * Delegate functionality to the parent constructor. + */ + public BigEndianOutputStream(OutputStream out) + { + super(out); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java new file mode 100644 index 000000000..ae510b39c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java @@ -0,0 +1,156 @@ +/* BufferedCdrOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayOutputStream; + +/** + * A CORBA output stream, writing data into the internal buffer ({@link ByteArrayOutputStream}). + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class BufferedCdrOutput + extends AbstractCdrOutput + implements gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The byte buffer. + */ + public final AligningOutput buffer; + + /** + * Creates the instance with the given initial buffer size. + * + * @param bufSize the buffer size. + */ + public BufferedCdrOutput(int bufSize) + { + buffer = new AligningOutput(bufSize); + setOutputStream(buffer); + } + + /** + * Creates the instance with the default buffer size. + */ + public BufferedCdrOutput() + { + buffer = new AligningOutput(); + setOutputStream(buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the stream is + * different from 0. + */ + public void setOffset(int an_offset) + { + buffer.setOffset(an_offset); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public void align(int boundary) + { + buffer.align(boundary); + } + + /** + * Return the input stream that reads the previously written values. + */ + public org.omg.CORBA.portable.InputStream create_input_stream() + { + BufferredCdrInput in = new BufferredCdrInput(buffer.toByteArray()); + in.setOrb(orb); + + in.setVersion(giop); + in.setCodeSet(getCodeSet()); + + return in; + } + + /** + * Resets (clears) the buffer. + */ + public void reset() + { + buffer.reset(); + setOutputStream(buffer); + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return buffer.getPosition(); + } + + /** + * Get the associated RunTime. + */ + public gnuRuntime getRunTime() + { + return runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + runtime = a_runtime; + } + + /** + * Seek to the given position. + */ + public void seek(int position) + { + buffer.seek(position); + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java b/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java new file mode 100644 index 000000000..accb65a0d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java @@ -0,0 +1,153 @@ +/* BufferredCdrInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + + +/** + * The CDR input stream that reads data from the byte buffer. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class BufferredCdrInput + extends AbstractCdrInput + implements gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The byte array input stream to read data from. + */ + public final AligningInput buffer; + + /** + * Creates the CDR input stream that reads from the given buffer + * array. + * + * @param a_buffer an array to read from. + */ + public BufferredCdrInput(byte[] a_buffer) + { + buffer = new AligningInput(a_buffer); + setInputStream(buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int offset) + { + buffer.setOffset(offset); + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + */ + public void align(int alignment) + { + buffer.align(alignment); + } + + /** + * Mark the current position. + * @param ahead + */ + public synchronized void mark(int ahead) + { + buffer.mark(ahead); + } + + /** + * Checks if marking is supported. + * @return + */ + public boolean markSupported() + { + return buffer.markSupported(); + } + + /** + * Resets the stream to the previously marked position. + */ + public void reset() + { + buffer.reset(); + setInputStream(buffer); + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return buffer.getPosition(); + } + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position) + { + buffer.seek(position); + setInputStream(buffer); + } + + /** + * Get the associated RunTime. + */ + public gnuRuntime getRunTime() + { + return runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + runtime = a_runtime; + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java b/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java new file mode 100644 index 000000000..e42991232 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java @@ -0,0 +1,147 @@ +/* EncapsulationOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * The encapsulated data, as they are defined by CORBA specification. + * This includes the extra 0 byte (Big endian) in the beginning. + * When written to the parent steam, the encapsulated data are preceeded + * by the data length in bytes. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class EncapsulationStream + extends AbstractCdrOutput +{ + /** + * The Big Endian (most siginificant byte first flag). + */ + public static final byte BIG_ENDIAN = 0; + + /** + * The Little Endian (least siginificant byte first flag). + */ + public static final byte LITTLE_ENDIAN = 1; + + /** + * The byte buffer. + */ + public final AligningOutput buffer; + + /** + * The stream, where the data are being encapsulated. + */ + public final org.omg.CORBA.portable.OutputStream parent; + + /** + * Create the EncapsulationOutput with the given parent stream + * and the specified encoding. + */ + public EncapsulationStream(org.omg.CORBA.portable.OutputStream _parent, + boolean use_big_endian) + { + super(); + setBigEndian(use_big_endian); + buffer = new AligningOutput(); + setOutputStream(buffer); + parent = _parent; + write(use_big_endian?BIG_ENDIAN:LITTLE_ENDIAN); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + buffer.setOffset(an_offset); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public void align(int boundary) + { + buffer.align(boundary); + } + + /** + * Writes the content of the encapsulated output into the parent + * buffer. + */ + public void close() + { + try + { + parent.write_long(buffer.size()); + buffer.writeTo(parent); + } + catch (IOException ex) + { + InternalError err = new InternalError(); + err.initCause(ex); + throw err; + } + } + + /** + * Return the input stream that reads the previously written values. + */ + public org.omg.CORBA.portable.InputStream create_input_stream() + { + BufferredCdrInput in = new BufferredCdrInput(buffer.toByteArray()); + in.setOrb(orb); + + in.setVersion(giop); + in.setCodeSet(getCodeSet()); + + return in; + } + + /** + * Resets (clears) the buffer. + */ + public void reset() + { + buffer.reset(); + setOutputStream(buffer); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java b/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java new file mode 100644 index 000000000..5e97c73b8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java @@ -0,0 +1,749 @@ +/* HeadlessInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnySeqHolder; +import org.omg.CORBA.BooleanSeqHolder; +import org.omg.CORBA.CharSeqHolder; +import org.omg.CORBA.Context; +import org.omg.CORBA.DataInputStream; +import org.omg.CORBA.DoubleSeqHolder; +import org.omg.CORBA.FloatSeqHolder; +import org.omg.CORBA.LongLongSeqHolder; +import org.omg.CORBA.LongSeqHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.OctetSeqHolder; +import org.omg.CORBA.Principal; +import org.omg.CORBA.ShortSeqHolder; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.ULongLongSeqHolder; +import org.omg.CORBA.ULongSeqHolder; +import org.omg.CORBA.UShortSeqHolder; +import org.omg.CORBA.WCharSeqHolder; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * Substitutes the main stream in factories when the header is already behind. + * Overrides methods that may be invoked from the factory, forcing not to read + * the header if called first time on this stream. + * + * This stream reverts to default behavior if one or more call are made (reading + * value types that are nested fields of the value type). + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class HeadlessInput + extends org.omg.CORBA_2_3.portable.InputStream + implements DataInputStream, gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Indicates that no positional information is available. + */ + static final int NONE = -1; + + /** + * If true, this is not the first call. + */ + public boolean subsequentCalls; + + /** + * The enclosed stream. + */ + final BufferredCdrInput stream; + + /** + * Create an instance, reading from the given buffer. + * + * @param a_stream a stream from where the data will be read. + * @param inheritSettings a stream from that endian and other settings are + * inherited. + */ + public HeadlessInput(BufferredCdrInput a_stream, InputStream inheritSettings) + { + stream = a_stream; + + if (inheritSettings instanceof AbstractCdrInput) + { + AbstractCdrInput t = (AbstractCdrInput) inheritSettings; + t.cloneSettings(stream); + } + else if (stream.orb() == null) + stream.setOrb(inheritSettings.orb()); + + if (inheritSettings instanceof gnuValueStream + && stream.getRunTime() == null) + { + stream.setRunTime(((gnuValueStream) inheritSettings).getRunTime()); + } + } + + /** + * Tries to read using boxed value helper. + */ + public Serializable read_value(BoxedValueHelper helper) + { + if (subsequentCalls) + return stream.read_value(helper); + else + { + subsequentCalls = true; + return helper.read_value(this); + } + } + + /** + * Tries to locate a factory using repository id. + */ + public Serializable read_value(String repository_id) + { + if (subsequentCalls) + return stream.read_value(repository_id); + else + { + subsequentCalls = true; + Serializable value = Vio.readValue(this, NONE, null, + null, repository_id, null, null); + return value; + } + } + + /** + * Try to read when having an unitialised value. + */ + public Serializable read_value(Serializable value) + { + if (subsequentCalls) + return stream.read_value(value); + else + { + subsequentCalls = true; + value = Vio.readValue(this, NONE, value, null, null, + null, null); + return value; + } + } + + /** + * Try to read when having an unitialised value. + */ + public Serializable read_value(Class clz) + { + if (subsequentCalls) + return stream.read_value(clz); + else + { + try + { + subsequentCalls = true; + Serializable value = (Serializable) Vio.instantiateAnyWay(clz); + value = Vio.readValue(this, NONE, value, null, null, + null, null); + return value; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Can't read an instance of " + + clz.getName()); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + } + } + + /** + * Delegates functionality to the underlying stream. + */ + public int available() + throws IOException + { + return stream.available(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void close() + throws IOException + { + stream.close(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void mark(int readlimit) + { + stream.mark(readlimit); + } + + /** + * Delegates functionality to the underlying stream. + */ + public boolean markSupported() + { + return stream.markSupported(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public ORB orb() + { + return stream.orb(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_abstract_interface() + { + return stream.read_abstract_interface(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_abstract_interface(Class clz) + { + return stream.read_abstract_interface(clz); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Any read_any() + { + return stream.read_any(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_boolean_array(boolean[] value, int offset, int length) + { + stream.read_boolean_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public boolean read_boolean() + { + return stream.read_boolean(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_char_array(char[] value, int offset, int length) + { + stream.read_char_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public char read_char() + { + return stream.read_char(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Context read_Context() + { + return stream.read_Context(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_double_array(double[] value, int offset, int length) + { + stream.read_double_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public double read_double() + { + return stream.read_double(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public BigDecimal read_fixed() + { + return stream.read_fixed(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_float_array(float[] value, int offset, int length) + { + stream.read_float_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public float read_float() + { + return stream.read_float(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_long_array(int[] value, int offset, int length) + { + stream.read_long_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read_long() + { + return stream.read_long(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_longlong_array(long[] value, int offset, int length) + { + stream.read_longlong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long read_longlong() + { + return stream.read_longlong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public org.omg.CORBA.Object read_Object() + { + return stream.read_Object(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public org.omg.CORBA.Object read_Object(Class klass) + { + return stream.read_Object(klass); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_octet_array(byte[] value, int offset, int length) + { + stream.read_octet_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public byte read_octet() + { + return stream.read_octet(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Principal read_Principal() + { + return stream.read_Principal(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_short_array(short[] value, int offset, int length) + { + stream.read_short_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public short read_short() + { + return stream.read_short(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String read_string() + { + return stream.read_string(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public TypeCode read_TypeCode() + { + return stream.read_TypeCode(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulong_array(int[] value, int offset, int length) + { + stream.read_ulong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read_ulong() + { + return stream.read_ulong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulonglong_array(long[] value, int offset, int length) + { + stream.read_ulonglong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long read_ulonglong() + { + return stream.read_ulonglong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ushort_array(short[] value, int offset, int length) + { + stream.read_ushort_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public short read_ushort() + { + return stream.read_ushort(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Serializable read_value() + { + return read_value((Serializable) null); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_wchar_array(char[] value, int offset, int length) + { + stream.read_wchar_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public char read_wchar() + { + return stream.read_wchar(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String read_wstring() + { + return stream.read_wstring(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read() + throws IOException + { + return stream.read(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read(byte[] b, int off, int len) + throws IOException + { + return stream.read(b, off, len); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read(byte[] b) + throws IOException + { + return stream.read(b); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void reset() + throws IOException + { + stream.reset(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long skip(long n) + throws IOException + { + return stream.skip(n); + } + + /** + * Get a string representation. + */ + public String toString() + { + return "HeadlessInput+" + stream.toString(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String[] _truncatable_ids() + { + return stream._truncatable_ids(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_Abstract() + { + return stream.read_Abstract(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_any_array(AnySeqHolder holder, int offset, int length) + { + stream.read_any_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) + { + stream.read_boolean_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_char_array(CharSeqHolder holder, int offset, int length) + { + stream.read_char_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_double_array(DoubleSeqHolder holder, int offset, int length) + { + stream.read_double_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_float_array(FloatSeqHolder holder, int offset, int length) + { + stream.read_float_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_long_array(LongSeqHolder holder, int offset, int length) + { + stream.read_long_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_longlong_array(LongLongSeqHolder holder, int offset, + int length) + { + stream.read_longlong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_octet_array(OctetSeqHolder holder, int offset, int length) + { + stream.read_octet_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_short_array(ShortSeqHolder holder, int offset, int length) + { + stream.read_short_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulong_array(ULongSeqHolder holder, int offset, int length) + { + stream.read_ulong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, + int length) + { + stream.read_ulonglong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ushort_array(UShortSeqHolder holder, int offset, int length) + { + stream.read_ushort_array(holder, offset, length); + } + + /** + * Delegates functionality to read_value. + */ + public Serializable read_Value() + { + return read_value(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_wchar_array(WCharSeqHolder holder, int offset, int length) + { + stream.read_wchar_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int getPosition() + { + return stream.getPosition(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public gnuRuntime getRunTime() + { + return stream.runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + stream.runtime = a_runtime; + } + + /** + * Delegates functionality to the underlying stream. + */ + public void seek(int position) + { + stream.seek(position); + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java b/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java new file mode 100644 index 000000000..663e04196 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java @@ -0,0 +1,169 @@ +/* IDLTypeHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * Handles case when the CORBA IDL type with the known helper is wrapped into + * Value type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class IDLTypeHelper + implements BoxedValueHelper +{ + /** + * A helper class. + */ + protected Class helper; + + /** + * Argument values for Helper.id(). + */ + static final Object[] ARGS_ID_V = new Object[0]; + + /** + * Argument types for Helper.id()). + */ + static final Class[] ARGS_ID = new Class[0]; + + /** + * Argument types for Helper.read. + */ + static final Class[] ARGS_READ = new Class[] { org.omg.CORBA.portable.InputStream.class }; + + /** + * Create an IDLTypeHelper that works via given helper class. + */ + public IDLTypeHelper(Class a_helperClass) + { + helper = a_helperClass; + } + + /** + * Get the Id, returned by this helper (use reflection). + */ + public String get_id() + { + try + { + Method m = helper.getMethod("id", ARGS_ID); + return (String) m.invoke(null, ARGS_ID_V); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " id()"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Read an instance from the stream. + */ + public Serializable read_value(InputStream input) + { + try + { + Method m = helper.getMethod("read", ARGS_READ); + return (Serializable) m.invoke(null, new Object[] { input }); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " read(..)"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Write the instance to the stream. + */ + public void write_value(OutputStream output, Serializable value) + { + try + { + Method[] m = helper.getMethods(); + + for (int i = 0; i < m.length; i++) + { + if (m[i].getName().equals("write") + && ((m[i].getModifiers() & Modifier.STATIC) != 0)) + { + Class[] p = m[i].getParameterTypes(); + + if (p.length == 2 && OutputStream.class.isAssignableFrom(p[0]) + && p[1].isAssignableFrom(value.getClass())) + { + m[i].invoke(null, new Object[] { output, value }); + return; + } + } + } + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " write(..)"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Create the start of message for exceptions. + */ + String msg() + { + return "Failed calling " + helper.getName() + " method: "; + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java b/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java new file mode 100644 index 000000000..93d18fb11 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java @@ -0,0 +1,634 @@ +/* LittleEndianInputStream.java -- + Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005 Free Software Foundation + +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.CDR; + +import gnu.java.lang.CPStringBuilder; + +import java.io.EOFException; +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.PushbackInputStream; + +/** + * This class reads data in the Little Endian format. It reuses + * code from GNU Classpath DataInputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public class LittleEndianInputStream + extends FilterInputStream + implements AbstractDataInput +{ + // Byte buffer, used to make primitive read calls more efficient. + byte[] buf = new byte[ 8 ]; + + /** + * This constructor initializes a new <code>DataInputStream</code> + * to read from the specified subordinate stream. + * + * @param in The subordinate <code>InputStream</code> to read from + */ + public LittleEndianInputStream(InputStream in) + { + super(in); + } + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to fill the buffer completely, but + * may return a short count if there is insufficient data remaining to be + * read to fill the buffer. + * + * @param b The buffer into which bytes will be read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + public int read(byte[] b) + throws IOException + { + return in.read(b, 0, b.length); + } + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to read <code>len</code> bytes and + * will start storing them at position <code>off</code> into the buffer. + * This method can return a short count if there is insufficient data + * remaining to be read to complete the desired read length. + * + * @param b The buffer into which bytes will be read. + * @param off The offset into the buffer to start storing bytes. + * @param len The requested number of bytes to read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + public int read(byte[] b, int off, int len) + throws IOException + { + return in.read(b, off, len); + } + + /** + * This method reads a Java boolean value from an input stream. It does + * so by reading a single byte of data. If that byte is zero, then the + * value returned is <code>false</code>. If the byte is non-zero, then + * the value returned is <code>true</code>. + * <p> + * This method can read a <code>boolean</code> written by an object + * implementing the <code>writeBoolean()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>boolean</code> value read + * + * @exception EOFException If end of file is reached before reading + * the boolean + * @exception IOException If any other error occurs + * + * @see DataOutput#writeBoolean + */ + public boolean readBoolean() + throws IOException + { + return convertToBoolean(in.read()); + } + + /** + * This method reads a Java byte value from an input stream. The value + * is in the range of -128 to 127. + * <p> + * This method can read a <code>byte</code> written by an object + * implementing the <code>writeByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>byte</code> value read + * + * @exception EOFException If end of file is reached before reading the byte + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + public byte readByte() + throws IOException + { + return convertToByte(in.read()); + } + + /** + * This method reads a Java <code>char</code> value from an input stream. + * It operates by reading two bytes from the stream and converting them to + * a single 16-bit Java <code>char</code>. The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>char</code> in + * the following manner: + * <p> + * <code>(char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)</code> + * <p> + * This method can read a <code>char</code> written by an object + * implementing the <code>writeChar()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>char</code> value read + * + * @exception EOFException If end of file is reached before reading the char + * @exception IOException If any other error occurs + * + * @see DataOutput#writeChar + */ + public char readChar() + throws IOException + { + readFully(buf, 0, 2); + return convertToChar(buf); + } + + /** + * This method reads a Java double value from an input stream. It operates + * by first reading a <code>long</code> value from the stream by calling the + * <code>readLong()</code> method in this interface, then converts + * that <code>long</code> to a <code>double</code> using the + * <code>longBitsToDouble</code> method in the class + * <code>java.lang.Double</code> + * <p> + * This method can read a <code>double</code> written by an object + * implementing the <code>writeDouble()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>double</code> value read + * + * @exception EOFException If end of file is reached before reading + * the double + * @exception IOException If any other error occurs + * + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble + */ + public double readDouble() + throws IOException + { + return Double.longBitsToDouble(readLong()); + } + + /** + * This method reads a Java float value from an input stream. It + * operates by first reading an <code>int</code> value from the + * stream by calling the <code>readInt()</code> method in this + * interface, then converts that <code>int</code> to a + * <code>float</code> using the <code>intBitsToFloat</code> method + * in the class <code>java.lang.Float</code> + * <p> + * This method can read a <code>float</code> written by an object + * implementing the <code>writeFloat()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>float</code> value read + * + * @exception EOFException If end of file is reached before reading the float + * @exception IOException If any other error occurs + * + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat + */ + public float readFloat() + throws IOException + { + return Float.intBitsToFloat(readInt()); + } + + /** + * This method reads raw bytes into the passed array until the array is + * full. Note that this method blocks until the data is available and + * throws an exception if there is not enough data left in the stream to + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. + * + * @param b The buffer into which to read the data + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + public void readFully(byte[] b) + throws IOException + { + readFully(b, 0, b.length); + } + + /** + * This method reads raw bytes into the passed array <code>buf</code> + * starting + * <code>offset</code> bytes into the buffer. The number of bytes read + * will be + * exactly <code>len</code>. Note that this method blocks until the data is + * available and throws an exception if there is not enough data left in + * the stream to read <code>len</code> bytes. Note also that zero length + * buffers are permitted. In this case, the method will return immediately + * without reading any bytes from the stream. + * + * @param buf The buffer into which to read the data + * @param offset The offset into the buffer to start storing data + * @param len The number of bytes to read into the buffer + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + public void readFully(byte[] buf, int offset, int len) + throws IOException + { + if (len < 0) + throw new IndexOutOfBoundsException("Negative length: " + len); + + while (len > 0) + { + // in.read will block until some data is available. + int numread = in.read(buf, offset, len); + if (numread < 0) + throw new EOFException(); + len -= numread; + offset += numread; + } + } + + /** + * This method reads a Java <code>int</code> value from an input stream + * It operates by reading four bytes from the stream and converting them to + * a single Java <code>int</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte4</code> represent + * the first four bytes read from the stream, they will be + * transformed to an <code>int</code> in the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF)))</code> + * <p> + * The value returned is in the range of -2147483648 to 2147483647. + * <p> + * This method can read an <code>int</code> written by an object + * implementing the <code>writeInt()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>int</code> value read + * + * @exception EOFException If end of file is reached before reading the int + * @exception IOException If any other error occurs + * + * @see DataOutput#writeInt + */ + public int readInt() + throws IOException + { + readFully(buf, 0, 4); + return convertToInt(buf); + } + + /** + * This method reads the next line of text data from an input + * stream. It operates by reading bytes and converting those bytes + * to <code>char</code> values by treating the byte read as the low + * eight bits of the <code>char</code> and using 0 as the high eight + * bits. Because of this, it does not support the full 16-bit + * Unicode character set. + * <p> + * The reading of bytes ends when either the end of file or a line + * terminator is encountered. The bytes read are then returned as a + * <code>String</code> A line terminator is a byte sequence + * consisting of either <code>\r</code>, <code>\n</code> or + * <code>\r\n</code>. These termination charaters are discarded and + * are not returned as part of the string. + * <p> + * This method can read data that was written by an object implementing the + * <code>writeLine()</code> method in <code>DataOutput</code>. + * + * @return The line read as a <code>String</code> + * + * @exception IOException If an error occurs + * + * @see DataOutput + * + * @deprecated + */ + public String readLine() + throws IOException + { + CPStringBuilder strb = new CPStringBuilder(); + + while (true) + { + int c = in.read(); + if (c == -1) // got an EOF + return strb.length() > 0 ? strb.toString() : null; + if (c == '\r') + { + int next_c = in.read(); + if (next_c != '\n' && next_c != -1) + { + if (!(in instanceof PushbackInputStream)) + in = new PushbackInputStream(in); + ((PushbackInputStream) in).unread(next_c); + } + break; + } + if (c == '\n') + break; + strb.append((char) c); + } + + return strb.length() > 0 ? strb.toString() : ""; + } + + /** + * This method reads a Java <code>long</code> value from an input stream + * It operates by reading eight bytes from the stream and converting them to + * a single Java <code>long</code>. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> through <code>byte8</code> represent + * the first eight bytes read from the stream, they will be + * transformed to an <code>long</code> in the following manner: + * <p> + * <code>(long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) + * </code> + * <p> + * The value returned is in the range of -9223372036854775808 to + * 9223372036854775807. + * <p> + * This method can read an <code>long</code> written by an object + * implementing the <code>writeLong()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>long</code> value read + * + * @exception EOFException If end of file is reached before reading the long + * @exception IOException If any other error occurs + * + * @see DataOutput#writeLong + */ + public long readLong() + throws IOException + { + readFully(buf, 0, 8); + return convertToLong(buf); + } + + /** + * This method reads a signed 16-bit value into a Java in from the + * stream. It operates by reading two bytes from the stream and + * converting them to a single 16-bit Java <code>short</code>. The + * two bytes are stored most significant byte first (i.e., "big + * endian") regardless of the native host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to a <code>short</code>. in + * the following manner: + * <p> + * <code>(short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of -32768 to 32767. + * <p> + * This method can read a <code>short</code> written by an object + * implementing the <code>writeShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The <code>short</code> value read + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + public short readShort() + throws IOException + { + readFully(buf, 0, 2); + return convertToShort(buf); + } + + /** + * This method reads 8 unsigned bits into a Java <code>int</code> + * value from the stream. The value returned is in the range of 0 to + * 255. + * <p> + * This method can read an unsigned byte written by an object + * implementing the <code>writeUnsignedByte()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned bytes value read as a Java <code>int</code>. + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + public int readUnsignedByte() + throws IOException + { + return convertToUnsignedByte(in.read()); + } + + /** + * This method reads 16 unsigned bits into a Java int value from the stream. + * It operates by reading two bytes from the stream and converting them to + * a single Java <code>int</code> The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + * <p> + * As an example, if <code>byte1</code> and <code>byte2</code> + * represent the first and second byte read from the stream + * respectively, they will be transformed to an <code>int</code> in + * the following manner: + * <p> + * <code>(int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF))</code> + * <p> + * The value returned is in the range of 0 to 65535. + * <p> + * This method can read an unsigned short written by an object + * implementing the <code>writeUnsignedShort()</code> method in the + * <code>DataOutput</code> interface. + * + * @return The unsigned short value read as a Java <code>int</code> + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + public int readUnsignedShort() + throws IOException + { + readFully(buf, 0, 2); + return convertToUnsignedShort(buf); + } + + /** + * This method attempts to skip and discard the specified number of bytes + * in the input stream. It may actually skip fewer bytes than requested. + * This method will not skip any bytes if passed a negative number of bytes + * to skip. + * + * @param n The requested number of bytes to skip. + * + * @return The requested number of bytes to skip. + * + * @exception IOException If an error occurs. + * @specnote The JDK docs claim that this returns the number of bytes + * actually skipped. The JCL claims that this method can throw an + * EOFException. Neither of these appear to be true in the JDK 1.3's + * implementation. This tries to implement the actual JDK behaviour. + */ + public int skipBytes(int n) + throws IOException + { + if (n <= 0) + return 0; + try + { + return (int) in.skip(n); + } + catch (EOFException x) + { + // do nothing. + } + return n; + } + + protected boolean convertToBoolean(int b) + throws EOFException + { + if (b < 0) + throw new EOFException(); + + return (b != 0); + } + + protected byte convertToByte(int i) + throws EOFException + { + if (i < 0) + throw new EOFException(); + + return (byte) i; + } + + protected int convertToUnsignedByte(int i) + throws EOFException + { + if (i < 0) + throw new EOFException(); + + return (i & 0xFF); + } + + /** + * Less significant byte first. + */ + protected char convertToChar(byte[] buf) + { + return (char) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected short convertToShort(byte[] buf) + { + return (short) ((buf [ 1 ] << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected int convertToUnsignedShort(byte[] buf) + { + return (((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected int convertToInt(byte[] buf) + { + return (((buf [ 3 ] & 0xff) << 24) | ((buf [ 2 ] & 0xff) << 16) | + ((buf [ 1 ] & 0xff) << 8) | (buf [ 0 ] & 0xff)); + } + + /** + * Less significant byte first. + */ + protected long convertToLong(byte[] buf) + { + return (((long) (buf [ 7 ] & 0xff) << 56) | + ((long) (buf [ 6 ] & 0xff) << 48) | + ((long) (buf [ 5 ] & 0xff) << 40) | + ((long) (buf [ 4 ] & 0xff) << 32) | + ((long) (buf [ 3 ] & 0xff) << 24) | + ((long) (buf [ 2 ] & 0xff) << 16) | + ((long) (buf [ 1 ] & 0xff) << 8) | ((long) (buf [ 0 ] & 0xff))); + } + + /** + * This should never be called. + * + * @throws InternalError, always. + */ + public String readUTF() + { + throw new InternalError(); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java new file mode 100644 index 000000000..f1b8e04b3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java @@ -0,0 +1,253 @@ +/* LittleEndianOutputStream.java -- + Copyright (C) 1998, 2001, 2003, 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.CDR; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * This stream writes data in the Little Endian format + * (less significant byte first). This is opposite to the + * usual data presentation in java platform. + * + * This class reuses code from DataOutputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Tom Tromey (tromey@cygnus.com) + */ +public class LittleEndianOutputStream + extends FilterOutputStream + implements AbstractDataOutput +{ + /** + * This method initializes an instance of <code>DataOutputStream</code> to + * write its data to the specified underlying <code>OutputStream</code> + * + * @param out The subordinate <code>OutputStream</code> to which this + * object will write + */ + public LittleEndianOutputStream(OutputStream out) + { + super(out); + } + + /** + * This method flushes any unwritten bytes to the underlying stream. + * + * @exception IOException If an error occurs. + */ + public void flush() + throws IOException + { + out.flush(); + } + + /** + * This method writes the specified byte (passed as an <code>int</code>) + * to the underlying output stream. + * + * @param value The <code>byte</code> to write, passed as an <code>int</code>. + * + * @exception IOException If an error occurs. + */ + public synchronized void write(int value) + throws IOException + { + out.write(value); + } + + /** + * This method writes <code>len</code> bytes from the specified byte array + * <code>buf</code> starting at position <code>offset</code> into the + * buffer to the underlying output stream. + * + * @param buf The byte array to write from. + * @param offset The index into the byte array to start writing from. + * @param len The number of bytes to write. + * + * @exception IOException If an error occurs. + */ + public synchronized void write(byte[] buf, int offset, int len) + throws IOException + { + out.write(buf, offset, len); + } + + /** + * This method writes a Java boolean value to an output stream. If + * <code>value</code> is <code>true</code>, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the <code>readBoolean</code> + * method in <code>DataInput</code>. + * + * @param value The <code>boolean</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see DataInput#readBoolean + */ + public void writeBoolean(boolean value) + throws IOException + { + write(value ? 1 : 0); + } + + /** + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * <code>int</code> value passed. + * + * The value written can be read using the <code>readByte</code> or + * <code>readUnsignedByte</code> methods in <code>DataInput</code>. + * + * @param value The <code>byte</code> to write to the stream, passed as + * the low eight bits of an <code>int</code>. + * + * @exception IOException If an error occurs + * + * @see DataInput#readByte + * @see DataInput#readUnsignedByte + */ + public void writeByte(int value) + throws IOException + { + write(value & 0xff); + } + + /** + * This method writes a Java short value to an output stream. + * + * @param value The <code>short</code> value to write to the stream, + * passed as an <code>int</code>. + * + * @exception IOException If an error occurs + */ + public synchronized void writeShort(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + } + + /** + * Writes char in Little Endian. + */ + public synchronized void writeChar(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + } + + /** + * Writes int in Little Endian. + */ + public synchronized void writeInt(int value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + write((byte) (0xff & (value >> 16))); + write((byte) (0xff & (value >> 24))); + } + + /** + * Writes long in Little Endian. + */ + public synchronized void writeLong(long value) + throws IOException + { + write((byte) (0xff & value)); + write((byte) (0xff & (value >> 8))); + write((byte) (0xff & (value >> 16))); + write((byte) (0xff & (value >> 24))); + write((byte) (0xff & (value >> 32))); + write((byte) (0xff & (value >> 40))); + write((byte) (0xff & (value >> 48))); + write((byte) (0xff & (value >> 56))); + } + + /** + * This method writes a Java <code>float</code> value to the stream. This + * value is written by first calling the method + * <code>Float.floatToIntBits</code> + * to retrieve an <code>int</code> representing the floating point number, + * then writing this <code>int</code> value to the stream exactly the same + * as the <code>writeInt()</code> method does. + * + * @param value The <code>float</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see writeInt + * @see DataInput#readFloat + * @see Float#floatToIntBits + */ + public void writeFloat(float value) + throws IOException + { + writeInt(Float.floatToIntBits(value)); + } + + /** + * This method writes a Java <code>double</code> value to the stream. This + * value is written by first calling the method + * <code>Double.doubleToLongBits</code> + * to retrieve an <code>long</code> representing the floating point number, + * then writing this <code>long</code> value to the stream exactly the same + * as the <code>writeLong()</code> method does. + * + * @param value The <code>double</code> value to write to the stream + * + * @exception IOException If an error occurs + * + * @see writeLong + * @see DataInput#readDouble + * @see Double#doubleToLongBits + */ + public void writeDouble(double value) + throws IOException + { + writeLong(Double.doubleToLongBits(value)); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java b/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java new file mode 100644 index 000000000..cb36f8c42 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java @@ -0,0 +1,292 @@ +/* UnknownExceptionCtxHandler.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.GIOP.ServiceContext; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.StringValueHelper; +import org.omg.CORBA.portable.OutputStream; + +import java.lang.reflect.Constructor; +import java.util.StringTokenizer; + +import javax.rmi.CORBA.Util; + +/** + * Reads the data about an unknown exception from the UnknownExceptionInfo. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class UnknownExceptionCtxHandler + extends Vio +{ + /** + * Encode exception and add its recored to the message service contexts. + */ + public static ServiceContext[] addExceptionContext(ServiceContext[] current, + Throwable exception, Object details) + { + try + { + ServiceContext[] c = new ServiceContext[current.length + 1]; + if (current.length > 0) + System.arraycopy(current, 0, c, 0, current.length); + + BufferedCdrOutput output = new BufferedCdrOutput(); + + if (details instanceof OutputStream) + output.setOrb(((OutputStream) output).orb()); + + if (details instanceof AbstractCdrOutput) + ((AbstractCdrOutput) details).cloneSettings(output); + + write(output, exception); + + ServiceContext xc = new ServiceContext(); + xc.context_id = ServiceContext.UnknownExceptionInfo; + xc.context_data = output.buffer.toByteArray(); + c[current.length] = xc; + return c; + } + catch (Exception ex) + { + ex.printStackTrace(); + return current; + } + } + + /** + * Write data about unknown exception. + */ + public static void write(BufferedCdrOutput output, Throwable t) + { + t.fillInStackTrace(); + output.write_Value(t); + } + + /** + * Read the data about an unknown exception from the UnknownExceptionInfo. + * Following the documentation, this must be just value type, but it seems + * that in Sun's implementation is is not, as starts from 0x0. For value type, + * this would be null. + * + * TODO Implement reading and writing in Sun format, making Classpath IIOP + * interoperable with Sun's implementation. Current inmplementation reads and + * reproduces the exception class type only. + * + * @param input the input stream to read the context (orb and other settings + * are inherited from the main stream that received the message). + * + * @param contexts all service contexts that were present in the message. + * + * @return the Throwable, extracted from context, on null, if this has failed. + */ + public static Throwable read(BufferredCdrInput input, ServiceContext[] contexts) + { + input.mark(Integer.MAX_VALUE); + + int h = input.read_long(); + if (h == 0) + { + // This block reads exception info in the Sun specific format. + // (currently we read the exception name only). + try + { + // We may need to jump back if the value is read via value + // factory. + input.mark(512); + + int value_tag = input.read_long(); + checkTag(value_tag); + + String codebase = null; + String[] ids = null; + String id = null; + + // Check for the agreed null value. + if (value_tag == vt_NULL) + return null; + else if (value_tag == vt_INDIRECTION) + return (Throwable) readIndirection(input); + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + // The codebase is present. The codebase is a space + // separated list of URLs from where the implementing + // code can be downloaded. + codebase = read_string(input); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + ids = read_string_array(input); + } + else if ((value_tag & vf_ID) != 0) + { + // Single supported repository id is present. + id = read_string(input); + } + } + + java.lang.Object ox = createInstance(id, ids, codebase); + + return (Throwable) ox; + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } + } + else + { + input.reset(); + // Read as defined in OMG documentation. + return (Throwable) input.read_Value(); + } + } + + /** + * Load exception by name and create the instance. The reason why this is + * different from Vio is because some exceptions have no parameterless + * constructor, but have a constructor with the string parameter instead. + */ + static Object createInstance(String id, String[] ids, String codebase) + { + Object o = _createInstance(id, codebase); + + if (ids != null) + for (int i = 0; i < ids.length && o == null; i++) + o = _createInstance(ids[i], codebase); + return o; + } + + static Object _createInstance(String id, String codebase) + { + if (id == null) + return null; + if (id.equals(StringValueHelper.id())) + return ""; + StringTokenizer st = new StringTokenizer(id, ":"); + + String prefix = st.nextToken(); + if (prefix.equalsIgnoreCase("IDL")) + return ObjectCreator.Idl2Object(id); + else if (prefix.equalsIgnoreCase("RMI")) + { + String className = st.nextToken(); + String hashCode = st.nextToken(); + String sid = null; + if (st.hasMoreElements()) + sid = st.nextToken(); + + try + { + Class objectClass = Util.loadClass(className, codebase, + Vio.class.getClassLoader()); + + String rid = ObjectCreator.getRepositoryId(objectClass); + + if (!rid.equals(id)) + { + // If direct string comparison fails, compare by meaning. + StringTokenizer st2 = new StringTokenizer(rid, ":"); + if (!st2.nextToken().equals("RMI")) + throw new InternalError("RMI format expected: '" + rid + "'"); + if (!st2.nextToken().equals(className)) + throwIt("Class name mismatch", id, rid, null); + + try + { + long h1 = Long.parseLong(hashCode, 16); + long h2 = Long.parseLong(st2.nextToken(), 16); + if (h1 != h2) + throwIt("Hashcode mismatch", id, rid, null); + + if (sid != null && st2.hasMoreTokens()) + { + long s1 = Long.parseLong(hashCode, 16); + long s2 = Long.parseLong(st2.nextToken(), 16); + if (s1 != s2) + throwIt("serialVersionUID mismatch", id, rid, null); + } + } + catch (NumberFormatException e) + { + throwIt("Invalid hashcode or svuid format: ", id, rid, e); + } + } + + // Some RemoteExceptions have no public parameterless constructor, + // but they have constructor taking string as parameter. + try + { + return objectClass.newInstance(); + } + catch (Exception ex) + { + // Try instantiate passing string as parameter. + Constructor c = objectClass.getConstructor(new Class[] { String.class }); + return c.newInstance(new Object[] { "<message unavailable>" }); + } + } + catch (MARSHAL m) + { + m.minor = Minor.Instantiation; + throw m; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Unable to instantiate " + id); + m.minor = Minor.Instantiation; + m.initCause(ex); + throw m; + } + } + else + throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":"); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/VMVio.java b/libjava/classpath/gnu/CORBA/CDR/VMVio.java new file mode 100644 index 000000000..47a6c0c25 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/VMVio.java @@ -0,0 +1,101 @@ +/* VMVio.java -- Native operations, required by value IO. + 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. */ + +/** + * This is a temporary replacement for the native call that would allocate + * objects without public constructors. The replacement only allocates + * objects with public parameterless constructor and objects with public + * constructor taking string (like some Throwables). + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * + * TODO FIXME replace by native call like in VMObjectInputStream. + * Required modification of Classpath the build system. + */ + + +package gnu.CORBA.CDR; + +import java.lang.reflect.Constructor; + +public class VMVio +{ + /** + * Allocates a new Object of type clazz but without running the default + * constructor on it. It then calls the given constructor on it. The given + * constructor method comes from the constr_clazz which is a super class of + * the given clazz. + */ + public static Object allocateObject(Class clazz, Class constr_clazz, + Constructor constructor) + throws InstantiationException + { + try + { + Constructor c = clazz.getConstructor(new Class[0]); + c.setAccessible(true); + return c.newInstance(new Object[0]); + } + catch (Exception ex) + { + try + { + Constructor c = clazz.getConstructor(new Class[] { String.class }); + return c.newInstance(new Object[] { "" }); + } + catch (Exception ex2) + { + Constructor c[] = clazz.getConstructors(); + + for (int i = 0; i < c.length; i++) + { + try + { + c[i].setAccessible(true); + Class[] args = c[i].getParameterTypes(); + return c[i].newInstance(new Object[args.length]); + } + catch (Exception ex3) + { + // Try another one. + } + } + } + throw new InstantiationException(clazz.getName()); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/Vio.java b/libjava/classpath/gnu/CORBA/CDR/Vio.java new file mode 100644 index 000000000..1eecb651b --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/Vio.java @@ -0,0 +1,1474 @@ +/* Vio.java -- Value type IO operations. + 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.CDR; + +import gnu.CORBA.Minor; +import gnu.CORBA.ObjectCreator; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.CustomMarshal; +import org.omg.CORBA.DataInputStream; +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.StringValueHelper; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.WStringValueHelper; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.CORBA.portable.ValueFactory; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.StringTokenizer; + +import javax.rmi.CORBA.Util; +import javax.rmi.CORBA.ValueHandler; + +/** + * A specialised class for reading and writing the value types. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class Vio +{ + /** + * If true, wrap value type data into chunks. This decrease the performance, + * and is not required for interoperability with jdk 1.5, but is left in the + * implementation as the optional mode for solving possible interoperability + * problems with non-Sun CORBA implementations. + * + * The current implementation would accept both single chunk or multiple + * chunks, but will always send a single chunk (if true) or unchunked data (if + * false). + */ + public static boolean USE_CHUNKING = false; + + /** + * The first field in the value record. The last octet may contain additional + * flags (vf_CODEBASE, vf_ID and vf_MULTIPLE_IDS). The tag value is different + * for the indirections (vt_INDIRECTION) and nulls (vt_NULL). + */ + public static final int vt_VALUE_TAG = 0x7fffff00; + + /** + * The value tag flag, indicating that the codebase URL is present in the + * value tag record. + */ + public static final int vf_CODEBASE = 0x1; + + /** + * The value tag flag, indicating that a single repository id is present in + * the value tag record. + */ + public static final int vf_ID = 0x2; + + /** + * The value tag flag, indicating, that there are multiple repository ids + * present in the record. If this flag is set, the flag vf_ID must also be + * set, resulting the value of the least significant byte 0x6. + */ + public static final int vf_MULTIPLE_IDS = 0x4; + + /** + * The value tag flag, indicating the presence of chunking. Each chunk is + * preceeded by a positive int, indicating the number of bytes in the chunk. A + * sequence of chunks is terminated by a non positive int. + */ + public static final int vf_CHUNKING = 0x8; + + /** + * The indirection tag value. Such tag must be followed by the CORBA long, + * indicating the offset in the CORBA message, where the indirected + * information is present. This offset is assumed zero at the position where + * the mentioned CORBA long starts and can refer both forward (positive + * values) and backward (negative values). + */ + public static final int vt_INDIRECTION = 0xffffffff; + + /** + * This tag value means that the value object being transferred is equal to + * null. + */ + public static final int vt_NULL = 0x0; + + /** + * The size of CORBA long (java int). + */ + static final int INT_SIZE = 4; + + /** + * The String value helper (one instance is sufficient). + */ + public static final WStringValueHelper m_StringValueHelper = new WStringValueHelper(); + + /** + * An instance of the value handler. + */ + static ValueHandler handler = Util.createValueHandler(); + + /** + * Read the value base from the given input stream. Determines the required + * class from the repository id. This includes operations that are not + * required when an unitialised instance or at least class of the value type + * is known. Hence it may be faster to use the alternative methods, + * read(InputStream, Class) or read(InputStream, Serializable). + * + * @param input a stream to read from. + * + * @return the loaded value. + * + * @throws MARSHAL if the reading has failed due any reason. + */ + public static Serializable read(InputStream input) + { + return read(input, (String) null); + } + + /** + * Read the value base from the given input stream. Determines the required + * class from the repository id. This includes operations that are not + * required when an unitialised instance or at least class of the value type + * is known. Hence it may be faster to use the alternative methods, + * read(InputStream, Class) or read(InputStream, Serializable). + * + * @param input a stream to read from. + * @param repository_id a repository id of the object being read, may be null. + * + * @return the loaded value. + * + * @throws MARSHAL if the reading has failed due any reason. + */ + public static Serializable read(InputStream input, String repository_id) + { + try + { + final int position = getCurrentPosition(input); + // We may need to jump back if the value is read via value factory. + input.mark(512); + + int value_tag = input.read_long(); + checkTag(value_tag); + + String codebase = null; + String[] ids = null; + String id = repository_id; + + // Check for the agreed null value. + if (value_tag == vt_NULL) + return null; + else if (value_tag == vt_INDIRECTION) + return readIndirection(input); + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + // The codebase is present. The codebase is a space + // separated list of URLs from where the implementing + // code can be downloaded. + codebase = read_string(input); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + ids = read_string_array(input); + } + else if ((value_tag & vf_ID) != 0) + { + // Single supported repository id is present. + id = read_string(input); + } + } + + BoxedValueHelper helper = getHelper(null, id); + // The existing implementing object. + java.lang.Object ox = null; + + if (helper != null) + ox = null; // Helper will care about the instantiating. + else if (id.equals(WStringValueHelper.id())) + helper = m_StringValueHelper; + else + ox = createInstance(id, ids, codebase); + return (Serializable) read_instance(input, position, ox, value_tag, + helper, id, ids, codebase); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + } + + /** + * Read the value base from the given input stream when the value base class + * is available. Hence there is no need to guess it from the repository id. + * + * @param input a stream to read from. + * @param value_class the class of the value being read. + * + * @return the loaded value. + * + * @throws MARSHAL if the reading has failed due any reason. + */ + public static Serializable read(InputStream input, Class value_class) + { + final int position = getCurrentPosition(input); + + String id = null; + String[] ids = null; + String codebase = null; + + try + { + int value_tag = input.read_long(); + checkTag(value_tag); + + // Check for the agreed null value. + if (value_tag == vt_NULL) + return null; + else if (value_tag == vt_INDIRECTION) + return readIndirection(input); + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + // The codebase is present. + codebase = read_string(input); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + ids = read_string_array(input); + } + else if ((value_tag & vf_ID) != 0) + { + // Single supported repository id is present. + id = read_string(input); + } + } + + BoxedValueHelper vHelper = id != null ? getHelper(value_class, id) + : getHelper(value_class, ids); + + java.lang.Object ox; + + if (vHelper == null) + { + try + { + ox = createInstance(id, ids, codebase); + } + catch (Exception e) + { + ox = null; + } + + if (ox != null) + { + if (value_class != null + && !value_class.isAssignableFrom(ox.getClass())) + { + MARSHAL m = new MARSHAL(ox.getClass() + " is not a " + + value_class.getName()); + m.minor = Minor.ClassCast; + throw m; + } + } + } + else + ox = null; + + ox = read_instance(input, position, ox, value_tag, vHelper, id, ids, + codebase); + return (Serializable) ox; + } + catch (MARSHAL m) + { + throw m; + } + catch (SystemException sysEx) + { + // OK. + throw sysEx; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Cant read " + value_class); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + } + + /** + * Read the value base from the given input stream when the unitialised + * instance is available. Hence there is no need to guess the class from the + * repository id and then to instantiate an instance. + * + * @param input a stream to read from. + * + * @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 Object read(InputStream input, Object value_instance, + BoxedValueHelper helper) + { + final int position = getCurrentPosition(input); + + String id = null; + String[] ids = null; + String codebase = null; + + try + { + int value_tag = input.read_long(); + checkTag(value_tag); + + // Check for the agreed null value. + if (value_tag == vt_NULL) + return null; + else if (value_tag == vt_INDIRECTION) + return readIndirection(input); + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + // The codebase is present. + codebase = read_string(input); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + ids = read_string_array(input); + } + else if ((value_tag & vf_ID) != 0) + { + // Single supported repository id is present. + id = read_string(input); + } + } + + Class value_class = value_instance == null ? null + : value_instance.getClass(); + + if (helper == null) + helper = id != null ? getHelper(value_class, id) : getHelper( + value_class, ids); + + value_instance = read_instance(input, position, value_instance, + value_tag, helper, id, ids, codebase); + return value_instance; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + } + + /** + * 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, BoxedValueHelper 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 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. + */ + static Object read_instance(InputStream input, final int position, + Object value, int value_tag, BoxedValueHelper helper, String id, + String[] ids, String codebase) + { + if (helper != m_StringValueHelper && id != null) + if (id.equals(StringValueHelper.id())) + { + value = null; + helper = m_StringValueHelper; + } + + try + { + if ((value_tag & vf_CHUNKING) != 0) + { + BufferedCdrOutput output = createBuffer(input, 1024); + // Read the current (not a nested one) value in this spec case. + readNestedValue(value_tag, input, output, -1); + BufferredCdrInput ci = new BufferredCdrInput(output.buffer.getBuffer()); + ci.setRunTime(output.getRunTime()); + + input = new HeadlessInput(ci, input); + } + else + { + if (input instanceof BufferredCdrInput) + { + // Highly probable case. + input = new HeadlessInput((BufferredCdrInput) input, null); + } + else if (input instanceof HeadlessInput) + { + // There is no need to instantiate one more HeadlessInput + // as we can just reset. + ((HeadlessInput) input).subsequentCalls = false; + } + else + { + BufferedCdrOutput bout = new BufferedCdrOutput(); + int c; + while ((c = input.read()) >= 0) + bout.write((byte) c); + input = new HeadlessInput( + (BufferredCdrInput) bout.create_input_stream(), input); + } + } + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL("Unable to read chunks"); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + + return readValue(input, position, value, helper, id, ids, codebase); + } + + /** + * Create a buffer, inheriting critical settings from the passed input stream. + */ + private static BufferedCdrOutput createBuffer(InputStream input, int proposed_size) + { + BufferedCdrOutput bout; + bout = new BufferedCdrOutput(2 * proposed_size + 256); + + if (input instanceof BufferredCdrInput) + { + BufferredCdrInput in = (BufferredCdrInput) input; + bout.setBigEndian(in.isBigEndian()); + } + + if (input instanceof gnuValueStream) + bout.setRunTime(((gnuValueStream) input).getRunTime()); + else + bout.setRunTime(new gnuRuntime(null, null)); + return bout; + } + + /** + * Read the chunked nested value from the given input stream, transferring the + * contents to the given output stream. + * + * @param value_tag the value tag of the value being read. + * @param input the input stream from where the remainder of the nested value + * must be read. + * @param output the output stream where the unchunked nested value must be + * copied. + * + * @return the tag that ended the nested value. + */ + public static int readNestedValue(int value_tag, InputStream input, + BufferedCdrOutput output, int level) + throws IOException + { + String id = null; + if (level < -1) + { + // For the first level, this information is already behind. + output.write_long(value_tag - vf_CHUNKING); + + // The nested value should be aways chunked. + if ((value_tag & vf_CHUNKING) == 0) + { + MARSHAL m = new MARSHAL("readNestedValue: must be chunked"); + m.minor = Minor.Chunks; + throw m; + } + else if (value_tag == vt_NULL) + { + MARSHAL m = new MARSHAL("readNestedValue: nul"); + m.minor = Minor.Chunks; + throw m; + } + else if (value_tag == vt_INDIRECTION) + { + MARSHAL m = new MARSHAL("readNestedValue: indirection"); + m.minor = Minor.Chunks; + throw m; + } + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + String codebase = read_string(input); + write_string(output, codebase); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + String[] ids = read_string_array(input); + id = ids[0]; + write_string_array(output, ids); + } + else if ((value_tag & vf_ID) != 0) + { + id = read_string(input); + write_string(output, id); + } + } + } + + int n = -1; + + // Read all chunks. + int chunk_size; + + byte[] r = null; + + while (true) + { + // Read the size of the next chunk or it may also be the + // header of the nested value. + chunk_size = input.read_long(); + + // End of chunk terminator. + if (chunk_size < 0 && chunk_size >= level) + return chunk_size; + else if (chunk_size >= 0x7FFFFF00) + { + int onInput = getCurrentPosition(input) - 4; + int onOutput = output.getPosition(); + output.getRunTime().redirect(onInput, onOutput); + // Value over 0x7FFFFF00 indicates that the nested value + // starts here. Read the nested value, storing it into the output. + // First parameter is actually the value tag. + chunk_size = readNestedValue(chunk_size, input, output, level - 1); + if (chunk_size < 0 && chunk_size >= level) + return chunk_size; + } + else + { + // The chunk follows. + if (r == null || r.length < chunk_size) + r = new byte[chunk_size + 256]; + + n = 0; + while (n < chunk_size) + n += input.read(r, n, chunk_size - n); + output.write(r, 0, n); + } + } + } + + /** + * Read the value (the header must be behind). + */ + public static Serializable readValue(InputStream input, final int position, + Object value, BoxedValueHelper helper, String id, String[] ids, + String codebase) + { + gnuRuntime g; + gnuValueStream c = ((gnuValueStream) input); + if (c.getRunTime() == null) + { + g = new gnuRuntime(codebase, value); + c.setRunTime(g); + } + else + { + g = c.getRunTime(); + g.addCodeBase(codebase); + g.target = (Serializable) value; + } + if (value != null) + g.objectWritten(value, position); + + if (input instanceof HeadlessInput) + ((HeadlessInput) input).subsequentCalls = false; + + boolean ok = true; + + // The user-defined io operations are implemented. + if (value instanceof CustomMarshal) + { + CustomMarshal marsh = (CustomMarshal) value; + marsh.unmarshal((DataInputStream) input); + } + else + // The IDL-generated io operations are implemented. + if (value instanceof Streamable) + { + ((Streamable) value)._read(input); + } + else if (helper != null) + { + // If helper is non-null the value should normally be null. + value = helper.read_value(input); + g.objectWritten(value, position); + } + else + { + ok = false; + ValueFactory factory = null; + org.omg.CORBA_2_3.ORB orb = (org.omg.CORBA_2_3.ORB) input.orb(); + + if (id != null) + factory = orb.lookup_value_factory(id); + + if (factory == null && ids != null) + { + for (int i = 0; i < ids.length && factory == null; i++) + { + factory = orb.lookup_value_factory(ids[i]); + } + } + + if (factory != null) + { + value = factory.read_value((org.omg.CORBA_2_3.portable.InputStream) input); + ok = true; + } + } + + if (!ok && value instanceof Serializable) + // Delegate to ValueHandler + { + if (ids != null && ids.length > 0) + id = ids[0]; + + value = handler.readValue(input, position, value.getClass(), id, g); + ok = true; + } + + if (!ok) + { + if (value != null) + { + MARSHAL m = new MARSHAL(value.getClass().getName() + + " must be Streamable, CustomMarshal or Serializable"); + m.minor = Minor.UnsupportedValue; + throw m; + } + else + { + MARSHAL m = new MARSHAL("Unable to instantiate " + id + ":" + list(ids) + + " helper " + helper); + m.minor = Minor.UnsupportedValue; + throw m; + } + } + else + return (Serializable) value; + } + + /** + * Conveniency method to list ids in exception reports. + */ + static String list(String[] s) + { + if (s == null) + return "null"; + else + { + CPStringBuilder b = new CPStringBuilder("{"); + for (int i = 0; i < s.length; i++) + { + b.append(s[i]); + b.append(" "); + } + b.append("}"); + return b.toString(); + } + } + + /** + * Write the value base into the given stream. + * + * @param output a stream to write to. + * + * @param value a value type object, must be either Streamable or + * CustomMarshal. + * + * @throws MARSHAL if the writing failed due any reason. + */ + public static void write(OutputStream output, Serializable value) + { + // Write null if this is a null value. + if (value == null) + output.write_long(vt_NULL); + else if (value instanceof String) + write(output, value, m_StringValueHelper); + else + write(output, value, value.getClass()); + } + + /** + * Write the value base into the given stream, stating that it is an instance + * of the given class. + * + * @param output a stream to write to. + * + * @param value a value to write. + * + * @throws MARSHAL if the writing failed due any reason. + */ + public static void write(OutputStream output, Serializable value, + Class substitute) + { + // Write null if this is a null value. + if (value == null) + output.write_long(vt_NULL); + else if (value instanceof String || substitute == String.class) + writeString(output, value); + else + { + String vId = ObjectCreator.getRepositoryId(value.getClass()); + if (substitute == null || value.getClass().equals(substitute)) + write_instance(output, value, vId, getHelper(value.getClass(), vId)); + else + { + String vC = ObjectCreator.getRepositoryId(substitute); + String[] ids = new String[] { vId, vC }; + BoxedValueHelper h = getHelper(substitute.getClass(), ids); + // If the helper is available, it is also responsible for + // providing the repository Id. Otherwise, write both + // ids. + if (h == null) + write_instance(output, value, ids, null); + else + write_instance(output, value, h.get_id(), null); + } + } + } + + /** + * Write the value base into the given stream, supplementing it with an array + * of the provided repository ids plus the repository id, derived from the + * passed value. + * + * @param output a stream to write to. + * + * @param value a value to write. + * + * @throws MARSHAL if the writing failed due any reason. + */ + public static void write(OutputStream output, Serializable value, + String[] multiple_ids) + { + // Write null if this is a null value. + if (value == null) + output.write_long(vt_NULL); + else + { + String[] ids = new String[multiple_ids.length + 1]; + ids[0] = ObjectCreator.getRepositoryId(value.getClass()); + System.arraycopy(multiple_ids, 0, ids, 1, multiple_ids.length); + BoxedValueHelper h = getHelper(value.getClass(), ids); + write_instance(output, value, ids, h); + } + } + + /** + * Write value when its repository Id is explicitly given. Only this Id is + * written, the type of value is not taken into consideration. + * + * @param output an output stream to write into. + * @param value a value to write. + * @param id a value repository id. + */ + public static void write(OutputStream output, Serializable value, String id) + { + if (value == null) + output.write_long(vt_NULL); + else + write_instance(output, value, id, getHelper(value.getClass(), id)); + } + + /** + * 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 + * (must be provided for this method). + */ + public static void write(OutputStream output, Serializable value, + BoxedValueHelper helper) + { + if (helper == null) + throw new AssertionError("Helper must be provided"); + if (value == null) + output.write_long(vt_NULL); + else + write_instance(output, value, helper.get_id(), helper); + } + + /** + * Write the parameter that is surely a string and not null. + */ + private static void writeString(OutputStream output, Serializable string) + { + write_instance(output, string, m_StringValueHelper.get_id(), + m_StringValueHelper); + } + + /** + * Write value when its repository Id is explicitly given. Does not handle + * null. + * + * @param output an output stream to write into. + * @param value a value to write. + * @param ids a value repository id (can be either single string or string + * array). + * @param helper a helper, writing object - specifical part. Can be null if + * the value should be written using other methods. + */ + static void write_instance(OutputStream output, Serializable value, + Object ids, BoxedValueHelper helper) + { + gnuValueStream rout = null; + gnuRuntime runtime = null; + + try + { + if (output instanceof gnuValueStream) + { + int position; + rout = (gnuValueStream) output; + runtime = rout.getRunTime(); + + if (runtime == null) + { + runtime = new gnuRuntime(null, value); + rout.setRunTime(runtime); + rout.getRunTime().objectWritten(value, + position = rout.getPosition()); + } + else if (runtime.target == value) + { + if (!writeSelf(output, value)) + throw new InternalError("Recursive helper call for " + + value.getClass().getName()); + return; + } + else + { + position = runtime.isWrittenAt(value); + if (position >= 0) + { + // The object was already written. + output.write_long(vt_INDIRECTION); + output.write_long(position - rout.getPosition()); + // Replacing object write data by indirection reference. + return; + } + else + { + runtime.objectWritten(value, position = rout.getPosition()); + } + } + } + + int value_tag = vt_VALUE_TAG; + + if (ids instanceof String) + value_tag |= vf_ID; + else if (ids instanceof String[]) + // OMG standard requires to set both flags. + value_tag |= vf_MULTIPLE_IDS | vf_ID; + + int chunkSizeLocation; + + OutputStream outObj; + + if (USE_CHUNKING) + { + // Wrap the value being written into one chunk (makes sense only for + // compatibility reasons). + outObj = output; + value_tag |= vf_CHUNKING; + } + else + outObj = output; + + output.write_long(value_tag); + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + write_string_array(output, (String[]) ids); + else if ((value_tag & vf_ID) != 0) + write_string(output, (String) ids); + + if (USE_CHUNKING) + { + // So far, write 0x55555555 instead of the chunk size (alignment may + // take place). + output.write_long(0x55555555); + // If the chunking is involved, the chunk size must be written here. + chunkSizeLocation = rout.getPosition() - INT_SIZE; + } + else + // Not in use for this case. + chunkSizeLocation = -1; + + writeValue(outObj, value, helper); + + if (USE_CHUNKING) + { + // Write the chunk size where the place for it was reserved. + int chunkSize = rout.getPosition() - chunkSizeLocation - INT_SIZE; + int current = rout.getPosition(); + rout.seek(chunkSizeLocation); + output.write_long(chunkSize); + rout.seek(current); + + // The end of record marker. + output.write_long(-1); + } + } + finally + { + if (runtime != null) + runtime.target = null; + } + } + + /** + * Write value (after header). + */ + static void writeValue(OutputStream output, Serializable value, + BoxedValueHelper helper) + { + ((gnuValueStream) output).getRunTime().target = value; + if (helper != null) + helper.write_value(output, value); + else if (!writeSelf(output, value)) + { + // Try to find helper via class loader. + boolean ok = false; + + if (!ok) + { + if (output instanceof BufferedCdrOutput) + { + BufferedCdrOutput b = (BufferedCdrOutput) output; + if (b.runtime == null) + b.runtime = new gnuRuntime(null, value); + } + + handler.writeValue(output, value); + } + } + } + + /** + * Try to write value supposing that it implements self-streamable interfaces. + * Return false if it does not or true on success. + */ + static boolean writeSelf(OutputStream output, Serializable value) + { + // User defined write method is present. + if (value instanceof CustomMarshal) + { + ((CustomMarshal) value).marshal((DataOutputStream) output); + return true; + } + else if (value instanceof Streamable) + { + ((Streamable) value)._write(output); + return true; + } + return false; + } + + /** + * Read the indirection data and return the object that was already written to + * this stream. + * + * @param an_input the input stream, must be BufferredCdrInput. + */ + static Serializable readIndirection(InputStream an_input) + { + if (!(an_input instanceof gnuValueStream)) + throw new NO_IMPLEMENT(gnuValueStream.class.getName() + + " expected as parameter"); + + gnuValueStream in = (gnuValueStream) an_input; + + int current_pos = in.getPosition(); + + int offset = an_input.read_long(); + if (offset > -INT_SIZE) + { + MARSHAL m = new MARSHAL("Indirection tag refers to " + offset + + " (must be less than -" + INT_SIZE + ")"); + m.minor = Minor.Offset; + throw m; + } + + int stored_at = current_pos + offset; + + if (in.getRunTime() == null) + { + MARSHAL m = new MARSHAL(stored_at + " offset " + offset + ": not written"); + m.minor = Minor.Value; + throw m; + } + + return (Serializable) in.getRunTime().isObjectWrittenAt(stored_at, offset); + } + + /** + * Check the passed value tag for correctness. + * + * @param value_tag a tag to check, must be between 0x7fffff00 and 0x7fffffff + * + * @throws MARSHAL if the tag is outside this interval. + */ + static void checkTag(int value_tag) + { + if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff) + && value_tag != vt_NULL && value_tag != vt_INDIRECTION) + { + MARSHAL m = new MARSHAL("Invalid value record, unsupported header tag: " + + value_tag + " (0x" + Integer.toHexString(value_tag) + ")"); + m.minor = Minor.ValueHeaderTag; + throw m; + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0 && (value_tag & vf_ID) == 0) + { + MARSHAL m = new MARSHAL("Invalid value record header flag combination (0x" + + Integer.toHexString(value_tag) + ")"); + m.minor = Minor.ValueHeaderFlags; + throw m; + } + } + + /** + * Throw MARSHAL. + */ + static void throwIt(String msg, String id1, String id2, Throwable e) + throws MARSHAL + { + MARSHAL m = new MARSHAL(msg + ":'" + id1 + "' versus '" + id2 + "'"); + if (e != null) + m.initCause(e); + m.minor = Minor.Value; + throw m; + } + + /** + * Load class by name and create the instance. + */ + static Object createInstance(String id, String[] ids, String codebase) + { + Object o = null; + + if (id != null) + o = _createInstance(id, codebase); + + if (ids != null) + for (int i = 0; i < ids.length && o == null; i++) + o = _createInstance(ids[i], codebase); + return o; + } + + static Object _createInstance(String id, String codebase) + { + if (id == null) + return null; + if (id.equals(StringValueHelper.id())) + return ""; + StringTokenizer st = new StringTokenizer(id, ":"); + + String prefix = st.nextToken(); + if (prefix.equalsIgnoreCase("IDL")) + return ObjectCreator.Idl2Object(id); + else if (prefix.equalsIgnoreCase("RMI")) + { + String className = st.nextToken(); + String hashCode = st.nextToken(); + String sid = null; + if (st.hasMoreElements()) + sid = st.nextToken(); + + try + { + Class objectClass = Util.loadClass(className, codebase, + Vio.class.getClassLoader()); + + String rid = ObjectCreator.getRepositoryId(objectClass); + + if (!rid.equals(id)) + { + // If direct string comparison fails, compare by meaning. + StringTokenizer st2 = new StringTokenizer(rid, ":"); + if (!st2.nextToken().equals("RMI")) + throw new InternalError("RMI format expected: '" + rid + "'"); + if (!st2.nextToken().equals(className)) + throwIt("Class name mismatch", id, rid, null); + + try + { + long h1 = Long.parseLong(hashCode, 16); + long h2 = Long.parseLong(st2.nextToken(), 16); + if (h1 != h2) + throwIt("Hashcode mismatch", id, rid, null); + + if (sid != null && st2.hasMoreTokens()) + { + long s1 = Long.parseLong(hashCode, 16); + long s2 = Long.parseLong(st2.nextToken(), 16); + if (s1 != s2) + throwIt("serialVersionUID mismatch", id, rid, null); + } + } + catch (NumberFormatException e) + { + throwIt("Invalid hashcode or svuid format: ", id, rid, e); + } + } + + // Low - level instantiation required here. + return instantiateAnyWay(objectClass); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Unable to instantiate " + id); + m.minor = Minor.Instantiation; + m.initCause(ex); + throw m; + } + } + else + throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":"); + } + + /** + * Read string, expecting the probable indirection. + */ + static String read_string(InputStream input) + { + gnuValueStream g = (gnuValueStream) input; + int previous = g.getPosition(); + int l = input.read_long(); + if (l != vt_INDIRECTION) + { + g.seek(previous); + String s = input.read_string(); + if (g.getRunTime() == null) + g.setRunTime(new gnuRuntime(null, null)); + g.getRunTime().singleIdWritten(s, previous); + return s; + } + else + { + gnuRuntime r = g.getRunTime(); + int base = g.getPosition(); + int delta = input.read_long(); + if (r == null) + { + previous = g.getPosition(); + g.seek(base + delta); + String indir = input.read_string(); + g.seek(previous); + return indir; + } + else + { + return (String) r.isObjectWrittenAt(base + delta, delta); + } + } + } + + /** + * Read string array, expecting the probable indirection. + */ + static String[] read_string_array(InputStream input) + { + gnuValueStream g = (gnuValueStream) input; + int previous = g.getPosition(); + int l = input.read_long(); + if (l != vt_INDIRECTION) + { + g.seek(previous); + String[] s = StringSeqHelper.read(input); + if (g.getRunTime() == null) + g.setRunTime(new gnuRuntime(null, null)); + g.getRunTime().objectWritten(s, previous); + return s; + } + else + { + gnuRuntime r = g.getRunTime(); + int base = g.getPosition(); + int delta = input.read_long(); + if (r == null) + { + previous = g.getPosition(); + g.seek(base + delta); + String[] indir = StringSeqHelper.read(input); + g.seek(previous); + return indir; + } + else + { + return (String[]) r.isObjectWrittenAt(base + delta, delta); + } + } + } + + /** + * Write repository Id, probably shared. + */ + static void write_string(OutputStream output, String id) + { + if (output instanceof gnuValueStream) + { + gnuValueStream b = (gnuValueStream) output; + if (b != null) + { + int written = b.getRunTime().idWrittenAt(id); + if (written >= 0) + { + // Reuse existing id record. + output.write_long(vt_INDIRECTION); + int p = b.getPosition(); + output.write_long(written - p); + } + else + { + b.getRunTime().singleIdWritten(id, b.getPosition()); + output.write_string(id); + } + } + } + else + output.write_string(id); + } + + /** + * Write repository Id, probably shared. + */ + static void write_string_array(OutputStream output, String[] ids) + { + if (output instanceof gnuValueStream) + { + gnuValueStream b = (gnuValueStream) output; + if (b != null) + { + int written = b.getRunTime().idWrittenAt(ids); + if (written >= 0) + { + // Reuse existing id record. + output.write_long(vt_INDIRECTION); + int p = b.getPosition(); + output.write_long(written - p); + } + else + { + b.getRunTime().multipleIdsWritten(ids, b.getPosition()); + StringSeqHelper.write(output, ids); + } + } + } + else + StringSeqHelper.write(output, ids); + } + + /** + * Get the helper that could write the given object, or null if no pre-defined + * helper available for this object. + */ + public static BoxedValueHelper getHelper(Class x, Object ids) + { + if (x != null && x.equals(String.class)) + return m_StringValueHelper; + else if (x != null && x.isArray()) + return new ArrayValueHelper(x); + else if (ids instanceof String) + return locateHelper((String) ids); + else if (ids instanceof String[]) + { + String[] ia = (String[]) ids; + BoxedValueHelper h; + for (int i = 0; i < ia.length; i++) + { + h = locateHelper(ia[i]); + if (h != null) + return h; + } + return null; + } + else + return null; + } + + /** + * Get the helper that could write the given object, or null if no pre-defined + * helper available for this object. + */ + public static BoxedValueHelper getHelper(Class x, String id) + { + if (x != null && x.equals(String.class)) + return m_StringValueHelper; + else if (x != null && x.isArray()) + return new ArrayValueHelper(x); + else + return locateHelper(id); + } + + /** + * Try to locate helper from the repository id. + */ + static BoxedValueHelper locateHelper(String id) + { + if (id != null) + { + if (id.equals(m_StringValueHelper.get_id())) + return m_StringValueHelper; + else + // Try to locate helper for IDL type. + if (id.startsWith("IDL:")) + { + try + { + Class helperClass = ObjectCreator.findHelper(id); + if (BoxedValueHelper.class.isAssignableFrom(helperClass)) + return (BoxedValueHelper) helperClass.newInstance(); + else if (helperClass != null) + return new IDLTypeHelper(helperClass); + else + return null; + } + catch (Exception ex) + { + return null; + } + } + } + return null; + } + + /** + * Get the current position. + */ + static int getCurrentPosition(InputStream x) + { + if (x instanceof gnuValueStream) + return ((gnuValueStream) x).getPosition(); + else + return 0; + } + + /** + * Instantiate an instance of this class anyway; also in the case when it has + * no parameterless or any other constructor. The fields will be assigned + * while reading the class from the stream. + * + * @param clazz a class for that the instance should be instantiated. + */ + public static Object instantiateAnyWay(Class clazz) + throws Exception + { + Class first_nonserial = clazz; + + while (Serializable.class.isAssignableFrom(first_nonserial) + || Modifier.isAbstract(first_nonserial.getModifiers())) + first_nonserial = first_nonserial.getSuperclass(); + + final Class local_constructor_class = first_nonserial; + + Constructor constructor = local_constructor_class.getDeclaredConstructor(new Class[0]); + + return VMVio.allocateObject(clazz, constructor.getDeclaringClass(), + constructor); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java b/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java new file mode 100644 index 000000000..1d07094e9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java @@ -0,0 +1,338 @@ +/* gnuRuntime.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.MARSHAL; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Our implementation of the sending context runtime. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuRuntime + extends LocalObject + implements org.omg.SendingContext.RunTime +{ + /** + * The data entry about the object that was written. + */ + static class Entry + { + /** + * The stream position, where the object was written. + */ + int at; + + /** + * The object that was written. + */ + Object object; + + public String toString() + { + return object + "[" + at + "] "+object.getClass().getName(); + } + } + + /** + * The instruction that the actual object is stored at different location. + * Used when processing chunked data where positions shifts due removing the + * chunking tags. + */ + static class Redirection + extends Entry + { + public String toString() + { + return "->" + at; + } + } + + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The history of the written objects, maps object to records. The different + * objects must be treated as different regardless that .equals returns. + */ + private Map sh_objects = new IdentityHashMap(); + + /** + * The written repository Ids that can be shared. + */ + private Map sh_ids = new TreeMap(new Comparator() + { + public int compare(Object a, Object b) + { + if (a instanceof String && b instanceof String) + // Comparing string with string. + return ((String) a).compareTo((String) b); + else if (a instanceof String[] && b instanceof String[]) + { + // Comparing array with array. + String[] sa = (String[]) a; + String[] sb = (String[]) b; + + if (sa.length != sb.length) + return sa.length - sb.length; + else + { + int c; + for (int i = 0; i < sa.length; i++) + { + c = sa[i].compareTo(sb[i]); + if (c != 0) + return c; + } + return 0; + } + } + else + // Comparing string with array. + return a instanceof String ? 1 : -1; + } + }); + + /** + * The history of the written objects, maps positions to records. The + * different objects must be treated as different regardless that .equals + * returns. + */ + private Map positions = new HashMap(); + + /** + * The Codebase. + */ + private String codebase; + + /** + * The pre-created instance of the object being written (avoid + * re-instantiation). + */ + public Serializable target; + + /** + * Create Runtime. + * + * @param a_id a repository Id, if only one Id was specified in the stream. + * @param a_ids a repository Ids, if the multiple Ids were specified in te + * stream. + * @param a_codebase a codebase, if it was specified in the stream. + */ + public gnuRuntime(String a_codebase, Object a_target) + { + if (a_target instanceof Serializable) + target = (Serializable) a_target; + + codebase = a_codebase; + } + + /** + * Mark the given object as written at the given position. + */ + public void objectWritten(Object object, int at) + { + if (object == null || at < 0) + return; // No positional information provided. + if (sh_objects.containsKey(object)) + throw new AssertionError("Repetetive writing of the same object " + + object + " at " + at + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = object; + + sh_objects.put(object, e); + positions.put(new Integer(at), e); + } + + /** + * Check if the object is already written. + * + * @return the position, at that the object is allready written or -1 if it is + * not yet written. + */ + public int isWrittenAt(Object x) + { + Entry e = (Entry) sh_objects.get(x); + return e == null ? -1 : e.at; + } + + /** + * Set redirection, indicating that the object, searched at the p_searched + * position can be actually found at the p_present position. + */ + public void redirect(int p_searched, int p_present) + { + Redirection redirection = new Redirection(); + redirection.at = p_present; + positions.put(new Integer(p_searched), redirection); + } + + /** + * Get the object, written at the given position. This returs both shared + * objects and repository Ids. + * + * @return the position, at that the object is allready written. + * + * @throws MARSHAL if there is no object written at that position. + */ + public Object isObjectWrittenAt(int x, int offset) + { + Entry e = (Entry) positions.get(new Integer(x)); + if (e instanceof Redirection) + return isObjectWrittenAt(e.at, offset); + else if (e != null) + return e.object; + else + { + MARSHAL m = new MARSHAL("No object was written at " + x + + " (offset " + offset + ") r " + this + dump()); + m.minor = Minor.Graph; + throw m; + } + } + + /** + * Mark the given object as written at the given position. + */ + public void singleIdWritten(String id, int at) + { + if (sh_ids.containsKey(id)) + throw new InternalError("Repetetive writing of the same string " + + id + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = id; + + sh_ids.put(id, e); + positions.put(new Integer(at), e); + } + + /** + * Mark the given object as written at the given position. + */ + public void multipleIdsWritten(String[] ids, int at) + { + if (sh_ids.containsKey(ids)) + throw new InternalError("Repetetive writing of the same string " + + ids + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = ids; + + sh_ids.put(ids, e); + positions.put(new Integer(at), e); + } + + /** + * Check if the object is already written. + * + * @return the position, at that the object is allready written or -1 if it is + * not yet written. + */ + public int idWrittenAt(Object x) + { + Entry e = (Entry) sh_ids.get(x); + return e == null ? -1 : e.at; + } + + /** + * Get the codebase. + */ + public String getCodeBase() + { + return codebase; + } + + /** + * Set the codebase, preserving the old value if the passed parameter is null + * and forming the space delimited list if both new and old values are not + * null. + */ + public void addCodeBase(String base) + { + if (base != null) + { + if (codebase == null) + codebase = base; + else + codebase = codebase + " " + base; + } + } + + /** + * Dump all objects that are currently stored. + */ + public String dump() + { + CPStringBuilder b = new CPStringBuilder(" Stream content: \n"); + + // Sort by position. + TreeSet t = new TreeSet(positions.keySet()); + Iterator p = t.iterator(); + + while (p.hasNext()) + { + Object k = p.next(); + b.append(" " + k + ": " + ((Entry) positions.get(k)).toString() + + "\n"); + } + return b.toString(); + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java b/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java new file mode 100644 index 000000000..95d9edb2e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java @@ -0,0 +1,71 @@ +/* gnuValueStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +/** + * A stream, implementing this interface, provides methods to get/set a position + * and get the RunTime. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface gnuValueStream +{ + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition(); + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position); + + /** + * Get the RunTime information. + */ + public gnuRuntime getRunTime(); + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime); + +} diff --git a/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java b/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java new file mode 100644 index 000000000..1dc7f9282 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CdrEncapsCodecImpl.java @@ -0,0 +1,358 @@ +/* CdrEncapsCodecImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.CDR.AbstractCdrOutput; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UserException; +import org.omg.IOP.Codec; +import org.omg.IOP.CodecPackage.FormatMismatch; +import org.omg.IOP.CodecPackage.InvalidTypeForEncoding; +import org.omg.IOP.CodecPackage.TypeMismatch; + +/** + * The local {@link Codec} implementation for ENCODING_CDR_ENCAPS + * encoding. This is a local implementation; the remote side should + * have its own Codec of this kind. + * + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class CdrEncapsCodecImpl + extends LocalObject + implements Codec +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * If set to true, no wide string or wide character is allowed (GIOP 1.0). + */ + private final boolean noWide; + + /** + * The version of this encoding. + */ + private final Version version; + + /** + * The associated ORB. + */ + protected final ORB orb; + + /** + * If true, this Codec writes the record length (as int) in the beginning + * of the record. This indicator is part of the formal OMG standard, but it is + * missing in Sun's implementation. Both Suns's and this Codec detects + * the indicator, if present, but can also decode data where this information + * is missing. If the length indicator is missing, the first four bytes in + * Suns encoding are equal to 0 (Big Endian marker). + */ + private boolean lengthIndicator = true; + + /** + * Create an instance of this Codec, encoding following the given version. + */ + public CdrEncapsCodecImpl(ORB _orb, Version _version) + { + orb = _orb; + version = _version; + noWide = version.until_inclusive(1, 0); + } + + /** + * Return the array of repository ids for this object. + * + * @return { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" }, always. + */ + public String[] _ids() + { + return new String[] { "IDL:gnu/CORBA/cdrEnapsCodec:1.0" }; + } + + /** + * Decode the contents of the byte array into Any. + * The byte array may have the optional four byte length indicator + * in the beginning. If these four bytes are zero, it is assumed, + * that no length indicator is present. + */ + public Any decode(byte[] them) + throws FormatMismatch + { + BufferredCdrInput input = createInput(them); + BufferredCdrInput encapsulation = createEncapsulation(them, input); + + TypeCode type = encapsulation.read_TypeCode(); + + try + { + checkTypePossibility("", type); + } + catch (InvalidTypeForEncoding ex) + { + throw new FormatMismatch(ex.getMessage()); + } + + return readAny(type, encapsulation); + } + + private BufferredCdrInput createEncapsulation(byte[] them, BufferredCdrInput input) + { + BufferredCdrInput encapsulation; + + if ((them [ 0 ] | them [ 1 ] | them [ 2 ] | them [ 3 ]) == 0) + { + // Skip that appears to be the always present Big Endian marker. + encapsulation = input; + input.read_short(); + } + else + encapsulation = input.read_encapsulation(); + return encapsulation; + } + + /** {@inheritDoc} */ + public byte[] encode(Any that) + throws InvalidTypeForEncoding + { + checkTypePossibility("", that.type()); + + BufferedCdrOutput output = createOutput(that); + + // BufferedCdrOutput has internal support for this encoding. + AbstractCdrOutput encapsulation = output.createEncapsulation(); + + try + { + TypeCodeHelper.write(encapsulation, that.type()); + that.write_value(encapsulation); + + encapsulation.close(); + output.close(); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Encapsulation; + m.initCause(ex); + throw m; + } + return output.buffer.toByteArray(); + } + + /** + * Decode the value, stored in the byte array, into Any, assuming, + * that the byte array holds the data structure, defined by the + * given typecode. + * + * The byte array may have the optional four byte length indicator + * in the beginning. If these four bytes are zero, it is assumed, + * that no length indicator is present. + */ + public Any decode_value(byte[] them, TypeCode type) + throws FormatMismatch, TypeMismatch + { + try + { + checkTypePossibility("", type); + } + catch (InvalidTypeForEncoding ex) + { + throw new TypeMismatch(ex.getMessage()); + } + + BufferredCdrInput input = createInput(them); + BufferredCdrInput encapsulation = createEncapsulation(them, input); + return readAny(type, encapsulation); + } + + /** + * Read an Any from the given stream. + * + * @param type a type of the Any to read. + * @param input the encapsulation stream. + */ + private Any readAny(TypeCode type, BufferredCdrInput encapsulation) + throws MARSHAL + { + gnuAny a = new gnuAny(); + a.setOrb(orb); + + // BufferredCdrInput has internal support for this encoding. + a.read_value(encapsulation, type); + return a; + } + + /** {@inheritDoc} */ + public byte[] encode_value(Any that) + throws InvalidTypeForEncoding + { + checkTypePossibility("", that.type()); + + BufferedCdrOutput output = createOutput(that); + + AbstractCdrOutput encapsulation = output.createEncapsulation(); + + try + { + that.write_value(encapsulation); + + encapsulation.close(); + output.close(); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Encapsulation; + m.initCause(ex); + throw m; + } + return output.buffer.toByteArray(); + } + + /** + * Create the CDR output stream for writing the given Any. + * The BufferedCdrOutput has internal support for encapsulation encodings. + * + * @param that the Any that will be written. + * + * @return the stream. + * + * @throws InvalidTypeForEncoding if that Any cannot be written under the + * given version. + */ + private BufferedCdrOutput createOutput(Any that) + throws InvalidTypeForEncoding + { + BufferedCdrOutput output = new BufferedCdrOutput(); + output.setOrb(orb); + output.setVersion(version); + return output; + } + + /** + * Checks if the given type can be encoded. Currently only checks for wide + * strings and wide chars for GIOP 1.0. + * + * @param t a typecode to chek. + * + * @throws InvalidTypeForEncoding if the typecode is not valid for the given + * version. + */ + private void checkTypePossibility(String name, TypeCode t) + throws InvalidTypeForEncoding + { + if (noWide) + { + try + { + int kind = t.kind().value(); + + if (kind == TCKind._tk_wchar || kind == TCKind._tk_wstring) + throw new InvalidTypeForEncoding(name + " wide char in " + + version + ); + else if (kind == TCKind._tk_alias || kind == TCKind._tk_array || + kind == TCKind._tk_sequence + ) + checkTypePossibility("Array member", t.content_type()); + + else if (kind == TCKind._tk_struct || kind == TCKind._tk_union) + { + for (int i = 0; i < t.member_count(); i++) + { + checkTypePossibility(t.member_name(i), t.member_type(i)); + } + } + } + catch (UserException ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + } + + /** + * Create the CDR input stream for reading the given byte array. + * + * @param them a byte array to read. + * + * @return the stream. + */ + private BufferredCdrInput createInput(byte[] them) + { + BufferredCdrInput input = new BufferredCdrInput(them); + input.setOrb(orb); + input.setVersion(version); + return input; + } + + /** + * Check if the Codec writes the length indicator. + */ + public boolean hasLengthIndicator() + { + return lengthIndicator; + } + + /** + * Sets if the Codec must write the record length in the beginning of the + * array. Encodings both with and without that indicator are understood + * both by Suns and this codec, but the OMG specification seems requiring + * it. The default behavior is to use the length indicator. + * + * @param use_lengthIndicator + */ + public void setUseLengthIndicator(boolean use_lengthIndicator) + { + lengthIndicator = use_lengthIndicator; + } +} diff --git a/libjava/classpath/gnu/CORBA/CollocatedOrbs.java b/libjava/classpath/gnu/CORBA/CollocatedOrbs.java new file mode 100644 index 000000000..5634ff3cf --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CollocatedOrbs.java @@ -0,0 +1,160 @@ +/* CollocatedOrbs.java -- Handles collocations + Copyright (C) 2006 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; + +import gnu.CORBA.Poa.gnuServantObject; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; + +/** + * This class provides support for the direct method invocations without + * involving the network in the case when both ORBs run on the same java + * virtual machine. Special attention is only needed when call is made + * between two independent ORBs, instantiated via ORB.init. The call to the + * object, obtained via IOR reference from the ORB where it was locally + * connected is always local anyway. + * + * For security reasons it may be sensible to keep this class and all support + * package private. + * + * @author Audrius Meskauskas + */ +class CollocatedOrbs +{ + /** + * This field is used in automated Classpath specific testing to disable + * the direct calls. + */ + static boolean DIRECT_CALLS_ALLOWED = true; + + /** + * Containts the references of the all running GNU Classpath ORBs in the + * local virtual machine. GNU Classpath ORBs register themselves here when + * created and unregister when either ORB.destroy is called or in the + * finalizer. + */ + private static ArrayList orbs = new ArrayList(); + + /** + * The address of the local host. + */ + static String localHost; + + static + { + try + { + localHost = InetAddress.getLocalHost().getHostAddress(); + } + catch (UnknownHostException ex) + { + throw new InternalError("Local host is not accessible:" + ex); + } + } + + /** + * Register the new ORB + * + * @param orb the orb to register + */ + static void registerOrb(OrbFunctional orb) + { + if (DIRECT_CALLS_ALLOWED) + synchronized (orbs) + { + assert ! orbs.contains(orb); + orbs.add(orb); + } + } + + /** + * Unregister the ORB. The ORB will no longer be reacheable locally but may + * be reacheable via network as if it would be remote. + * + * @param orb the orb to unregister + */ + static void unregisterOrb(OrbFunctional orb) + { + if (DIRECT_CALLS_ALLOWED) + synchronized (orbs) + { + assert orbs.contains(orb); + orbs.remove(orb); + } + } + + /** + * Search the possibly local object. If the IOR is not local or none of the + * found ORBs of this virtual machine knows about it, null is returned. + * + * @param ior the IOR to search + * @return the found local CORBA object or null in not found. + */ + static org.omg.CORBA.Object searchLocalObject(IOR ior) + { + if (! DIRECT_CALLS_ALLOWED && ! ior.Internet.host.equals(localHost)) + return null; + + synchronized (orbs) + { + OrbFunctional orb; + org.omg.CORBA.Object object; + for (int i = 0; i < orbs.size(); i++) + { + orb = (OrbFunctional) orbs.get(i); + object = orb.find_connected_object(ior.key, ior.Internet.port); + if (object != null) + { + if (object instanceof SafeForDirectCalls) + { + return object; + } + else if (object instanceof gnuServantObject) + { + return object; + } + } + } + } + return null; + } + +} diff --git a/libjava/classpath/gnu/CORBA/Connected_objects.java b/libjava/classpath/gnu/CORBA/Connected_objects.java new file mode 100644 index 000000000..62976c71f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Connected_objects.java @@ -0,0 +1,255 @@ +/* Connected_objects.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * The repository of objects, that have been connected to the + * {@link FunctionalORB} by the method + * {@link ORB.connect(org.omg.CORBA.Object)}. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class Connected_objects +{ + /** + * The reference data about the connected object. + */ + public class cObject + { + /** + * Create an initialised instance. + */ + cObject(org.omg.CORBA.Object _object, int _port, byte[] _key, + java.lang.Object an_identity + ) + { + object = _object; + port = _port; + key = _key; + identity = an_identity; + } + + /** + * The object. + */ + public final org.omg.CORBA.Object object; + + /** + * The port on that the object is connected. + */ + public final int port; + + /** + * The object key. + */ + public final byte[] key; + + /** + * The shared serving identity (usually POA) or null if no such + * applicable. + */ + public final java.lang.Object identity; + } + + /** + * The free number to give for the next instance. + * This field is incremented each time the + * new collection of the connected objects is created. + * Each collection has its own unique instance number. + */ + private static long free_object_number; + + /** + * The map of the all connected objects, maps the object key to the + * object. + */ + private Map objects = new TreeMap(new ByteArrayComparator()); + + /** + * Get the record of the stored object. + * + * @param stored_object the stored object + * + * @return the record about the stored object, null if + * this object is not stored here. + */ + public cObject getKey(org.omg.CORBA.Object stored_object) + { + synchronized (objects) + { + 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; + } + + /** + * Add the new object to the repository. The object key is + * generated automatically. + * + * @param object the object to add. + * @param port on that the ORB will be listening to the remote + * invocations. + * + * @return the newly created object record. + */ + public cObject add(org.omg.CORBA.Object object, int port) + { + return add(generateObjectKey(object), object, port, null); + } + + /** + * Add the new object to the repository. + * + * @param key the object key. + * @param object the object to add. + * @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, + java.lang.Object identity + ) + { + cObject rec = new cObject(object, port, key, identity); + synchronized (objects) + { + objects.put(key, rec); + } + return rec; + } + + /** + * Get the stored object. + * + * @param key the key (in the byte array form). + * + * @return the matching object, null if none is matching. + */ + public cObject get(byte[] key) + { + synchronized (objects) + { + return (cObject) objects.get(key); + } + } + + /** + * Get the map entry set. + */ + public Set entrySet() + { + return objects.entrySet(); + } + + /** + * Remove the given object. + * + * @param object the object to remove. + */ + public void remove(org.omg.CORBA.Object object) + { + synchronized (objects) + { + cObject ref = getKey(object); + if (ref != null) + objects.remove(ref.key); + } + } + + /** + * Remove the given object, indiciating it by the key. + * + * @param object the object to remove. + */ + public void remove(byte[] key) + { + objects.remove(key); + } + + /** + * Generate the object key, unique in the currently + * running java virtual machine. + * + * The generated key includes the object class name + * and the absolute instance number. + * + * @return the generated key. + */ + protected byte[] generateObjectKey(org.omg.CORBA.Object object) + { + return (object.getClass().getName() + ":" + getFreeInstanceNumber()).getBytes(); + } + + /** + * Get next free instance number. + */ + private static synchronized long getFreeInstanceNumber() + { + long instance_number = free_object_number; + free_object_number++; + return instance_number; + } + + /** + * Get the number of the connected objects. + * + * @return the size of the internal map. + */ + public int size() + { + return objects.size(); + } +} diff --git a/libjava/classpath/gnu/CORBA/CorbaList.java b/libjava/classpath/gnu/CORBA/CorbaList.java new file mode 100644 index 000000000..25bea9230 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CorbaList.java @@ -0,0 +1,115 @@ +/* CorbaList.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.io.Serializable; + +import java.util.ArrayList; + +import org.omg.CORBA.Bounds; + +/** + * This class is used to store array lists. Differently from + * the java.util lists, + * it throws {@link org.omg.CORBA.Bounds} rather than + * {@link IndexOutOfBoundsException}. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class CorbaList + extends ArrayList + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Creates the list with the given initial size. + */ + public CorbaList(int initial_size) + { + super(initial_size); + } + + /** + * Creates the list with the default size. + */ + public CorbaList() + { + } + + /** + * Remove the item at the given index. + * @param at the index + * @throws org.omg.CORBA.Bounds if the index is out of bounds. + */ + public void drop(int at) + throws Bounds + { + try + { + super.remove(at); + } + catch (IndexOutOfBoundsException ex) + { + throw new Bounds("[" + at + "], valid [0.." + size() + "]"); + } + } + + /** + * Get the item at the given index. + * @param at the index + * @return the item at the index + * @throws org.omg.CORBA.Bounds if the index is out of bounds. + */ + public Object item(int at) + throws Bounds + { + try + { + return super.get(at); + } + catch (IndexOutOfBoundsException ex) + { + throw new Bounds("[" + at + "], valid [0.." + size() + "]"); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/DefaultSocketFactory.java b/libjava/classpath/gnu/CORBA/DefaultSocketFactory.java new file mode 100644 index 000000000..e540fd0a4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DefaultSocketFactory.java @@ -0,0 +1,79 @@ +/* DefaultSocketFactory.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.interfaces.SocketFactory; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * The default socket factory that forges "plain" server and client sockets. The + * class can be replaced by setting the gnu.CORBA.SocketFactory property. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class DefaultSocketFactory + implements SocketFactory +{ + /** + * It is enough to have one instance of this class for all ORBs. + */ + public static final DefaultSocketFactory Singleton = new DefaultSocketFactory(); + + /** + * Create a client socket. + */ + public Socket createClientSocket(String host, int port) + throws IOException + { + return new Socket(host, port); + } + + /** + * Create a server socket. + */ + public ServerSocket createServerSocket(int port) + throws IOException + { + return new ServerSocket(port); + } + +} diff --git a/libjava/classpath/gnu/CORBA/DefinitionKindHolder.java b/libjava/classpath/gnu/CORBA/DefinitionKindHolder.java new file mode 100644 index 000000000..1ef7350dd --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DefinitionKindHolder.java @@ -0,0 +1,91 @@ +/* DefinitionKindHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.DefinitionKind; +import org.omg.CORBA.DefinitionKindHelper; + + +/** + * The definition kind holder. This class is not included in the original + * API specification, so we place it outside the org.omg namespace. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class DefinitionKindHolder + implements org.omg.CORBA.portable.Streamable +{ + /** + * The stored value. + */ + public DefinitionKind value; + + /** + * Create the initialised instance. + * @param initialValue + */ + public DefinitionKindHolder(DefinitionKind initialValue) + { + value = initialValue; + } + + /** + * Read from the CDR stream. + */ + public void _read(org.omg.CORBA.portable.InputStream in) + { + value = DefinitionKindHelper.read(in); + } + + /** + * Get the typecode. + */ + public org.omg.CORBA.TypeCode _type() + { + return DefinitionKindHelper.type(); + } + + /** + * Write into the CDR stream. + */ + public void _write(org.omg.CORBA.portable.OutputStream out) + { + DefinitionKindHelper.write(out, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/DuplicateNameHolder.java b/libjava/classpath/gnu/CORBA/DuplicateNameHolder.java new file mode 100644 index 000000000..d98f0ed40 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DuplicateNameHolder.java @@ -0,0 +1,106 @@ +/* DuplicateNameHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName; +import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateNameHelper; + +/** +* A holder for the exception {@link DuplicateName}. + +* @author Audrius Meskauskas, Lithiania (AudriusA@Bioinformatics.org) +*/ +public class DuplicateNameHolder + implements Streamable +{ + /** + * The stored DuplicateName value. + */ + public DuplicateName value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public DuplicateNameHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public DuplicateNameHolder(DuplicateName initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = DuplicateNameHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + DuplicateNameHelper.write(output, value); + } + + /** + * Get the typecode of the DuplicateName. + */ + public TypeCode _type() + { + return DuplicateNameHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/AbstractAny.java b/libjava/classpath/gnu/CORBA/DynAn/AbstractAny.java new file mode 100644 index 000000000..0f3b897df --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/AbstractAny.java @@ -0,0 +1,177 @@ +/* AbstractAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.TypeKindNamer; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +import java.io.Serializable; + +/** + * The top of our DynAny implementation, this class provides ORB that is + * required to create anys and factory that is required to initialise DynAnys. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class AbstractAny + extends LocalObject + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The "initial final_type" that can be an alias of the known final_type. + */ + public TypeCode official_type; + + /** + * The "basic" final_type to that the final_type finally evaluates. + */ + public final TypeCode final_type; + + /** + * The DynAny factory, required in initializations. + */ + public final gnuDynAnyFactory factory; + + /** + * The ORB, to that this DynAny belongs. + */ + public final ORB orb; + + /** + * The minor code, indicating the error, related to work with non - GNU + * Classpath DynAny. + */ + short MINOR = 8148; + + /** + * The message about the empty structure or exception. + */ + static final String EMPTY = "Empty structure with no fields."; + + /** + * The message about the structure or exception size mismatch. + */ + static final String SIZE = "Size mismatch."; + + /** + * The message about the content of this DynAny being equal to + * <code>null</code> + */ + static final String ISNULL = "The content is null"; + + /** + * The change value listener. + */ + ValueChangeListener listener; + + /** + * Create the abstract dyn any. + */ + public AbstractAny(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + official_type = oType; + final_type = aType; + factory = aFactory; + orb = anOrb; + } + + /** + * Get the typecode. + */ + public TypeCode type() + { + return official_type; + } + + /** + * Create the Any. + */ + public Any createAny() + { + return orb.create_any(); + } + + /** + * The "value changed" listener. + */ + protected void valueChanged() + { + if (listener != null) + listener.changed(); + } + + /** + * Check the type. + */ + void checkType(TypeCode expected, TypeCode actual) + throws TypeMismatch + { + if (!expected.equal(actual)) + throw new TypeMismatch(typeMismatch(expected, actual)); + } + + /** + * Format "Type mismatch" string. + */ + String typeMismatch(TypeCode expected, TypeCode actual) + { + return TypeKindNamer.nameIt(expected) + " expected " + + TypeKindNamer.nameIt(actual); + } + + /** + * Format "size mismatch" string. + */ + String sizeMismatch(int here, int other) + { + return "Size mismatch, " + other + " (expected " + here + ")"; + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/DivideableAny.java b/libjava/classpath/gnu/CORBA/DynAn/DivideableAny.java new file mode 100644 index 000000000..ae73cfe6f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/DivideableAny.java @@ -0,0 +1,512 @@ +/* DivideableAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import org.omg.CORBA.Any; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UNKNOWN; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynValueCommon; + +import java.io.Serializable; + +/** + * Provides a base for DynAnys, having multiple components. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class DivideableAny + extends AbstractAny + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The array of the components that in general case may have different + * final_type. + */ + protected DynAny[] array; + + /** + * The internal pointer. + */ + protected int pos = 0; + + public DivideableAny(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + } + + /** + * Advance forward. + */ + public boolean next() + { + pos++; + return array.length > pos; + } + + /** + * Set zero position. + */ + public void rewind() + { + pos = 0; + } + + /** + * Set a position. + */ + public boolean seek(int p) + { + pos = p; + return pos >= 0 && array.length > pos; + } + + /** + * Get the insertion point as DynAny. This method may throw exceptions if the + * current insertion point does not support reading or insertion of the + * primitive types. + * + * @return the focused component, from where the primitve value can be read or + * where it can be inserted. + * @throws InvalidValue if the primitive value cannot be inserted at the given + * point. + */ + protected DynAny focused() + throws InvalidValue, TypeMismatch + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ].component_count() == 0) + return array [ pos ]; + else + throw new TypeMismatch("Multiple coponents at " + pos); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + } + + /** {@inheritDoc} */ + public int component_count() + { + return array.length; + } + + /** + * Return the second (enclosed any) that is stored in the wrapped Any. + */ + public Any get_any() + throws TypeMismatch, InvalidValue + { + return focused().get_any(); + } + + /** {@inheritDoc} */ + public boolean get_boolean() + throws TypeMismatch, InvalidValue + { + return focused().get_boolean(); + } + + /** {@inheritDoc} */ + public char get_char() + throws TypeMismatch, InvalidValue + { + return focused().get_char(); + } + + /** {@inheritDoc} */ + public double get_double() + throws TypeMismatch, InvalidValue + { + return focused().get_double(); + } + + /** {@inheritDoc} */ + public float get_float() + throws TypeMismatch, InvalidValue + { + return focused().get_float(); + } + + /** {@inheritDoc} */ + public int get_long() + throws TypeMismatch, InvalidValue + { + return focused().get_long(); + } + + /** {@inheritDoc} */ + public long get_longlong() + throws TypeMismatch, InvalidValue + { + return focused().get_longlong(); + } + + /** {@inheritDoc} */ + public byte get_octet() + throws TypeMismatch, InvalidValue + { + return focused().get_octet(); + } + + /** {@inheritDoc} */ + public Object get_reference() + throws TypeMismatch, InvalidValue + { + return focused().get_reference(); + } + + /** {@inheritDoc} */ + public short get_short() + throws TypeMismatch, InvalidValue + { + return focused().get_short(); + } + + /** {@inheritDoc} */ + public String get_string() + throws TypeMismatch, InvalidValue + { + return focused().get_string(); + } + + /** {@inheritDoc} */ + public TypeCode get_typecode() + throws TypeMismatch, InvalidValue + { + return focused().get_typecode(); + } + + /** {@inheritDoc} */ + public int get_ulong() + throws TypeMismatch, InvalidValue + { + return focused().get_ulong(); + } + + /** {@inheritDoc} */ + public long get_ulonglong() + throws TypeMismatch, InvalidValue + { + return focused().get_ulonglong(); + } + + /** {@inheritDoc} */ + public short get_ushort() + throws TypeMismatch, InvalidValue + { + return focused().get_ushort(); + } + + /** {@inheritDoc} */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ] instanceof DynValueCommon) + return array [ pos ].get_val(); + else + throw new TypeMismatch(); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + } + + /** {@inheritDoc} */ + public char get_wchar() + throws TypeMismatch, InvalidValue + { + return focused().get_wchar(); + } + + /** {@inheritDoc} */ + public String get_wstring() + throws TypeMismatch, InvalidValue + { + return focused().get_wstring(); + } + + /** {@inheritDoc} */ + public void insert_any(Any a_x) + throws TypeMismatch, InvalidValue + { + focused().insert_any(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_boolean(boolean a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_boolean(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_char(char a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_char(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_double(double a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_double(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_float(float a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_float(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_long(int a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_long(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_longlong(long a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_longlong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_octet(byte a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_octet(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_reference(Object a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_reference(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_short(short a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_short(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_string(String a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_string(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_typecode(TypeCode a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_typecode(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ulong(int a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ulong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ulonglong(long a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ulonglong(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_ushort(short a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_ushort(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + if (pos >= 0 && pos < array.length) + { + if (array [ pos ] instanceof DynValueCommon) + array [ pos ].insert_val(a_x); + else + throw new TypeMismatch(); + } + else + throw new InvalidValue("Out of bounds at " + pos + " valid 0.." + + (array.length - 1) + ); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_wchar(char a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_wchar(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public void insert_wstring(String a_x) + throws InvalidValue, TypeMismatch + { + focused().insert_wstring(a_x); + valueChanged(); + } + + /** {@inheritDoc} */ + public DynAny get_dyn_any() + throws TypeMismatch, InvalidValue + { + return focused().get_dyn_any(); + } + + /** {@inheritDoc} */ + public void insert_dyn_any(DynAny insert_it) + throws TypeMismatch, InvalidValue + { + focused().insert_dyn_any(insert_it); + } + + /** + * Get current component. + * + * @return current component or <code>null</code> if the pointer is out of + * bounds. + */ + public DynAny current_component() + throws TypeMismatch + { + if (array.length == 0) + throw new TypeMismatch("empty"); + return (pos >= 0 && pos < array.length) ? array [ pos ] : null; + } + + /** + * No action, cleanup is done by garbage collector in java. + */ + public void destroy() + { + } + + /** + * Involved in equal(DynAny). + */ + public abstract Any to_any() + throws TypeMismatch; + + /** + * Compares with other DynAny for equality. The final_type, array size and + * array members must match. + */ + public boolean equal(DynAny other) + { + try + { + if (!official_type.equal(other.type())) + return false; + else if (other instanceof DivideableAny) + { + DivideableAny x = (DivideableAny) other; + if (x.array.length != array.length) + return false; + + for (int i = 0; i < array.length; i++) + { + if (!array [ i ].equal(x.array [ i ])) + return false; + } + return true; + } + else if (other == null || other instanceof AbstractAny) + return false; + else + return other.to_any().equal(to_any()); + } + catch (TypeMismatch e) + { + UNKNOWN u = new UNKNOWN(MINOR, CompletionStatus.COMPLETED_NO); + u.initCause(e); + throw u; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java new file mode 100644 index 000000000..c3214e6ad --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/NameValuePairHolder.java @@ -0,0 +1,94 @@ +/* NameValuePairHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import org.omg.CORBA.NameValuePair; +import org.omg.CORBA.NameValuePairHelper; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +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}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValuePairHolder + implements Streamable +{ + /** + * The stored value of the name value pair. + */ + public NameValuePair value; + + public NameValuePairHolder() + { + } + + public NameValuePairHolder(NameValuePair a_value) + { + value = a_value; + } + + /** + * Read the name value pair. + */ + public void _read(InputStream input) + { + value = NameValuePairHelper.read(input); + } + + /** + * Return the typecode of the name value pair. + */ + public TypeCode _type() + { + return NameValuePairHelper.type(); + } + + /** + * Write the name value pair. + */ + public void _write(OutputStream output) + { + NameValuePairHelper.write(output, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/RecordAny.java b/libjava/classpath/gnu/CORBA/DynAn/RecordAny.java new file mode 100644 index 000000000..8badd2011 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/RecordAny.java @@ -0,0 +1,405 @@ +/* RecordAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.HolderLocator; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynValueCommonOperations; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; + +import java.io.Serializable; + +import java.lang.reflect.Field; + +/** + * A shared base for both dynamic structure an dynamic value final_type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class RecordAny + extends DivideableAny + implements DynAny, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + String[] fNames; + + /** + * Creates the structure with the given typecode. + * + * @param fields The DynAny's, representing the fields of the structure. + */ + public RecordAny(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + } + + /** @inheritDoc */ + public TCKind current_member_kind() + throws TypeMismatch, InvalidValue + { + if (array.length == 0) + throw new TypeMismatch(EMPTY); + try + { + return final_type.member_type(pos).kind(); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + catch (Bounds e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public String current_member_name() + throws TypeMismatch, InvalidValue + { + if (array.length == 0) + throw new TypeMismatch(EMPTY); + try + { + return final_type.member_name(pos); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + catch (Bounds e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** + * Get content of the structure. This method must be defined on a different + * name because get_members_as_dyn_any() throws exception only in some of the + * supported interfaces. + */ + public NameDynAnyPair[] gnu_get_members_as_dyn_any() + { + NameDynAnyPair[] r = new NameDynAnyPair[ array.length ]; + for (int i = 0; i < r.length; i++) + { + try + { + r [ i ] = new NameDynAnyPair(fNames [ i ], array [ i ]); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + return r; + } + + /** + * Get content of the structure. This method must be defined on a different + * name because get_members_as_dyn_any() throws exception only in some of the + * supported interfaces. + */ + public NameValuePair[] gnu_get_members() + { + NameValuePair[] r = new NameValuePair[ array.length ]; + for (int i = 0; i < r.length; i++) + { + try + { + r [ i ] = new NameValuePair(fNames [ i ], array [ i ].to_any()); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + return r; + } + + /** + * Set members from the provided array. + */ + public void set_members_as_dyn_any(NameDynAnyPair[] value) + throws TypeMismatch, InvalidValue + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + DynAny dynAny = value [ i ].value; + checkType(dynAny.type(), i); + checkName(value [ i ].id, i); + + array [ i ] = dynAny; + } + pos = 0; + } + + /** + * Check the name at the given position ("" matches everything). + */ + private void checkName(String xName, int i) + throws TypeMismatch + { + if (xName.length() > 0 && fNames [ i ].length() > 0) + if (!xName.equals(fNames [ i ])) + throw new TypeMismatch("Field name mismatch " + xName + " expected " + + fNames [ i ] + ); + } + + /** + * Check the type at the given position. + */ + private void checkType(TypeCode t, int i) + throws TypeMismatch + { + if (!array [ i ].type().equal(t)) + throw new TypeMismatch(typeMismatch(array [ i ].type(), t) + " field " + + i + ); + } + + /** + * Set members from the provided array. + */ + public void set_members(NameValuePair[] value) + throws TypeMismatch, InvalidValue + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + Any any = value [ i ].value; + checkType(any.type(), i); + checkName(value [ i ].id, i); + + array [ i ].from_any(any); + } + pos = 0; + } + + /** @inheritDoc */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynStruct) + { + try + { + set_members_as_dyn_any(((DynStruct) from).get_members_as_dyn_any()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + } + else + throw new TypeMismatch("Not a DynStruct"); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + RecordAny d = newInstance(official_type, final_type, factory, orb); + d.array = c; + return d; + } + + /** + * Create a new instance when copying. + */ + protected abstract RecordAny newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, + ORB anOrb + ); + + /** + * Done via reflection. + */ + public Any to_any() + { + try + { + Streamable sHolder = HolderLocator.createHolder(official_type); + + Class sHolderClass = sHolder.getClass(); + Field sHolderValue = sHolderClass.getField("value"); + Class sClass = sHolderValue.getType(); + + Object structure = sClass.newInstance(); + Object member; + Any am; + Field vread; + Field vwrite; + Streamable memberHolder; + + for (int i = 0; i < array.length; i++) + { + am = array [ i ].to_any(); + memberHolder = am.extract_Streamable(); + vwrite = structure.getClass().getField(final_type.member_name(i)); + vread = memberHolder.getClass().getField("value"); + member = vread.get(memberHolder); + vwrite.set(structure, member); + } + + Any g = createAny(); + sHolderValue.set(sHolder, structure); + g.insert_Streamable(sHolder); + g.type(official_type); + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** + * Done via reflection. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + Streamable s = an_any.extract_Streamable(); + if (s == null) + { + if (this instanceof DynValueCommonOperations) + { + ((DynValueCommonOperations) this).set_to_null(); + return; + } + else + throw new InvalidValue(ISNULL); + } + + Object structure = s.getClass().getField("value").get(s); + if (structure == null && (this instanceof DynValueCommonOperations)) + { + ((DynValueCommonOperations) this).set_to_null(); + return; + } + + Any member; + Streamable holder; + Object field; + TypeCode fType; + Field fField; + + for (int i = 0; i < array.length; i++) + { + fField = structure.getClass().getField(fNames [ i ]); + field = fField.get(structure); + fType = array [ i ].type(); + holder = HolderLocator.createHolder(fType); + + member = createAny(); + holder.getClass().getField("value").set(holder, field); + member.insert_Streamable(holder); + member.type(fType); + + array [ i ].from_any(member); + } + + if (this instanceof DynValueCommonOperations) + ((DynValueCommonOperations) this).set_to_value(); + } + catch (InvalidValue v) + { + throw v; + } + catch (NoSuchFieldException ex) + { + TypeMismatch v = + new TypeMismatch("holder value does not match typecode"); + v.initCause(ex); + throw v; + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/UndivideableAny.java b/libjava/classpath/gnu/CORBA/DynAn/UndivideableAny.java new file mode 100644 index 000000000..da4e9618e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/UndivideableAny.java @@ -0,0 +1,493 @@ +/* Undivideable.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import java.io.Serializable; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +/** + * Represent DynAny that has no internal components (DynEnum and so on). The + * methods, related to internal components, throw exceptions or return agreed + * values like null. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class UndivideableAny + extends AbstractAny + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create a new instance with the given typecode. + */ + public UndivideableAny(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + super(oType, aType, aFactory, anOrb); + } + + /** + * There are no components. + * + * @return 0, always. + */ + public int component_count() + { + return 0; + } + + /** + * There is no current component. + * + * @throws TypeMismatch, always. + */ + public DynAny current_component() + throws TypeMismatch + { + throw new TypeMismatch("Not applicable"); + } + + /** + * Returns without action. + */ + public void destroy() + { + } + + /** + * Not in use. + */ + public Any get_any() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public boolean get_boolean() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public char get_char() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public double get_double() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public DynAny get_dyn_any() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public float get_float() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public int get_long() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public long get_longlong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public byte get_octet() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public Object get_reference() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public short get_short() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public String get_string() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public TypeCode get_typecode() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public int get_ulong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public long get_ulonglong() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public short get_ushort() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public char get_wchar() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public String get_wstring() + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_any(Any an_any) + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_boolean(boolean a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_char(char a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_double(double a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_dyn_any(DynAny insert_it) + throws TypeMismatch, InvalidValue + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_float(float a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_long(int a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_longlong(long a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_octet(byte a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_reference(Object a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_short(short a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_string(String a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_typecode(TypeCode a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ulong(int a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ulonglong(long a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_ushort(short a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_wchar(char a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public void insert_wstring(String a_x) + throws InvalidValue, TypeMismatch + { + throw new TypeMismatch(); + } + + /** + * Not in use. + */ + public boolean next() + { + return false; + } + + /** + * Not in use. + */ + public void rewind() + { + } + + /** + * Not in use. + */ + public boolean seek(int p) + { + return false; + } + + /** + * Get the typecode of this enumeration. + */ + public TypeCode type() + { + return official_type; + } + + /** + * Compares with other DynAny for equality. + */ + public boolean equals(java.lang.Object other) + { + if (other instanceof DynAny) + return equal((DynAny) other); + else + return false; + } + + /** + * This depends on an object. + */ + public abstract boolean equal(DynAny other); + +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/ValueChangeListener.java b/libjava/classpath/gnu/CORBA/DynAn/ValueChangeListener.java new file mode 100644 index 000000000..4c3a456d2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/ValueChangeListener.java @@ -0,0 +1,50 @@ +/* ValueChangeListener.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +/** + * An interface, able to receive notification about the change of value + * of some DynAny. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface ValueChangeListener +{ + void changed(); +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java new file mode 100644 index 000000000..314426c82 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAny.java @@ -0,0 +1,945 @@ +/* gnuDynAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.OctetHolder; +import gnu.CORBA.Unexpected; +import gnu.CORBA.WCharHolder; +import gnu.CORBA.WStringHolder; +import gnu.CORBA.HolderLocator; +import gnu.CORBA.TypeKindNamer; +import gnu.CORBA.GeneralHolder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnyHolder; +import org.omg.CORBA.BooleanHolder; +import org.omg.CORBA.CharHolder; +import org.omg.CORBA.DoubleHolder; +import org.omg.CORBA.FloatHolder; +import org.omg.CORBA.IntHolder; +import org.omg.CORBA.LongHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.ObjectHolder; +import org.omg.CORBA.ShortHolder; +import org.omg.CORBA.StringHolder; +import org.omg.CORBA.TCKind; +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.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; + +import java.io.IOException; +import java.io.Serializable; + +import java.util.Arrays; + +/** + * The primitive dynamic Any holds the value basic final_type that cannot be + * traversed. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynAny extends AbstractAny implements DynAny, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The enclosed Streamable, holding the actual value. + */ + protected Streamable holder; + + /** + * Create DynAny providing the holder. + * + * @param a_holder + */ + public gnuDynAny(Streamable aHolder, TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + holder = aHolder; + } + + /** + * Assign the contents of the given {@link DynAny} to this DynAny. + * + * @param from the source to assign from. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof gnuDynAny) + holder = ((gnuDynAny) from).holder; + else + holder = from.to_any().extract_Streamable(); + valueChanged(); + } + + /** + * Create a copy of this {@link DynAny} via buffer read/write. + */ + public DynAny copy() + { + if (holder != null) + { + BufferedCdrOutput buffer = new BufferedCdrOutput(); + holder._write(buffer); + + gnuDynAny other; + try + { + other = + new gnuDynAny((Streamable) (holder.getClass().newInstance()), + official_type, final_type, factory, orb + ); + } + catch (Exception e) + { + // Holder must have parameterless constructor. + throw new Unexpected(e); + } + other.holder._read(buffer.create_input_stream()); + return other; + } + else + { + return new gnuDynAny(null, official_type, final_type, factory, orb); + } + } + + /** + * Always returns <code>null</code>. + * + * @return <code>null</code>, always. + */ + public DynAny current_component() throws TypeMismatch + { + throw new TypeMismatch("Not applicable for " + + TypeKindNamer.nameIt(final_type) + ); + } + + /** + * Returns without action, leaving all work to the garbage collector. + */ + public void destroy() + { + } + + /** + * Takes the passed parameter as the enclosed {@link Any} reference. + * + * @param an_any the {@link Any} that will be used as an enclosed reference. + * + * @throws TypeMismatch if the final_type of the passed Any is not the same as + * the final_type, currently stored in this Any. + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + + Streamable a_holder = an_any.extract_Streamable(); + if (a_holder == null) + { + throw new InvalidValue(ISNULL); + } + else if (a_holder instanceof GeneralHolder) + { + holder = HolderLocator.createHolder(official_type); + if (holder == null) + holder = HolderLocator.createHolder(final_type); + + if (holder == null) + holder = ((GeneralHolder) a_holder).Clone(); + else + { + InputStream in = an_any.create_input_stream(); + holder._read(in); + try + { + in.close(); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + } + else + { + try + { + InputStream in = an_any.create_input_stream(); + holder = (Streamable) a_holder.getClass().newInstance(); + holder._read(in); + in.close(); + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + } + valueChanged(); + } + + /** + * Return the second (enclosed any) that is stored in the wrapped Any. + */ + public Any get_any() throws TypeMismatch + { + try + { + return ((AnyHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public boolean get_boolean() throws TypeMismatch + { + try + { + return ((BooleanHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public char get_char() throws TypeMismatch + { + try + { + return ((CharHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public double get_double() throws TypeMismatch + { + try + { + return ((DoubleHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public float get_float() throws TypeMismatch + { + try + { + return ((FloatHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public int get_long() throws TypeMismatch + { + try + { + return ((IntHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public long get_longlong() throws TypeMismatch + { + try + { + return ((LongHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public byte get_octet() throws TypeMismatch + { + try + { + return ((OctetHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public Object get_reference() throws TypeMismatch + { + try + { + return ((ObjectHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public short get_short() throws TypeMismatch + { + try + { + return ((ShortHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public String get_string() throws TypeMismatch + { + try + { + return ((StringHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public TypeCode get_typecode() throws TypeMismatch + { + try + { + return ((TypeCodeHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public int get_ulong() throws TypeMismatch + { + check(TCKind.tk_ulong); + return get_long(); + } + + /** {@inheritDoc} */ + public long get_ulonglong() throws TypeMismatch + { + check(TCKind.tk_ulonglong); + return get_longlong(); + } + + /** {@inheritDoc} */ + public short get_ushort() throws TypeMismatch + { + check(TCKind.tk_ushort); + return get_short(); + } + + /** {@inheritDoc} */ + public Serializable get_val() throws TypeMismatch + { + try + { + return ((ValueBaseHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public char get_wchar() throws TypeMismatch + { + try + { + return ((WCharHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public String get_wstring() throws TypeMismatch + { + try + { + return ((WStringHolder) holder).value; + } + catch (ClassCastException cex) + { + TypeMismatch m = new TypeMismatch(); + m.initCause(cex); + throw m; + } + } + + /** {@inheritDoc} */ + public void insert_any(Any a_x) throws TypeMismatch, InvalidValue + { + try + { + if (a_x.type().kind().value() == TCKind._tk_null) + ((AnyHolder) holder).value = a_x; + else + { + OutputStream buf = a_x.create_output_stream(); + buf.write_any(a_x); + holder._read(buf.create_input_stream()); + buf.close(); + } + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (MARSHAL m) + { + InvalidValue v = new InvalidValue(); + v.initCause(m); + throw v; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** {@inheritDoc} */ + public void insert_boolean(boolean a_x) throws InvalidValue, TypeMismatch + { + try + { + ((BooleanHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_char(char a_x) throws InvalidValue, TypeMismatch + { + try + { + ((CharHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_double(double a_x) throws InvalidValue, TypeMismatch + { + try + { + ((DoubleHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_float(float a_x) throws InvalidValue, TypeMismatch + { + try + { + ((FloatHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_long(int a_x) throws InvalidValue, TypeMismatch + { + try + { + ((IntHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_longlong(long a_x) throws InvalidValue, TypeMismatch + { + try + { + ((LongHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_octet(byte a_x) throws InvalidValue, TypeMismatch + { + try + { + ((OctetHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_reference(Object a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ObjectHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_short(short a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ShortHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_string(String a_x) throws InvalidValue, TypeMismatch + { + try + { + if (a_x != null && + final_type.length() > 0 && + a_x.length() > final_type.length() + ) + throw new InvalidValue(a_x.length() + " exceeds bound, " + + final_type.length() + ); + ((StringHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_typecode(TypeCode a_x) throws InvalidValue, TypeMismatch + { + try + { + ((TypeCodeHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ulong(int a_x) throws InvalidValue, TypeMismatch + { + try + { + ((IntHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ulonglong(long a_x) throws InvalidValue, TypeMismatch + { + try + { + ((LongHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_ushort(short a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ShortHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) throws InvalidValue, TypeMismatch + { + try + { + ((ValueBaseHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_wchar(char a_x) throws InvalidValue, TypeMismatch + { + try + { + ((WCharHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + } + + /** {@inheritDoc} */ + public void insert_wstring(String a_x) throws InvalidValue, TypeMismatch + { + try + { + if (a_x != null && + final_type.length() > 0 && + a_x.length() > type().length() + ) + throw new InvalidValue(a_x.length() + " exceeds bound, " + + final_type.length() + ); + ((WStringHolder) holder).value = a_x; + valueChanged(); + } + catch (ClassCastException cex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(cex); + throw t; + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * The objects, enclosed inside this class, have only one component (self). + * + * @return false, always (no other action). + */ + public boolean next() + { + return false; + } + + /** + * Returns without action. + */ + public void rewind() + { + } + + /** + * This objects, stored in this wrapper, never have multiple internal + * components to seek. + * + * @return false, always (no other action). + */ + public boolean seek(int p) + { + return false; + } + + /** + * Returns the enclosed {@link Any}. + * + * @return the enclosed {@link Any}. + */ + public Any to_any() + { + Any a = createAny(); + a.insert_Streamable(holder); + a.type(official_type); + return a; + } + + /** {@inheritDoc} */ + public TypeCode type() + { + return official_type; + } + + /** + * Compute hashcode in a trivial way. + */ + protected int getHashCodeSimple(int maximum) + { + int h = super.hashCode() / 2; + if (h < 0) + h = -h; + return h % maximum; + } + + /** + * Inserts Any, contained in the parameter, into Any, contained in this + * DynAny. + */ + public void insert_dyn_any(DynAny d) throws TypeMismatch, InvalidValue + { + check(d.type().kind()); + + Any a = d.to_any(); + holder = a.extract_Streamable(); + valueChanged(); + } + + /** + * Checks for equality. The DynAnys are equal if the stored Anys are equal. + */ + public boolean equal(DynAny other) + { + if (other instanceof AbstractAny) + { + if (other instanceof gnuDynAny) + { + gnuDynAny x = (gnuDynAny) other; + + if (!x.holder.getClass().equals(holder.getClass())) + return false; + + BufferedCdrOutput b1 = new BufferedCdrOutput(); + x.holder._write(b1); + + BufferedCdrOutput b2 = new BufferedCdrOutput(b1.buffer.size() + 10); + holder._write(b2); + + return Arrays.equals(b1.buffer.toByteArray(), + b2.buffer.toByteArray() + ); + } + else + return false; + } + if (other == null) + return false; + else if (other.component_count() != component_count() || + !official_type.equal(other.type()) + ) + return false; + else + return other.to_any().equal(to_any()); + } + + /** + * This final_type has no components. + * + * @return 0, always. + */ + public int component_count() + { + return 0; + } + + public DynAny get_dyn_any() throws TypeMismatch, InvalidValue + { + return new gnuDynAny(holder, official_type, final_type, factory, orb); + } + + private void check(TCKind t) throws TypeMismatch + { + if (t.value() != final_type.kind().value()) + throw new TypeMismatch(t.value() + "!=" + final_type.kind().value()); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java new file mode 100644 index 000000000..b42e63213 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynAnyFactory.java @@ -0,0 +1,356 @@ +/* gnuDynAnyFactory.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Poa.ORB_1_4; +import gnu.CORBA.Unexpected; +import gnu.CORBA.HolderLocator; +import gnu.CORBA.TypeKindNamer; + +import org.omg.CORBA.Any; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactory; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynArray; +import org.omg.DynamicAny.DynEnum; +import org.omg.DynamicAny.DynFixed; +import org.omg.DynamicAny.DynSequence; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynUnion; +import org.omg.DynamicAny.DynValue; +import org.omg.DynamicAny.DynValueBox; + +/** + * This class is returned by ORB when resolving + * initial reference "DynAnyFactory". + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynAnyFactory + extends LocalObject + implements DynAnyFactory +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, to that the factory belongs. + */ + final ORB_1_4 orb; + + /** + * Create a new factory, specifying the ORB to that the factory belongs. + * + * @param anOrb + */ + public gnuDynAnyFactory(ORB_1_4 anOrb) + { + orb = anOrb; + } + + /** + * Get the orb. + */ + public ORB_1_4 getOrb() + { + return orb; + } + + /** + * Create an initialised array. + */ + public DynArray create_array(TypeCode official, TypeCode type) + { + return new gnuDynArray(official, type, this, orb, true); + } + + /** + * Create an empty sequence. + */ + public DynSequence create_sequence(TypeCode official, TypeCode type) + { + return new gnuDynSequence(official, type, this, orb); + } + + /** + * Create structure. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynStruct create_structure(TypeCode official, TypeCode type) + { + return new gnuDynStruct(official, type, this, orb); + } + + /** + * Create union. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynUnion create_union(TypeCode official, TypeCode type) + { + try + { + return new gnuDynUnion(official, type, this, orb); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + + /** + * Create value. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynValue create_value(TypeCode official, TypeCode type) + { + return new gnuDynValue(official, type, this, orb); + } + + /** + * Create value box. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynValueBox create_value_box(TypeCode official, TypeCode type) + { + return new gnuDynValueBox(official, type, this, orb); + } + + /** + * Create enumeration. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynEnum create_enumeration(TypeCode official, TypeCode type) + { + return new gnuDynEnum(official, type, this, orb); + } + + /** + * Create fixed. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynFixed create_fixed(TypeCode official, TypeCode type) + { + return new gnuDynFixed(official, type, this, orb); + } + + /** + * Create alias. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynAny create_alias(TypeCode official, TypeCode type) + throws InconsistentTypeCode + { + try + { + return create_dyn_any_from_type_code(official, type.content_type()); + } + catch (BadKind e) + { + throw new Unexpected(e); + } + } + + /** + * Create the undivideable DynAny. + */ + public DynAny create_simple(TypeCode official, TypeCode type) + { + Streamable holder = HolderLocator.createHolder(type); + return new gnuDynAny(holder, official, type, this, orb); + } + + /** + * Create the DynAny from typecode. + */ + public DynAny create_dyn_any_from_type_code(TypeCode type) + throws InconsistentTypeCode + { + return create_dyn_any_from_type_code(type, type); + } + + /** + * Create the DynAny from typecode. + * + * @param official the type that was originally passed as a parameter by user. + * May be alias of some other type. + * @param type the type into that the "official type" evaluates during alias + * resolving. Initially equal to "official type". + */ + public DynAny create_dyn_any_from_type_code(TypeCode official, TypeCode type) + throws InconsistentTypeCode + { + DynAny d; + try + { + switch (type.kind().value()) + { + case TCKind._tk_array : + return create_array(official, type); + + case TCKind._tk_sequence : + return create_sequence(official, type); + + case TCKind._tk_struct : + case TCKind._tk_except : + return create_structure(official, type); + + case TCKind._tk_union : + return create_union(official, type); + + case TCKind._tk_value : + return create_value(official, type); + + case TCKind._tk_value_box : + return create_value_box(official, type); + + case TCKind._tk_enum : + return create_enumeration(official, type); + + case TCKind._tk_fixed : + return create_fixed(official, type); + + case TCKind._tk_alias : + return create_alias(official, type); + + case TCKind._tk_null : + return new gnuDynAny(null, official, type, this, orb); + + case TCKind._tk_TypeCode : + d = create_simple(official, type); + d.insert_typecode(orb.get_primitive_tc(TCKind.tk_null)); + return d; + + case TCKind._tk_any : + d = create_simple(official, type); + + Any empty_any = orb.create_any(); + empty_any.type(orb.get_primitive_tc(TCKind.tk_null)); + d.insert_any(empty_any); + return d; + + case TCKind._tk_wstring : + d = create_simple(official, type); + d.insert_wstring(""); + return d; + + case TCKind._tk_string : + d = create_simple(official, type); + d.insert_string(""); + return d; + + case TCKind._tk_native : + case TCKind._tk_Principal : + case TCKind._tk_abstract_interface : + throw new InconsistentTypeCode("Following API, the " + + TypeKindNamer.nameIt(type) + + " must not be supported." + ); + + default : + return create_simple(official, type); + } + } + catch (UserException uex) + { + InconsistentTypeCode it = new InconsistentTypeCode(); + it.initCause(uex); + throw it; + } + } + + /** + * Create the DynAny using the passed value as template and assign this value. + */ + public DynAny create_dyn_any(Any value) + throws InconsistentTypeCode + { + DynAny created = create_dyn_any_from_type_code(value.type()); + try + { + created.from_any(value); + } + catch (UserException uex) + { + InconsistentTypeCode t = new InconsistentTypeCode("Inconsistent Any"); + t.initCause(uex); + throw t; + } + catch (Exception e) + { + throw new Unexpected(e); + } + return created; + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java new file mode 100644 index 000000000..5676c3d39 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynArray.java @@ -0,0 +1,337 @@ +/* gnuDynArray.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.HolderLocator; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynArray; + +import java.io.Serializable; + +import java.lang.reflect.Array; +import java.lang.reflect.Field; + +/** + * Provides support for dynamic array or sequence, where all members have the + * same final_type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynArray + extends DivideableAny + implements DynArray, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The component "official" type (may be alias). + */ + final TypeCode official_components; + + /** + * The component "final" type, after resolving any aliases. + */ + final TypeCode final_components; + + /** + * Creates new array. + * + * @param aType the final_type of array. + * @param aFactory the factory, used to initialise default values. + * @param orb the ORB to that this DynAny belongs. + * @param initialise_array if false, the array is not initialised in + * constructor. + * + * + * @throws BAD_PARAM if the passed typecode does not provide the length(). + */ + public gnuDynArray(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb, boolean initialise_array + ) + throws BAD_PARAM + { + super(oType, aType, aFactory, anOrb); + + try + { + official_components = final_type.content_type(); + + TypeCode component = official_components; + while (component.kind().value() == TCKind._tk_alias) + component = component.content_type(); + final_components = component; + + if (initialise_array) + { + array = new DynAny[ aType.length() ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(official_components); + } + } + } + catch (Exception e) + { + BAD_PARAM bad = new BAD_PARAM("Unable to initialise array"); + bad.initCause(e); + throw bad; + } + } + + /** + * Copy one DynAny into another. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynArray && from.component_count() == array.length) + { + DynArray dyn = (DynArray) from; + array = dyn.get_elements_as_dyn_any(); + } + else + throw new TypeMismatch(); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + gnuDynArray d = + new gnuDynArray(official_type, final_type, factory, orb, false); + d.array = c; + return d; + } + + /** + * Get elements as array of anys. + */ + public Any[] get_elements() + { + Any[] r = new Any[ array.length ]; + for (int i = 0; i < r.length; i++) + r [ i ] = array [ i ].to_any(); + return r; + } + + /** {@inheritDoc} */ + public DynAny[] get_elements_as_dyn_any() + { + DynAny[] a = new DynAny[ array.length ]; + for (int i = 0; i < a.length; i++) + { + a [ i ] = array [ i ].copy(); + } + return a; + } + + /** + * Set elements when array of dyn anys is provided. This method can set nested + * data structures as an array components. + */ + public void set_elements_as_dyn_any(DynAny[] value) + throws InvalidValue, TypeMismatch + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + array [ i ].assign(value [ i ]); + } + pos = 0; + valueChanged(); + } + + /** + * Set elements when array of ordinary anys is provided. + */ + public void set_elements(Any[] value) + throws InvalidValue, TypeMismatch + { + if (value.length != array.length) + throw new InvalidValue(sizeMismatch(array.length, value.length)); + + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + try + { + array [ i ] = factory.create_dyn_any(value [ i ]); + } + catch (InconsistentTypeCode e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + pos = 0; + valueChanged(); + } + + /** + * Done via reflection. + */ + public Any to_any() + { + try + { + Streamable memberHolder = + HolderLocator.createHolder(official_components); + + if (memberHolder == null) + memberHolder = HolderLocator.createHolder(final_components); + + Class memberHolderClass = memberHolder.getClass(); + Class memberClass = memberHolderClass.getField("value").getType(); + + Object members = Array.newInstance(memberClass, array.length); + Object member; + Any am; + Field value = memberHolder.getClass().getField("value"); + + for (int i = 0; i < array.length; i++) + { + // Recursive call should support multidimensional arrays. + am = array [ i ].to_any(); + memberHolder = am.extract_Streamable(); + member = value.get(memberHolder); + Array.set(members, i, member); + } + + Streamable arrayHolder = HolderLocator.createHolder(official_type); + arrayHolder.getClass().getField("value").set(arrayHolder, members); + + Any g = createAny(); + g.insert_Streamable(arrayHolder); + g.type(official_type); + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** + * Done via reflection. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + Streamable s = an_any.extract_Streamable(); + Object members = s.getClass().getField("value").get(s); + + checkArrayValid(members); + + Any member; + Streamable holder; + Class holderClass = null; + + for (int i = 0; i < array.length; i++) + { + if (holderClass == null) + { + holder = HolderLocator.createHolder(official_components); + if (holder == null) + holder = HolderLocator.createHolder(final_components); + holderClass = holder.getClass(); + } + else + holder = (Streamable) holderClass.newInstance(); + + member = createAny(); + holder.getClass().getField("value").set(holder, + Array.get(members, i) + ); + member.insert_Streamable(holder); + member.type(official_components); + + // This may lead to recursion, supporting multidimensional + // arrays. + array [ i ].from_any(member); + } + } + catch (Exception ex) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(ex); + throw t; + } + valueChanged(); + } + + /** + * Check if array size is valid and (for sequences) resized + * if required. Called from from_any. + */ + protected void checkArrayValid(Object members) + throws TypeMismatch, InvalidValue + { + if (array.length != Array.getLength(members)) + throw new InvalidValue(sizeMismatch(array.length, Array.getLength(members))); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java new file mode 100644 index 000000000..76b0a9527 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynEnum.java @@ -0,0 +1,244 @@ +/* gnuDynEnum.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynEnum; + +import java.io.IOException; + +import java.util.Arrays; + +/** + * Our implementation of dynamic enumeration. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynEnum extends UndivideableAny implements DynEnum +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The valid string values of the enumeration. Most of enumerations are short, + * counting 2-5 memebers. With so small number of memebers, it seems not + * reasonable to use hashtables. + */ + final String[] values; + + /** + * The current value of enum. + */ + int current; + + /** + * Create a new dyn enum from the given typecode. + */ + public gnuDynEnum(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + values = new String[ final_type.member_count() ]; + + for (int i = 0; i < values.length; i++) + { + values [ i ] = final_type.member_name(i); + } + } + catch (Exception e) + { + throw new BAD_PARAM("Not enum"); + } + } + + /** + * Create a clone of the given enum, sharing values and final_type. + */ + public gnuDynEnum(gnuDynEnum from) + { + super(from.official_type, from.final_type, from.factory, from.orb); + values = from.values; + } + + /** + * Assign the Enum from the passed value. The passed DynAny must hold the + * enumeration of exactly the same final_type. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + if (!(from instanceof DynEnum)) + throw new TypeMismatch("Not a DynEnum"); + try + { + set_as_ulong(((DynEnum) from).get_as_ulong()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * Copy this DynEnum. + */ + public DynAny copy() + { + gnuDynEnum other = new gnuDynEnum(this); + other.current = current; + return other; + } + + /** + * Compares for equality. + */ + public boolean equal(DynAny other) + { + if (other instanceof gnuDynEnum) + { + gnuDynEnum oe = (gnuDynEnum) other; + return current == oe.current && + (oe.values == values || Arrays.equals(values, oe.values)); + } + else if (other instanceof DynEnum) + { + DynEnum oe = (DynEnum) other; + return current == oe.get_as_ulong() && official_type.equal(oe.type()); + } + else + return false; + } + + /** + * Set value from any that must contain enumeration. + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + InputStream in = an_any.create_input_stream(); + set_as_ulong(in.read_long()); + in.close(); + } + catch (MARSHAL eof) + { + throw new InvalidValue(); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get the value of this enumeration as string. + */ + public String get_as_string() + { + return values [ current ]; + } + + /** + * Get the value of this enumeration as int. + */ + public int get_as_ulong() + { + return current; + } + + /** + * Set the value of this enumeration as string. + */ + public void set_as_string(String value) throws InvalidValue + { + for (int i = 0; i < values.length; i++) + { + if (values [ i ].equals(value)) + { + current = i; + valueChanged(); + return; + } + } + throw new InvalidValue(value); + } + + /** + * Set the value of this enumeration as int. + */ + public void set_as_ulong(int value) throws InvalidValue + { + if (value < 0 || value >= values.length) + throw new InvalidValue(value + " not in [0.." + values.length); + else + { + current = value; + valueChanged(); + } + } + + /** + * Wrap the enumeration value into any. + */ + public Any to_any() + { + Any a = createAny(); + a.insert_long(current); + a.type(official_type); + return a; + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java new file mode 100644 index 000000000..9c7ea8252 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynFixed.java @@ -0,0 +1,252 @@ +/* gnuDynFixed.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynFixed; +import org.omg.DynamicAny.DynFixedOperations; + +import java.math.BigDecimal; + +/** + * Implements DynAny, holding CORBA <code>fixed</code>. This class is derived + * from gnuDynEnm to avoid repetetive inclusion of unused DynAny methods. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynFixed extends UndivideableAny implements DynFixed +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The default value, assigned in the new instance. + */ + static final BigDecimal ZERO = new BigDecimal("0.0"); + + /** + * The content of the dyn fixed, wrapped in this DynAny. + */ + BigDecimal value; + + /** + * The number of digits after the decimal point. + */ + final int scale; + + /** + * The number of digits. + */ + final int digits; + + /** + * Create a new instance of the dyn fixed. + */ + public gnuDynFixed(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + digits = final_type.fixed_digits(); + scale = final_type.fixed_scale(); + } + catch (Exception e) + { + throw new BAD_PARAM("Not a fixed"); + } + value = ZERO; + } + + /** + * Clone the current instance. + */ + public gnuDynFixed(gnuDynFixed from) + { + super(from.official_type, from.final_type, from.factory, from.orb); + digits = from.digits; + scale = from.scale; + value = from.value; + } + + /** + * Get the value of the wrapped dyn fixed, as string. + */ + public String get_value() + { + return value.toString(); + } + + /** + * Set the value. + */ + public boolean set_value(String fixed_value) + throws TypeMismatch, InvalidValue + { + // Count the digits till decimal point. + int digs = 0; + char c; + boolean leading0 = true; + Digs: + for (int i = 0; i < fixed_value.length(); i++) + { + c = fixed_value.charAt(i); + if (Character.isDigit(c)) + { + if (!(c == '0' && leading0)) + digs++; + if (c != '0') + leading0 = false; + } + else if (c == '.') + break Digs; + } + if (digs > (digits - scale)) + throw new InvalidValue("Too many digits: " + digs + " for " + digits + + "." + scale + ); + + try + { + value = new BigDecimal(fixed_value); + } + catch (NumberFormatException ex) + { + if (fixed_value.trim().length() == 0) + throw new InvalidValue("Empty string passed"); + + TypeMismatch inva = + new TypeMismatch("Not a number: '" + fixed_value + "'"); + inva.initCause(ex); + throw inva; + } + + valueChanged(); + return value.scale() <= scale; + } + + /** + * Assign the value from another BigDecimal. + */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof gnuDynFixed) + { + gnuDynFixed other = (gnuDynFixed) from; + value = other.value; + } + else if (from instanceof DynFixedOperations) + { + value = new BigDecimal(((DynFixedOperations) from).get_value()); + } + else + throw new TypeMismatch("Not a DynFixed"); + valueChanged(); + } + + /** + * Create a copy. + */ + public DynAny copy() + { + return new gnuDynFixed(this); + } + + /** + * Compare for equality. + */ + public boolean equal(DynAny other) + { + if (other instanceof gnuDynFixed) + { + // Normally, this code would be executed. + return value.equals(((gnuDynFixed) other).value); + } + if (other instanceof DynFixedOperations) + { + // This may be involved when mixing implementations. + return ((DynFixedOperations) other).get_value().equals(get_value()); + } + else + return false; + } + + /** + * Set the value from Any (must hold <code>fixed</code> with the matching + * typecode.). + */ + public void from_any(Any an_any) throws TypeMismatch, InvalidValue + { + try + { + checkType(official_type, an_any.type()); + + value = an_any.extract_fixed(); + valueChanged(); + } + catch (BAD_OPERATION e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** + * Create and return Any, holding this DynFixed value. + */ + public Any to_any() + { + Any g = createAny(); + g.insert_fixed(value, official_type); + return g; + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java new file mode 100644 index 000000000..d006c24a5 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynSequence.java @@ -0,0 +1,254 @@ +/* gnuDynSequence.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynSequence; + +import java.io.Serializable; + +import java.lang.reflect.*; + +public class gnuDynSequence + extends gnuDynArray + implements DynSequence, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The bound of the sequence, as defined in typecode. + */ + final int bound; + + /** + * Create a new gnuDynSequence with the given typecode. + * + * @throws BAD_PARAM if the passed typecode is probably not a sequence + * typecode. + */ + public gnuDynSequence(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + throws BAD_PARAM + { + super(oType, aType, aFactory, anOrb, false); + array = new DynAny[ 0 ]; + try + { + bound = final_type.length(); + } + catch (BadKind ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get the length of the sequence. + */ + public int get_length() + { + return array.length; + } + + /** + * Resize the sequence, preserving components. + */ + public void set_length(int length) + throws InvalidValue + { + checkBound(length); + if (length == array.length) + return; // Nothing to do. + else if (length < array.length) + { + // Truncate. + DynAny[] d = new DynAny[ length ]; + for (int i = 0; i < d.length; i++) + d [ i ] = array [ i ]; + array = d; + } + else + { + // Expand. + DynAny[] d = new DynAny[ length ]; + for (int i = 0; i < array.length; i++) + d [ i ] = array [ i ]; + + for (int i = array.length; i < d.length; i++) + { + try + { + d [ i ] = + factory.create_dyn_any_from_type_code(official_components); + } + catch (InconsistentTypeCode e) + { + throw new Unexpected(e); + } + } + array = d; + } + valueChanged(); + } + + /** + * Copy one DynAny into another. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynSequence) + { + DynSequence dyn = (DynSequence) from; + array = dyn.get_elements_as_dyn_any(); + } + else + throw new TypeMismatch(); + } + + /* + * Set the contenst of the sequence, resizing if required. + */ + public void set_elements_as_dyn_any(DynAny[] value) + throws InvalidValue, TypeMismatch + { + checkBound(value.length); + if (array.length != value.length) + set_length(value.length); + + for (int i = 0; i < value.length; i++) + { + checkType(official_components, value [ i ].type()); + array [ i ].assign(value [ i ]); + } + valueChanged(); + } + + /** + * Set the elements from array of Any's. + */ + public void set_elements(Any[] value) + throws InvalidValue, TypeMismatch + { + checkBound(value.length); + + DynAny[] prev = array; + + array = new DynAny[ value.length ]; + try + { + super.set_elements(value); + + // valueChanged() is called in super.set_elements(value). + } + + // On the problem, value does not change. + catch (TypeMismatch ex) + { + array = prev; + throw ex; + } + catch (InvalidValue ex) + { + array = prev; + throw ex; + } + catch (RuntimeException rex) + { + array = prev; + throw rex; + } + } + + /** + * Create a copy. + */ + public DynAny copy() + { + DynAny[] c = new DynAny[ array.length ]; + for (int i = 0; i < c.length; i++) + { + c [ i ] = array [ i ].copy(); + } + + gnuDynSequence d = + new gnuDynSequence(official_type, final_type, factory, orb); + d.array = c; + return d; + } + + /** + * Check the bound. + * + * @param x the value to check. + */ + void checkBound(int x) + throws InvalidValue + { + if (bound != 0) + if (x < 0 || x > bound) + throw new InvalidValue(x + " out of bounds, valid [0.." + bound + "]"); + } + + /** + * Check if array size is valid. Called from from_any. + */ + protected void checkArrayValid(Object members) + throws TypeMismatch, InvalidValue + { + checkBound(Array.getLength(members)); + if (get_length() != Array.getLength(members)) + set_length(Array.getLength(members)); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java new file mode 100644 index 000000000..b15aff3e1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynStruct.java @@ -0,0 +1,109 @@ +/* gnuDynStruct.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import java.io.Serializable; + +import org.omg.CORBA.ORB; +import org.omg.CORBA.TypeCode; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; +import gnu.CORBA.Unexpected; +import org.omg.DynamicAny.DynAny; + +/** + * Implementation of the DynStruct. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynStruct + extends RecordAny + implements DynStruct, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create an instance. + */ + public gnuDynStruct(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + super(oType, aType, aFactory, anOrb); + + // Initialise fields. + try + { + array = new DynAny[ final_type.member_count() ]; + fNames = new String[ array.length ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(final_type.member_type(i)); + fNames [ i ] = final_type.member_name(i); + } + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + protected RecordAny newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb) + { + return new gnuDynStruct(oType, aType, aFactory, anOrb); + } + + /** @inheritDoc */ + public NameDynAnyPair[] get_members_as_dyn_any() + { + return super.gnu_get_members_as_dyn_any(); + } + + /** @inheritDoc */ + public NameValuePair[] get_members() + { + return super.gnu_get_members(); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java new file mode 100644 index 000000000..adbc5731d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynUnion.java @@ -0,0 +1,437 @@ +/* gnuDynUnion.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynUnion; + +import java.io.Serializable; + +/** + * Implementation of DynUnion. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynUnion + extends DivideableAny + implements DynUnion, Serializable, ValueChangeListener +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The discrimintor of this union. + */ + DynAny discriminator; + + /** + * The message string that occurs several times throwing exception. + */ + static String NOAM = "No active member"; + + /** + * Create a new instance with the given typecode. + * + * @param aType the final_type, must be final_type of the union. + */ + public gnuDynUnion(TypeCode oType, TypeCode aType, gnuDynAnyFactory aFactory, + ORB anOrb + ) + throws InconsistentTypeCode + { + super(oType, aType, aFactory, anOrb); + try + { + discriminator = + factory.create_dyn_any_from_type_code(final_type.discriminator_type()); + + ((AbstractAny) discriminator).listener = this; + + if (final_type.default_index() >= 0) + set_to_default_member(); + else + set_to_no_active_member(); + } + catch (Exception ex) + { + InconsistentTypeCode inc = new InconsistentTypeCode("discriminator"); + inc.initCause(ex); + throw inc; + } + } + + /* + * (non-Javadoc) + * + * @see gnu.CORBA.DynAn.DivideableAny#to_any() + */ + public Any to_any() + { + Any a = createAny(); + OutputStream ou = a.create_output_stream(); + discriminator.to_any().write_value(ou); + if (array.length == 2) + array [ 1 ].to_any().write_value(ou); + a.read_value(ou.create_input_stream(), final_type); + return a; + } + + /** + * Assign from another identical structure. + */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (!(from instanceof DynUnion)) + throw new TypeMismatch("DynUnion required"); + else + { + try + { + DynUnion u = (DynUnion) from; + discriminator.assign(u.get_discriminator()); + if (u.has_no_active_member()) + { + if (array.length != 1) + array = new DynAny[] { discriminator }; + } + else + { + if (array.length != 2) + array = new DynAny[] { discriminator, u.member().copy() }; + else + array [ 1 ] = u.member().copy(); + } + } + catch (InvalidValue e) + { + throw new Unexpected(e); + } + } + valueChanged(); + } + + /** @inheritDoc */ + public DynAny copy() + { + try + { + gnuDynUnion other = + new gnuDynUnion(official_type, final_type, factory, orb); + other.discriminator = discriminator.copy(); + ((AbstractAny) other.discriminator).listener = other; + if (array.length == 1) + { + other.array = new DynAny[] { other.discriminator }; + } + else + { + other.array = + new DynAny[] { other.discriminator, array [ 1 ].copy() }; + } + return other; + } + catch (InconsistentTypeCode ex) + { + throw new Unexpected(ex); + } + } + + /** + * Done via reading from stream. + */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + + Any adis = createAny(); + try + { + InputStream stream = an_any.create_input_stream(); + adis.read_value(stream, final_type.discriminator_type()); + + DynAny nd = factory.create_dyn_any(adis); + + set_discriminator(nd); + if (array.length == 2) + { + // Reusing the same Any <code>adis</code>. + adis.read_value(stream, array [ 1 ].type()); + array [ 1 ].from_any(adis); + } + } + catch (InconsistentTypeCode it) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(it); + throw t; + } + catch (MARSHAL m) + { + InvalidValue t = new InvalidValue(); + t.initCause(m); + throw t; + } + catch (BadKind b) + { + throw new Unexpected(b); + } + valueChanged(); + } + + /** @inheritDoc */ + public TCKind discriminator_kind() + { + return discriminator.type().kind(); + } + + /** @inheritDoc */ + public DynAny get_discriminator() + { + return discriminator; + } + + /** @inheritDoc */ + public boolean has_no_active_member() + { + return array.length == 1; + } + + /** @inheritDoc */ + public TCKind member_kind() + throws InvalidValue + { + return member().type().kind(); + } + + /** + * Get the name of the current variant of the union. + */ + public String member_name() + throws InvalidValue + { + if (array.length == 1) + throw new InvalidValue(NOAM); + try + { + Any da = discriminator.to_any(); + + + // Get the discriminator variant. + for (int i = 0; i < final_type.member_count(); i++) + { + if (final_type.member_label(i).equal(da)) + return final_type.member_name(i); + } + throw new InvalidValue(NOAM); + } + catch (Exception e) + { + InvalidValue t = new InvalidValue("Err"); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public DynAny member() + throws InvalidValue + { + if (array.length < 2) + throw new InvalidValue(NOAM); + else + return array [ 1 ]; + } + + /** + * Set the union discriminator. + */ + public void set_discriminator(DynAny aDiscriminator) + throws TypeMismatch + { + try + { + if (!aDiscriminator.type().equal(final_type.discriminator_type())) + throw new TypeMismatch("Wrong discriminator final_type for " + + final_type.name() + ); + + // Seting the same discriminator value again should not change + // the fields of the current member. + if (!discriminator.equal(aDiscriminator)) + { + discriminator.assign(aDiscriminator); + updateMember(); + } + else + { + pos = array.length == 2 ? 1 : 0; + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** + * Set to default member, if one exists. + */ + public void set_to_default_member() + throws TypeMismatch + { + try + { + int di = final_type.default_index(); + if (di < 0) + throw new TypeMismatch("Union " + final_type.name() + + "has no default index" + ); + + Any da = final_type.member_label(di); + discriminator.from_any(da); + updateMember(); + } + catch (TypeMismatch m) + { + // This one OK. + throw m; + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public void set_to_no_active_member() + throws TypeMismatch + { + try + { + if (final_type.default_index() >= 0) + { + throw new TypeMismatch("Explicit default case defined."); + } + } + catch (BadKind ex) + { + // The default index is not set. + } + array = new DynAny[] { discriminator }; + valueChanged(); + } + + /** + * Update member, in accordance with discriminator value. + */ + public void updateMember() + throws TypeMismatch + { + try + { + Any da = discriminator.to_any(); + + + // Get the discriminator variant. + for (int i = 0; i < final_type.member_count(); i++) + { + if (final_type.member_label(i).equal(da)) + { + array = + new DynAny[] + { + discriminator, + factory.create_dyn_any_from_type_code(final_type.member_type(i)) + }; + pos = 1; + valueChanged(); + return; + } + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + + // Discrimintator does not point to valid member. + array = new DynAny[] { discriminator }; + pos = 0; + valueChanged(); + } + + /** + * Called when the discriminator is changed. + */ + public void changed() + { + try + { + updateMember(); + } + catch (TypeMismatch ex) + { + throw new Unexpected(ex); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java new file mode 100644 index 000000000..32b2f0d1a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValue.java @@ -0,0 +1,380 @@ +/* gnuDynValue.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Minor; +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.VM_TRUNCATABLE; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ValueFactory; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynStruct; +import org.omg.DynamicAny.DynValue; +import org.omg.DynamicAny.DynValueCommon; +import org.omg.DynamicAny.DynValueOperations; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameValuePair; + +import java.io.Serializable; + +/** + * Implementation of DynValue. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynValue extends RecordAny implements DynValue, + Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * If true, the value of this ValueType is set to null. + */ + boolean isNull; + + /** + * Create an instance. + */ + public gnuDynValue(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + + // Initialise fields. The array of fields also includes all inherited + // fields. + try + { + array = new DynAny[ final_type.member_count() ]; + fNames = new String[ array.length ]; + for (int i = 0; i < array.length; i++) + { + array [ i ] = + factory.create_dyn_any_from_type_code(final_type.member_type(i)); + fNames [ i ] = final_type.member_name(i); + } + + // Search of inherited members. + if (final_type.type_modifier() == VM_TRUNCATABLE.value) + { + TypeCode parent = final_type.concrete_base_type(); + DynAny ancestor = factory.create_dyn_any_from_type_code(parent); + + if (ancestor instanceof DynValue) + { + // Add members of ancestor in front of the curren members. + DynValue anc = (DynValue) ancestor; + anc.set_to_value(); + + NameDynAnyPair[] aar = anc.get_members_as_dyn_any(); + inheritFields(aar); + } + else if (ancestor instanceof DynStruct) + { + // Add members of ancestor in front of the curren members. + DynStruct anc = (DynStruct) ancestor; + NameDynAnyPair[] aar = anc.get_members_as_dyn_any(); + inheritFields(aar); + } + else + throw new BAD_PARAM("The parent of " + final_type.id() + ", " + + parent.id() + ", is not structure nor value." + ); + } + } + catch (Exception e) + { + throw new Unexpected(e); + } + + set_to_null(); + } + + /** + * Inherit the provided fields. + */ + private void inheritFields(NameDynAnyPair[] aar) + { + DynAny[] nArray = new DynAny[ array.length + aar.length ]; + String[] nNames = new String[ array.length + aar.length ]; + int p = 0; + for (int i = 0; i < aar.length; i++) + { + nArray [ p ] = aar [ i ].value; + nNames [ p ] = aar [ i ].id; + p++; + } + + for (int i = 0; i < array.length; i++) + { + nArray [ p ] = array [ i ]; + nNames [ p ] = fNames [ i ]; + p++; + } + + array = nArray; + fNames = nNames; + } + + /** @inheritDoc */ + public TCKind current_member_kind() throws TypeMismatch, InvalidValue + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.current_member_kind(); + } + + /** @inheritDoc */ + public String current_member_name() throws TypeMismatch, InvalidValue + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.current_member_name(); + } + + /** @inheritDoc */ + public NameDynAnyPair[] get_members_as_dyn_any() throws InvalidValue + { + if (isNull) + throw new InvalidValue(ISNULL); + return super.gnu_get_members_as_dyn_any(); + } + + /** @inheritDoc */ + public NameValuePair[] get_members() throws InvalidValue + { + if (isNull) + throw new InvalidValue(ISNULL); + else + return super.gnu_get_members(); + } + + /** @inheritDoc */ + public void set_members_as_dyn_any(NameDynAnyPair[] value) + throws TypeMismatch, InvalidValue + { + super.set_members_as_dyn_any(value); + isNull = false; + } + + /** @inheritDoc */ + public void set_members(NameValuePair[] value) + throws TypeMismatch, InvalidValue + { + super.set_members(value); + isNull = false; + } + + /** @inheritDoc */ + public boolean is_null() + { + return isNull; + } + + /** @inheritDoc */ + public void set_to_null() + { + isNull = true; + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_value() + { + isNull = false; + valueChanged(); + } + + /** + * Create a new instance. + */ + protected RecordAny newInstance(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + gnuDynValue v = new gnuDynValue(oType, aType, aFactory, anOrb); + if (isNull) + v.set_to_null(); + else + v.set_to_value(); + return v; + } + + /** + * Compare for equality, minding null values. + */ + public boolean equal(DynAny other) + { + if (other instanceof DynValueOperations) + { + DynValueCommon o = (DynValueCommon) other; + if (isNull) + return o.is_null() && o.type().equal(official_type); + else + return !o.is_null() && super.equal(other); + } + else + return false; + } + + /** + * Get the focused component, throwing exception if the current value is null. + */ + protected DynAny focused() throws InvalidValue, TypeMismatch + { + if (isNull) + throw new TypeMismatch(ISNULL); + else + return super.focused(); + } + + /** + * Convert into Any. + */ + public Any to_any() + { + if (isNull) + { + Any a0 = createAny(); + a0.type(orb.get_primitive_tc(TCKind.tk_null)); + return a0; + } + else + { + try + { + ValueFactory factory = + ((org.omg.CORBA_2_3.ORB) orb).lookup_value_factory(official_type.id()); + if (factory == null) + { + MARSHAL m = new MARSHAL("Factory for " + official_type.id() + + " not registered."); + m.minor = Minor.Factory; + throw m; + } + + OutputStream out = orb.create_output_stream(); + + for (int i = 0; i < array.length; i++) + array [ i ].to_any().write_value(out); + + org.omg.CORBA_2_3.portable.InputStream in = + (org.omg.CORBA_2_3.portable.InputStream) out.create_input_stream(); + Serializable v = factory.read_value(in); + + Any g = createAny(); + g.type(official_type); + g.insert_Value(v, official_type); + + return g; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + } + + /** @inheritDoc */ + public void assign(DynAny from) throws TypeMismatch + { + checkType(official_type, from.type()); + + if (from instanceof DynValue) + { + DynValue other = (DynValue) from; + if (other.is_null()) + set_to_null(); + else + { + set_to_value(); + try + { + DynValueOperations src = (DynValueOperations) from; + set_members_as_dyn_any(src.get_members_as_dyn_any()); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + } + } + else + throw new TypeMismatch("Not a DynValue"); + } + + /** + * Get the number of components. + */ + public int component_count() + { + return isNull ? 0 : super.component_count(); + } + + /** {@inheritDoc} */ + public Serializable get_val() throws TypeMismatch, InvalidValue + { + return to_any().extract_Value(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) throws InvalidValue, TypeMismatch + { + Any a = to_any(); + a.insert_Value(a_x); + from_any(a); + valueChanged(); + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java new file mode 100644 index 000000000..9c50534ed --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAn/gnuDynValueBox.java @@ -0,0 +1,389 @@ +/* gnuDynValueBox.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.DynAn; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.HolderLocator; + +import org.omg.CORBA.Any; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode; +import org.omg.DynamicAny.DynAnyPackage.InvalidValue; +import org.omg.DynamicAny.DynAnyPackage.TypeMismatch; +import org.omg.DynamicAny.DynValueBox; +import org.omg.DynamicAny.DynValueBoxOperations; +import org.omg.DynamicAny.DynValueCommon; + +import java.io.Serializable; + +import java.lang.reflect.Field; + +/** + * Implementation of the DynValueBox. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuDynValueBox + extends DivideableAny + implements DynValueBox, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The final_type of contents of this value box. + */ + final TypeCode content; + + /** + * The string for some TypeMismatch exceptions. + */ + String CONTENT = "Box content final_type mismatch"; + + /** + * Create a new instance of gnuDynValueBox. + */ + public gnuDynValueBox(TypeCode oType, TypeCode aType, + gnuDynAnyFactory aFactory, ORB anOrb + ) + { + super(oType, aType, aFactory, anOrb); + try + { + content = final_type.content_type(); + array = new DynAny[] { factory.create_dyn_any_from_type_code(content) }; + set_to_null(); + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + public void assign(DynAny from) + throws TypeMismatch + { + checkType(official_type, from.type()); + if (from instanceof DynValueBoxOperations) + { + DynValueBoxOperations other = (DynValueBoxOperations) from; + if (other.is_null()) + set_to_null(); + else + { + DynAny inBox; + try + { + inBox = other.get_boxed_value_as_dyn_any(); + } + catch (InvalidValue e) + { + TypeMismatch t = new TypeMismatch("Invalid value"); + t.initCause(e); + throw t; + } + if (!content.equal(inBox.type())) + throw new TypeMismatch(CONTENT); + array = new DynAny[] { inBox.copy() }; + } + } + valueChanged(); + } + + /** @inheritDoc */ + public DynAny copy() + { + gnuDynValueBox other = + new gnuDynValueBox(official_type, final_type, factory, orb); + if (is_null()) + other.set_to_null(); + else + { + try + { + other.array = new DynAny[] { array [ 0 ].copy() }; + } + catch (Exception e) + { + throw new Unexpected(e); + } + } + return other; + } + + /** + * Returns null for null value, delegates to super. otherwise. + */ + public DynAny current_component() + throws TypeMismatch + { + if (is_null()) + return null; + else + return super.current_component(); + } + + /** + * Compare for equality, minding null values. + */ + public boolean equal(DynAny other) + { + if (other instanceof DynValueCommon) + { + DynValueCommon o = (DynValueCommon) other; + if (is_null()) + return o.is_null() && o.type().equal(official_type); + else + return !o.is_null() && super.equal(other); + } + else + return false; + } + + /** @inheritDoc */ + public void from_any(Any an_any) + throws TypeMismatch, InvalidValue + { + checkType(official_type, an_any.type()); + try + { + if (!an_any.type().content_type().equal(content)) + throw new InvalidValue(CONTENT); + } + catch (BadKind e) + { + TypeMismatch t = new TypeMismatch("Not a box"); + t.initCause(e); + throw t; + } + + Serializable s = an_any.extract_Value(); + if (s == null) + set_to_null(); + else + { + try + { + Streamable holder = HolderLocator.createHolder(content); + Field v = holder.getClass().getField("value"); + v.set(holder, s); + + Any cont = createAny(); + cont.insert_Streamable(holder); + + array = new DynAny[] { factory.create_dyn_any(cont) }; + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + valueChanged(); + } + + /** @inheritDoc */ + public Any get_boxed_value() + throws InvalidValue + { + try + { + if (is_null()) + throw new InvalidValue(ISNULL); + else + return array [ 0 ].to_any(); + } + catch (Exception e) + { + InvalidValue t = new InvalidValue(); + t.initCause(e); + throw t; + } + } + + /** @inheritDoc */ + public DynAny get_boxed_value_as_dyn_any() + throws InvalidValue + { + if (is_null()) + throw new InvalidValue(ISNULL); + else + return array [ 0 ].copy(); + } + + /** {@inheritDoc} */ + public Serializable get_val() + throws TypeMismatch, InvalidValue + { + return to_any().extract_Value(); + } + + /** {@inheritDoc} */ + public void insert_val(Serializable a_x) + throws InvalidValue, TypeMismatch + { + Any a = to_any(); + a.insert_Value(a_x); + from_any(a); + valueChanged(); + } + + /** @inheritDoc */ + public boolean is_null() + { + return array.length == 0; + } + + /** @inheritDoc */ + public void set_boxed_value(Any boxIt) + throws TypeMismatch + { + if (!content.equal(boxIt.type())) + throw new TypeMismatch(CONTENT); + try + { + if (is_null()) + { + array = new DynAny[] { factory.create_dyn_any(boxIt) }; + } + else + { + array [ 0 ].from_any(boxIt); + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + valueChanged(); + } + + /** @inheritDoc */ + public void set_boxed_value_as_dyn_any(DynAny boxIt) + throws TypeMismatch + { + if (!content.equal(boxIt.type())) + throw new TypeMismatch(CONTENT); + try + { + if (is_null()) + { + array = new DynAny[] { boxIt.copy() }; + } + else + { + array [ 0 ].assign(boxIt); + } + } + catch (Exception e) + { + TypeMismatch t = new TypeMismatch(); + t.initCause(e); + throw t; + } + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_null() + { + array = new DynAny[ 0 ]; + valueChanged(); + } + + /** @inheritDoc */ + public void set_to_value() + { + try + { + if (array.length == 0) + { + array = + new DynAny[] { factory.create_dyn_any_from_type_code(content) }; + } + } + catch (InconsistentTypeCode e) + { + throw new Unexpected(e); + } + valueChanged(); + } + + /** @inheritDoc */ + public Any to_any() + { + Any a = createAny(); + + if (!is_null()) + { + try + { + Streamable holder; + if (array [ 0 ] instanceof gnuDynAny) + holder = ((gnuDynAny) array [ 0 ]).holder; + else + { + Any uan = array [ 0 ].to_any(); + holder = uan.extract_Streamable(); + } + + Field v = holder.getClass().getField("value"); + Serializable value = (Serializable) v.get(holder); + a.type(official_type); + a.insert_Value(value, content); + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + } + else + a.type(orb.get_primitive_tc(TCKind.tk_null)); + return a; + } +} diff --git a/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java b/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java new file mode 100644 index 000000000..4447aa685 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/DynAnySeqHolder.java @@ -0,0 +1,116 @@ +/* DynAnySeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.DynAny; +import org.omg.DynamicAny.DynAnySeqHelper; + +/** + * A holder for the sequence of {@link DynAny} + * ({@link DynAnySeq}). + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class DynAnySeqHolder + implements Streamable +{ + /** + * The stored array of <code>DynAny</code>. + */ + public DynAny[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public DynAnySeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public DynAnySeqHolder(DynAny[] initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = DynAnySeqHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + DynAnySeqHelper.write(output, value); + } + + /** + * Get the typecode of the DynAny. + */ + public org.omg.CORBA.TypeCode _type() + { + return DynAnySeqHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/EmptyExceptionHolder.java b/libjava/classpath/gnu/CORBA/EmptyExceptionHolder.java new file mode 100644 index 000000000..a48b60562 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/EmptyExceptionHolder.java @@ -0,0 +1,131 @@ +/* EmptyStructHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UNKNOWN; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +/** + * This holder can store any CORBA exception that has no user defined fields. + * Only the repository ID is written when the method {@link #_write} is called. + * The _read method is not supported for this holder. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class EmptyExceptionHolder + implements Streamable +{ + /** + * The wrapped exception. + */ + public Throwable value; + + /** + * The typecode of the wrapped exception. + */ + public TypeCode typecode; + + /** + * Create the exception holder, initialised to the given values. + * + * @param an_exception the wrapped exception. + * @param an_id the exception repository id. + */ + public EmptyExceptionHolder(Throwable an_exception, TypeCode a_typecode) + { + value = an_exception; + typecode = a_typecode; + } + + /** + * Reads the exception from the input stream. + * + * The value field obtains the value of either the read exception or + * the UNKNOWN if the repository ID does not match + * the exception from the reachable code. + */ + public void _read(InputStream input) + { + String id = input.read_string(); + Object ex = ObjectCreator.Idl2Object(id); + if (ex == null) + value = new UNKNOWN(id); + else + value = (Throwable) ex; + } + + /** + * Return the typecode of the stored exception. + * + * @return the value, passed as a_typecode in constructor. + */ + public TypeCode _type() + { + return typecode; + } + + /** + * Write the exception into the give output stream. Writes the + * repository id that is taken from the typecode. This method also + * works when no helper class is available. + * + * @param output a stream to write into. + * + * @throws BAD_OPERATION if the value for the holder is not set or + * the typecode cannot provide repository id. + */ + public void _write(OutputStream output) + { + try + { + output.write_string(typecode.id()); + } + catch (Exception ex) + { + BAD_OPERATION bad = new BAD_OPERATION(); + bad.minor = Minor.CDR; + bad.initCause(ex); + throw bad; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java b/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java new file mode 100644 index 000000000..320b6d232 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ForwardRequestHelper.java @@ -0,0 +1,152 @@ +/* ForwardRequestHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.Poa.ForwardRequestHolder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ObjectHelper; +import org.omg.CORBA.StructMember; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.PortableServer.ForwardRequest; + +/** + * The helper operations for the exception {@link ForwardRequest}. + * + * @specnote The helper must be here and not in POA subpackage as it must + * be discovered by the {@link ObjectCreator} when reading this remote + * exception. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class ForwardRequestHelper +{ + /** + * Extract the ForwardRequest from given Any. + * This method uses the ForwardRequestHolder. + * + * @throws BAD_OPERATION if the passed Any does not contain ForwardRequest. + */ + public static ForwardRequest extract(Any any) + { + try + { + return ((ForwardRequestHolder) any.extract_Streamable()).value; + } + catch (ClassCastException cex) + { + BAD_OPERATION bad = new BAD_OPERATION("ForwardRequest expected"); + bad.minor = Minor.Any; + bad.initCause(cex); + throw bad; + } + } + + /** + * Get the ForwardRequest repository id. + * + * @return "ForwardRequest", always. + */ + public static String id() + { + return "ForwardRequest"; + } + + /** + * Insert the ForwardRequest into the given Any. + * This method uses the ForwardRequestHolder. + * + * @param any the Any to insert into. + * @param that the ForwardRequest to insert. + */ + public static void insert(Any any, ForwardRequest that) + { + any.insert_Streamable(new ForwardRequestHolder(that)); + } + + /** + * Read the exception from the CDR intput stream. + * + * @param input a org.omg.CORBA.portable stream to read from. + */ + public static ForwardRequest read(InputStream input) + { + // Read the exception repository id. + String id = input.read_string(); + ForwardRequest value = new ForwardRequest(); + + value.forward_reference = input.read_Object(); + return value; + } + + /** + * Create the ForwardRequest typecode (structure, + * named "ForwardRequest"). + * The typecode states that the structure contains the + * following fields: forward_reference. + */ + public static TypeCode type() + { + ORB orb = OrbRestricted.Singleton; + StructMember[] members = new StructMember[ 1 ]; + + TypeCode field; + + field = ObjectHelper.type(); + members [ 0 ] = new StructMember("forward_reference", field, null); + return orb.create_exception_tc(id(), "ForwardRequest", members); + } + + /** + * Write the exception to the CDR output stream. + * + * @param output a org.omg.CORBA.portable stream stream to write into. + * @param value a value to write. + */ + public static void write(OutputStream output, ForwardRequest value) + { + // Write the exception repository id. + output.write_string(id()); + output.write_Object(value.forward_reference); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/CancelHeader.java b/libjava/classpath/gnu/CORBA/GIOP/CancelHeader.java new file mode 100644 index 000000000..40f373721 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/CancelHeader.java @@ -0,0 +1,70 @@ +/* CancelHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * The message header for cancelling the request. + * + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class CancelHeader +{ + /** + * The Id of request being cancelled. + */ + public int request_id; + + /** + * Read the header. + * + * @param input a stream to read from. + */ + public abstract void read(InputStream input); + + /** + * Write the header. + * + * @param output a stream to write to. + */ + public abstract void write(OutputStream output); +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/CharSets_OSF.java b/libjava/classpath/gnu/CORBA/GIOP/CharSets_OSF.java new file mode 100644 index 000000000..6cefe995f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/CharSets_OSF.java @@ -0,0 +1,238 @@ +/* CharSets_OSF.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import java.nio.charset.Charset; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Set; + +/** + * This class contains the codes, used to identify character sets + * in CORBA. These codes are defined in Open Software Foundation (OSF) + * code set registry. + * + * The name of this class specially sets "OSF" apart if somebody would start + * searching Open Software Foundation abbreviation. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class CharSets_OSF +{ + public static final int ASCII = 0x00010020; + public static final int ISO8859_1 = 0x00010001; + public static final int ISO8859_2 = 0x00010002; + public static final int ISO8859_3 = 0x00010003; + public static final int ISO8859_4 = 0x00010004; + public static final int ISO8859_5 = 0x00010005; + public static final int ISO8859_6 = 0x00010006; + public static final int ISO8859_7 = 0x00010007; + public static final int ISO8859_8 = 0x00010008; + public static final int ISO8859_9 = 0x00010009; + public static final int ISO8859_15_FDIS = 0x0001000F; + public static final int UTF8 = 0x05010001; + public static final int UTF16 = 0x00010109; + public static final int UCS2 = 0x00010100; + public static final int Cp1047 = 0x10020417; + public static final int Cp1250 = 0x100204E2; + public static final int Cp1251 = 0x100204E3; + public static final int Cp1252 = 0x100204E4; + public static final int Cp1253 = 0x100204E5; + public static final int Cp1254 = 0x100204E6; + public static final int Cp1255 = 0x100204E7; + public static final int Cp1256 = 0x100204E8; + public static final int Cp1257 = 0x100204E9; + public static final int Cp1363 = 0x10020553; + public static final int Cp1363C = 0x10020553; + public static final int Cp1381 = 0x10020565; + public static final int Cp1383 = 0x10020567; + public static final int Cp1386 = 0x1002056A; + public static final int Cp33722 = 0x100283BA; + public static final int Cp33722C = 0x100283BA; + public static final int Cp930 = 0x100203A2; + public static final int Cp943 = 0x100203AF; + public static final int Cp943C = 0x100203AF; + public static final int Cp949 = 0x100203B5; + public static final int Cp949C = 0x100203B5; + public static final int Cp950 = 0x100203B6; + public static final int Cp964 = 0x100203C4; + public static final int Cp970 = 0x100203CA; + public static final int EUC_JP = 0x00030010; + public static final int EUC_KR = 0x0004000A; + public static final int EUC_TW = 0x00050010; + + /** + * The native character set for the narrow character. + */ + public static final int NATIVE_CHARACTER = ISO8859_1; + + /** + * The native character set for the wide character. + */ + public static final int NATIVE_WIDE_CHARACTER = UTF16; + + /** + * Table to convert from the code to string name. + */ + private static Hashtable code_to_string; + + /** + * Table to convert from the string name to code. + */ + private static Hashtable string_to_code; + + /** + * Get the charset code from its name. + * + * @return the charset code of 0 if not defined. + */ + public static int getCode(String name) + { + if (string_to_code == null) + makeMap(); + + Integer code = (Integer) string_to_code.get(name); + return code == null ? 0 : code.intValue(); + } + + /** + * Get the charset name from its code. + * + * @return the code set name or nullfor the unknown code set. + */ + public static String getName(int code) + { + if (code_to_string == null) + makeMap(); + return (String) code_to_string.get(new Integer(code)); + } + + /** + * Get the list of supported char sets for that the CORBA codes are + * also known. + */ + public static int[] getSupportedCharSets() + { + Set supported_sets = Charset.availableCharsets().keySet(); + int[] supported = new int[ supported_sets.size() ]; + Iterator iter = supported_sets.iterator(); + + int i = 0; + int code; + while (iter.hasNext()) + { + code = getCode(iter.next().toString()); + if (code > 0) + supported [ i++ ] = code; + } + + // Truncate the unused part. + int[] f = new int[ i ]; + System.arraycopy(supported, 0, f, 0, f.length); + + return f; + } + + /** + * Create a convertion map. + */ + private static void makeMap() + { + code_to_string = new Hashtable(); + string_to_code = new Hashtable(); + + // Put standard char sets. + put(ASCII, "US-ASCII"); + put(ISO8859_1, "ISO-8859-1"); + put(UTF16, "UTF-16"); + + // Put other known char sets. + put(ISO8859_2, "ISO-8859-2"); + put(ISO8859_3, "ISO-8859-3"); + put(ISO8859_4, "ISO-8859-4"); + put(ISO8859_5, "ISO-8859-5"); + put(ISO8859_6, "ISO-8859-6"); + put(ISO8859_7, "ISO-8859-7"); + put(ISO8859_8, "ISO-8859-8"); + put(ISO8859_9, "ISO-8859-9"); + + put(UTF8, "UTF-8"); + put(UCS2, "UCS-2"); + + put(ISO8859_15_FDIS, "ISO8859-15-FDIS"); + + put(Cp1047, "Cp1047"); + put(Cp1250, "Cp1250"); + put(Cp1251, "Cp1251"); + put(Cp1252, "Cp1252"); + put(Cp1253, "Cp1253"); + put(Cp1254, "Cp1254"); + put(Cp1255, "Cp1255"); + put(Cp1256, "Cp1256"); + put(Cp1257, "Cp1257"); + put(Cp1363, "Cp1363"); + put(Cp1363C, "Cp1363C"); + put(Cp1381, "Cp1381"); + put(Cp1383, "Cp1383"); + put(Cp1386, "Cp1386"); + put(Cp33722, "Cp33722"); + put(Cp33722C, "Cp33722C"); + put(Cp930, "Cp930"); + put(Cp943, "Cp943"); + put(Cp943C, "Cp943C"); + put(Cp949, "Cp949"); + put(Cp949C, "Cp949C"); + put(Cp950, "Cp950"); + put(Cp964, "Cp964"); + put(Cp970, "Cp970"); + + put(EUC_JP, "EUC-JP"); + put(EUC_KR, "EUC-KR"); + put(EUC_TW, "EUC-TW"); + } + + private static void put(int code, String name) + { + Integer ic = new Integer(code); + + code_to_string.put(ic, name); + string_to_code.put(name, ic); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/CloseMessage.java b/libjava/classpath/gnu/CORBA/GIOP/CloseMessage.java new file mode 100644 index 000000000..c555f2b94 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/CloseMessage.java @@ -0,0 +1,106 @@ +/* CloseMessage.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.MARSHAL; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * The explicit command to close the connection. + * + * + * The close message consists from the message header only and + * is the same for GIOP 1.0, 1.1, 1.2 and 1.3. The CloseMessage + * uses the default value from the {@link MessageHeader}. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class CloseMessage + extends MessageHeader +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The singleton close message is typically enough, despite new + * instances may be instantiated if the specific version field + * value is mandatory. + */ + private static final CloseMessage Singleton = new CloseMessage(); + + /** + * Create a new error message, setting the message field + * to the {@link MESSAGE_CLOSE} and the version number to + * the given major and minor values. + */ + public CloseMessage() + { + message_type = CLOSE_CONNECTION; + } + + /** + * Send the close message to the given output stream. The method, + * however, does not close the socket itself, this must be done + * explicitly in the calling code. + * + * @param socketStream a stream, where the close message is + * written. + */ + public static void close(OutputStream socketStream) + { + try + { + Singleton.write(socketStream); + socketStream.flush(); + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL("Unable to flush the stream"); + m.minor = Minor.Header; + m.initCause(ex); + throw m; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/CodeSetServiceContext.java b/libjava/classpath/gnu/CORBA/GIOP/CodeSetServiceContext.java new file mode 100644 index 000000000..81412e029 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/CodeSetServiceContext.java @@ -0,0 +1,222 @@ +/* CodeSet_sctx.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.IOR; +import java.io.IOException; + +/** + * The code set service context. This context must be included in all + * messages that use wide characters. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class CodeSetServiceContext + extends ServiceContext +{ + /** + * The context code sets id. + */ + public static final int ID = 1; + + /** + * The standard component to include in the messages. + */ + public static final CodeSetServiceContext STANDARD = new CodeSetServiceContext(); + + /** + * The encoding, used to transfer the narrow (1 byte) character data. + * The default value is taken from {@link CharSets_OSF#NATIVE_CHARACTER}. + */ + public int char_data = CharSets_OSF.NATIVE_CHARACTER; + + /** + * The encoding, used to transfer the wide character data. + * The default value is taken from + * {@link CharSets_OSF#NATIVE_WIDE_CHARACTER}. + */ + public int wide_char_data = CharSets_OSF.NATIVE_WIDE_CHARACTER; + + /** + * Find and return the code set service context in the give + * contexts array. Returns {@link #STANDARD} if no code set + * context is present. + * + * @param contexts the array of contexts, can be null. + */ + public static CodeSetServiceContext find(ServiceContext[] contexts) + { + if (contexts != null) + for (int i = 0; i < contexts.length; i++) + { + if (contexts [ i ] instanceof CodeSetServiceContext) + return (CodeSetServiceContext) contexts [ i ]; + } + return STANDARD; + } + + /** + * Select the suitable encoding that is defined in the provided profile. + * + * TODO character encoding. Now the encoding can be set, but it is ignored. + * If you take this task, scan 'TODO character encoding' for + * relevant places. + */ + public static CodeSetServiceContext negotiate(IOR.CodeSets_profile profile) + { + if (profile.negotiated != null) + return profile.negotiated; + + CodeSetServiceContext use = new CodeSetServiceContext(); + + use.char_data = + negotiate(profile.narrow, STANDARD.char_data, CharSets_OSF.ISO8859_1); + + use.wide_char_data = + negotiate(profile.wide, STANDARD.wide_char_data, CharSets_OSF.UTF16); + + profile.negotiated = use; + + return use; + } + + /** + * Read the context from the given stream. Does not read the + * code sets id. + */ + public void readContext(AbstractCdrInput input) + { + AbstractCdrInput encap = input.read_encapsulation(); + + char_data = encap.read_ulong(); + wide_char_data = encap.read_ulong(); + } + + /** + * Return a string representation. + */ + public String toString() + { + return " Encoding: narrow " + name(char_data) + ", wide " + + name(wide_char_data) + ". "; + } + + /** + * Write the context to the given stream, including the code + * sets id. + */ + public void write(AbstractCdrOutput output) + { + output.write_ulong(ID); + + AbstractCdrOutput enout = output.createEncapsulation(); + + enout.write_long(char_data); + enout.write_ulong(wide_char_data); + + try + { + enout.close(); + } + catch (IOException ex) + { + InternalError t = new InternalError(); + t.initCause(ex); + throw t; + } + } + + /** + * Negotiate about the character encoding. Prefer our native encoding, + * if no, prefer IORs native encoding, if no, find any encoding, + * supported by both sides, if no, return the specified final decission. + * + * @param profile the component profile in IOR. + * @param our_native our native encoding + * @param final_decission the encoding that must be returned if no + * compromise is found. + * + * @return the resulted encoding. + */ + protected static int negotiate(IOR.CodeSets_profile.CodeSet_component profile, + int our_native, int final_decission + ) + { + // If our and IORs native sets match, use the native set. + if (profile.native_set == our_native) + return our_native; + + // If the native sets do not match, but the IOR says it + // supports our native set, use our native set. + if (profile.conversion != null) + for (int i = 0; i < profile.conversion.length; i++) + { + if (our_native == profile.conversion [ i ]) + return our_native; + } + + // At this point, we suggest to use the IORs native set. + int[] allSupported = CharSets_OSF.getSupportedCharSets(); + + for (int s = 0; s < allSupported.length; s++) + if (allSupported [ s ] == profile.native_set) + return profile.native_set; + + // Any compromise left? + if (profile.conversion != null) + for (int s = 0; s < allSupported.length; s++) + for (int i = 0; i < profile.conversion.length; i++) + if (allSupported [ s ] == profile.conversion [ i ]) + return allSupported [ s ]; + + // Return the CORBA default char encoding. + return final_decission; + } + + /** + * Conveniency method, used in toString() + */ + private String name(int set) + { + return "0x" + Integer.toHexString(set) + " (" + CharSets_OSF.getName(set) + + ") "; + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/ContextHandler.java b/libjava/classpath/gnu/CORBA/GIOP/ContextHandler.java new file mode 100644 index 000000000..77ea20e38 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/ContextHandler.java @@ -0,0 +1,76 @@ +/* ContextHandler.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import org.omg.CORBA.BAD_INV_ORDER; + +/** + * A header, supporting the service contexts. Such header has a context field + * and methods for adding the new contexts. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class ContextHandler +{ + + /** + * Empty array, indicating that no service context is available. + */ + protected static final ServiceContext[] NO_CONTEXT = new ServiceContext[0]; + + /** + * The context data. + */ + public ServiceContext[] service_context = NO_CONTEXT; + + /** + * Add service context to this header. + * + * @param context_to_add context to add. + * @param replace if true, the existing context with this ID is replaced. + * Otherwise, BAD_INV_ORDER is throwsn. + */ + public void addContext(org.omg.IOP.ServiceContext context_to_add, + boolean replace) + throws BAD_INV_ORDER + { + service_context = ServiceContext.add(service_context, context_to_add, + replace); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/ErrorMessage.java b/libjava/classpath/gnu/CORBA/GIOP/ErrorMessage.java new file mode 100644 index 000000000..0bd48dea8 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/ErrorMessage.java @@ -0,0 +1,114 @@ +/* ErrorMessage.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; +import gnu.CORBA.Minor; + +import java.io.IOException; +import java.io.OutputStream; + +import java.net.Socket; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; + +/** + * The error message is sent in response to the message, encoded + * in the unsupported version of the format or otherwise invalid. + * + * The error message consists from the message header only and + * is the same for GIOP 1.0, 1.1, 1.2 and 1.3. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ErrorMessage + extends MessageHeader +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Create a new error message, setting the message field + * to the {@link MESSAGE_ERROR} and the version number to + * the given major and minor values. + */ + public ErrorMessage(gnu.CORBA.Version msg_version) + { + version = msg_version; + message_type = MESSAGE_ERROR; + } + + /** + * Send the error message to the given IOR address. + * + * @param ior the IOR address (host and port, other fields + * are not used). + * + * @param orb the ORB, sending the error message. + */ + public void send(IOR ior, ORB orb) + { + try + { + Socket socket; + + if (orb instanceof OrbFunctional) + socket = ((OrbFunctional) orb).socketFactory.createClientSocket( + ior.Internet.host, ior.Internet.port); + else + socket = new Socket(ior.Internet.host, ior.Internet.port); + + OutputStream socketOutput = socket.getOutputStream(); + write(socketOutput); + socketOutput.close(); + socket.close(); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.Header; + t.initCause(ex); + throw t; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/MessageHeader.java b/libjava/classpath/gnu/CORBA/GIOP/MessageHeader.java new file mode 100644 index 000000000..3137343ed --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/MessageHeader.java @@ -0,0 +1,465 @@ +/* MessageHeader.java -- GIOP message header. + 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.GIOP; + +import gnu.CORBA.Minor; +import gnu.CORBA.Version; +import gnu.CORBA.CDR.BigEndianInputStream; +import gnu.CORBA.CDR.BigEndianOutputStream; +import gnu.CORBA.CDR.LittleEndianInputStream; +import gnu.CORBA.CDR.LittleEndianOutputStream; +import gnu.CORBA.CDR.AbstractDataInput; +import gnu.CORBA.CDR.AbstractDataOutput; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.IDLEntity; + +import java.io.ByteArrayOutputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.util.Arrays; + +/** + * The GIOP message header. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class MessageHeader + implements IDLEntity +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Request message. + */ + public static final byte REQUEST = 0; + + /** + * Reply message + */ + public static final byte REPLY = 1; + + /** + * Cancel request message. + */ + public static final byte CANCEL_REQUEST = 2; + + /** + * Locate request message, used to check the server ability to process + * requests for the object reference. This message is also used to get the + * address where the object reference should be sent. + */ + public static final byte LOCATE_REQUEST = 3; + + /** + * Locate reply message, sent in response to the {@link #LocateRequest} + * message. + */ + public static final byte LOCATE_REPLY = 4; + + /** + * Instruction to close the connection. + */ + public static final byte CLOSE_CONNECTION = 5; + + /** + * Error report. + */ + public static final byte MESSAGE_ERROR = 6; + + /** + * The fragment messge, following the previous message that has more fragments + * flag set. Added in GIOP 1.1 + */ + public static final byte FRAGMENT = 7; + + /** + * This must always be "GIOP". + */ + public static final byte[] MAGIC = new byte[] { 'G', 'I', 'O', 'P' }; + + /** + * The message type names. + */ + protected static String[] types = new String[] { "Request", "Reply", + "Cancel", "Locate request", "Locate reply", "Close connection", "Error", + "Fragment" }; + + /** + * The GIOP version. Initialised to 1.0 . + */ + public Version version; + + /** + * The flags field, introduced since GIOP 1.1. + */ + public byte flags = 0; + + /** + * The message type. + */ + public byte message_type = REQUEST; + + /** + * The message size, excluding the message header. + */ + public int message_size = 0; + + /** + * Create an empty message header, corresponding version 1.0. + */ + public MessageHeader() + { + version = new Version(1, 0); + } + + /** + * Create an empty message header, corresponding the given version. + * + * @param major the major message header version. + * @param minor the minot message header version. + */ + public MessageHeader(int major, int minor) + { + version = new Version(major, minor); + } + + /** + * Checks if the message is encoded in the Big Endian, most significant byte + * first. + */ + public boolean isBigEndian() + { + return (flags & 0x1) == 0; + } + + /** + * Checks if the message is partial, and more subsequent fragments follow. + */ + public boolean moreFragmentsFollow() + { + return (flags & 0x2) != 0; + } + + /** + * Set the encoding to use. + * + * @param use_big_endian if true (default), the Big Endian encoding is used. + * If false, the Little Endian encoding is used. + */ + public void setBigEndian(boolean use_big_endian) + { + if (use_big_endian) + flags = (byte) (flags & ~1); + else + flags = (byte) (flags | 1); + } + + /** + * Get the size of the message header itself. So far, it is always 12 bytes. + */ + public int getHeaderSize() + { + return 12; + } + + /** + * Get the message type as string. + * + * @param type the message type as int (the field {@link message_type}). + * + * @return the message type as string. + */ + public String getTypeString(int type) + { + try + { + return types[type]; + } + catch (ArrayIndexOutOfBoundsException ex) + { + return "unknown type (" + type + ")"; + } + } + + /** + * Creates reply header, matching the message header version number. + * + * @return one of {@link gnu.CORBA.GIOP.v1_0.ReplyHeader}, + * {@link gnu.CORBA.GIOP.v1_2.ReplyHeader}, etc - depending on the version + * number in this header. + */ + public ReplyHeader create_reply_header() + { + if (version.since_inclusive(1, 2)) + return new gnu.CORBA.GIOP.v1_2.ReplyHeader(); + else + return new gnu.CORBA.GIOP.v1_0.ReplyHeader(); + } + + /** + * Creates request header, matching the message header version number. + * + * @return one of {@link gnu.CORBA.GIOP.v1_0.RequestHeader}, + * {@link gnu.CORBA.GIOP.v1_2.RequestHeader}, etc - depending on the version + * number in this header. + */ + public RequestHeader create_request_header() + { + if (version.since_inclusive(1, 2)) + return new gnu.CORBA.GIOP.v1_2.RequestHeader(); + else + return new gnu.CORBA.GIOP.v1_0.RequestHeader(); + } + + /** + * Create the cancel header, matching the message header version number. + */ + public CancelHeader create_cancel_header() + { + return new gnu.CORBA.GIOP.v1_0.CancelHeader(); + } + + /** + * Create the error message. + */ + public ErrorMessage create_error_message() + { + return new ErrorMessage(version); + } + + /** + * Read the header from the stream. + * + * @param istream a stream to read from. + * @throws MARSHAL if this is not a GIOP 1.0 header. + */ + public void read(java.io.InputStream istream) + throws MARSHAL, EOFException + { + try + { + byte[] xMagic = new byte[MAGIC.length]; + int r = istream.read(xMagic); + int minor; + if (! Arrays.equals(xMagic, MAGIC)) + { + CPStringBuilder b = new CPStringBuilder(); + if (r == - 1) + { + b.append("Immediate EOF"); + minor = Minor.EOF; + } + else + { + minor = Minor.Giop; + b.append(r + " bytes: "); + for (int i = 0; i < xMagic.length; i++) + { + b.append(Integer.toHexString(xMagic[i] & 0xFF)); + b.append(' '); + } + } + MARSHAL m = new MARSHAL("Not a GIOP message: " + b); + m.minor = minor; + throw m; + } + + version = Version.read_version(istream); + + AbstractDataInput din; + + flags = (byte) istream.read(); + + // This checks the bit in the byte we have just received. + if (isBigEndian()) + din = new BigEndianInputStream(istream); + else + din = new LittleEndianInputStream(istream); + + message_type = (byte) din.read(); + + message_size = din.readInt(); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.Header; + t.initCause(ex); + throw t; + } + } + + /** + * Get the short string summary of the message. + * + * @return a short message summary. + */ + public String toString() + { + return "GIOP " + version + ", " + (isBigEndian() ? "Big" : "Little") + + " endian, " + getTypeString(message_type) + ", " + message_size + + " bytes. "; + } + + /** + * Write the header to stream. + * + * @param out a stream to write into. + */ + public void write(java.io.OutputStream out) + { + try + { + AbstractDataOutput dout; + + if (isBigEndian()) + dout = new BigEndianOutputStream(out); + else + dout = new LittleEndianOutputStream(out); + + // Write magic sequence. + dout.write(MAGIC); + + // Write version number. + version.write((OutputStream) dout); + dout.write(flags); + dout.write(message_type); + dout.writeInt(message_size); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(ex.getMessage()); + t.minor = Minor.Header; + t.initCause(ex); + throw t; + } + } + + /** + * Read data, followed by the message header. Handle fragmented messages. + * + * @param source the data source to read from. + * @param service the socket on that the time outs are set. Can be null (no + * timeouts are set). + * @param to_read the timeout while reading the message. + * @param to_pause the timeout for pauses between the message parts. + */ + public byte[] readMessage(InputStream source, Socket service, int to_read, + int to_pause) + { + try + { + byte[] r = new byte[message_size]; + + int n = 0; + if (service != null) + service.setSoTimeout(to_read); + + while (n < r.length) + { + n += source.read(r, n, r.length - n); + } + if (service != null) + service.setSoTimeout(to_pause); + + // Read the message remainder if the message is fragmented. + if (moreFragmentsFollow()) + { + ByteArrayOutputStream buffer = new ByteArrayOutputStream( + 2 * r.length); + buffer.write(r); + + if (r.length < 10) + // Increase the buffer size if the default value (size of the + // previous message) is really too small. + r = new byte[1024]; + + MessageHeader h2 = new MessageHeader(); + + do + { + h2.read(source); + + int dn; + + n = 0; + while (n < h2.message_size) + { + dn = source.read(r, 0, h2.message_size - n); + + if (n == 0 && service != null) + service.setSoTimeout(to_read); + + if (n == 0 && version.since_inclusive(1, 2)) + { + // Skip the four byte request id. + buffer.write(r, 4, dn - 4); + } + else + buffer.write(r, 0, dn); + n = +dn; + } + + if (service != null) + service.setSoTimeout(to_pause); + } + while (h2.moreFragmentsFollow()); + return buffer.toByteArray(); + } + else + return r; + } + catch (IOException ioex) + { + MARSHAL m = new MARSHAL("Unable to read the message continuation."); + m.minor = Minor.Header; + m.initCause(ioex); + throw m; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java new file mode 100644 index 000000000..d14482903 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/ReplyHeader.java @@ -0,0 +1,145 @@ +/* ReplyHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; + +/** + * The header of the standard reply. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class ReplyHeader + extends ContextHandler +{ + /** + * Reply status, if no exception occured. + */ + public static final int NO_EXCEPTION = 0; + + /** + * Reply status, user exception. + */ + public static final int USER_EXCEPTION = 1; + + /** + * Reply status, system exception. + */ + 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. + */ + public static final int LOCATION_FORWARD = 3; + + /** + * Reply status, indicating that the target has permanently changed the + * address to the supplied IOR. + */ + public static final int LOCATION_FORWARD_PERM = 4; + + /** + * Reply status, indicating, that the ORB requires to resend the object + * address in the required addressing mode, contained as the reply body. + */ + public static final int NEEDS_ADDRESSING_MODE = 5; + + /** + * The status of this reply, holds one of the reply status constants. + */ + public int reply_status; + + /** + * The Id of request into response of which this reply has been sent. + */ + public int request_id; + + /** + * Return the message status as a string. + */ + public String getStatusString() + { + switch (reply_status) + { + case NO_EXCEPTION: + return "ok"; + + case USER_EXCEPTION: + return "user exception"; + + case SYSTEM_EXCEPTION: + return "system exception"; + + case LOCATION_FORWARD: + return "moved"; + + default: + return null; + } + } + + /** + * Reads the header from the stream. + * + * @param in a stream to read from. + */ + public abstract void read(AbstractCdrInput in); + + /** + * Returns a short string representation. + * + * @return a string representation. + */ + public String toString() + { + String status = getStatusString(); + if (status == null) + status = "status " + reply_status; + return request_id + ", " + status; + } + + /** + * Writes the header to the stream. + * + * @param out a stream to write into. + */ + public abstract void write(AbstractCdrOutput out); +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java new file mode 100644 index 000000000..45997ab3d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/RequestHeader.java @@ -0,0 +1,156 @@ +/* RequestHeader.java -- The GIOP 1.0 request message. + 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.GIOP; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.portable.IDLEntity; + +/** + * The GIOP request message. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class RequestHeader + extends ContextHandler + 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). + */ + private static int freeId = 0x01234567; + + /** + * The operation being invoked (IDL scope name). + */ + public String operation; + + /** + * Identifies the object that is the target of the invocation. + */ + public byte[] object_key; + + /** + * A value identifying the requesting principal. Initialised into a single + * zero byte. + * + * @deprecated by CORBA 2.2. + */ + public byte[] requesting_principal; + + /** + * 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(); + + /** + * If true, the response from the server is expected. + */ + 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. + * + * @return the next free request id. + */ + public static synchronized int getNextId() + { + int f = freeId; + if (freeId == Integer.MAX_VALUE) + freeId = 1; + else + freeId++; + + return f; + } + + /** + * Set if the sender expects any response to this message. + */ + public abstract void setResponseExpected(boolean expected); + + /** + * Return true if response is expected. + */ + public abstract boolean isResponseExpected(); + + /** + * Converts an byte array into hexadecimal string values. Used in various + * toString() methods. + */ + public String bytes(byte[] array) + { + CPStringBuilder b = new CPStringBuilder(); + for (int i = 0; i < array.length; i++) + { + b.append(Integer.toHexString(array[i] & 0xFF)); + b.append(" "); + } + return b.toString(); + } + + /** + * Reads the header from the stream. + * + * @param in a stream to read from. + */ + public abstract void read(AbstractCdrInput in); + + /** + * Return a string representation. + */ + public abstract String toString(); + + /** + * Writes the header to the stream. + * + * @param out a stream to write into. + */ + public abstract void write(AbstractCdrOutput out); + +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java new file mode 100644 index 000000000..673ae0ba9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/ServiceContext.java @@ -0,0 +1,301 @@ +/* ServiceContext.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.portable.IDLEntity; + +/** + * Contains the ORB service data being passed. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ServiceContext + implements IDLEntity +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /* Standard values for the context_id. */ + public static final int TransactionService = 0; + + /** + * Defines code sets, used to encode wide and narrow characters. Required for + * messages with data structures, involving wide characters. + */ + public static final int CodeSets = 1; + + public static final int ChainBypassCheck = 2; + + public static final int ChainBypassInfo = 3; + + public static final int LogicalThreadId = 4; + + public static final int BI_DIR_IIOP = 5; + + public static final int SendingContextRunTime = 6; + + public static final int INVOCATION_POLICIES = 7; + + public static final int FORWARDED_IDENTITY = 8; + + /** + * Contains exception details if exception being transferred is other than + * System or User exception. javax.rmi uses this context to transfer arbitrary + * java exceptions as CORBA value types. + */ + public static final int UnknownExceptionInfo = 9; + + public static final int RTCorbaPriority = 10; + + public static final int RTCorbaPriorityRange = 11; + + public static final int FT_GROUP_VERSION = 12; + + public static final int FT_REQUEST = 13; + + public static final int ExceptionDetailMessage = 14; + + public static final int SecurityAttributeService = 15; + + public static final int ActivityService = 16; + + /** + * 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. + */ + public static ServiceContext read(AbstractCdrInput istream) + { + int id = istream.read_ulong(); + + switch (id) + { + case CodeSetServiceContext.ID: + + CodeSetServiceContext codeset = new CodeSetServiceContext(); + codeset.readContext(istream); + return codeset; + + default: + + ServiceContext ctx = new ServiceContext(); + ctx.context_id = id; + ctx.context_data = istream.read_sequence(); + return ctx; + } + } + + /** + * Read a sequence of contexts from the input stream. + */ + public static ServiceContext[] readSequence(AbstractCdrInput istream) + { + int size = istream.read_long(); + ServiceContext[] value = new gnu.CORBA.GIOP.ServiceContext[size]; + for (int i = 0; i < value.length; i++) + value[i] = read(istream); + return value; + } + + /** + * Write the context values into the stream. + * + * @param ostream a stream to write the data to. + */ + public void write(AbstractCdrOutput ostream) + { + ostream.write_ulong(context_id); + ostream.write_sequence(context_data); + } + + /** + * Write the sequence of contexts into the input stream. + */ + public static void writeSequence(AbstractCdrOutput ostream, ServiceContext[] value) + { + ostream.write_long(value.length); + for (int i = 0; i < value.length; i++) + 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); + } + + /** + * Find context with the given name in the context array without conversions. + */ + public static ServiceContext find(int ctx_name, ServiceContext[] cx) + { + for (int i = 0; i < cx.length; i++) + if (cx[i].context_id == ctx_name) + return cx[i]; + return null; + } + + /** + * Return a string representation. + */ + public String toString() + { + return "ctx " + context_id + ", size " + context_data.length; + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_0/CancelHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_0/CancelHeader.java new file mode 100644 index 000000000..115849223 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_0/CancelHeader.java @@ -0,0 +1,72 @@ +/* CancelHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP.v1_0; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +/** + * The message header for cancelling the request. + * + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class CancelHeader + extends gnu.CORBA.GIOP.CancelHeader +{ + /** + * Read the header. + * + * @param input a stream to read from. + */ + public void read(InputStream input) + { + request_id = input.read_ulong(); + } + + /** + * Write the header. + * + * @param output a stream to write to. + */ + public void write(OutputStream output) + { + output.write_ulong(request_id); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_0/ReplyHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_0/ReplyHeader.java new file mode 100644 index 000000000..dcb00c0eb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_0/ReplyHeader.java @@ -0,0 +1,141 @@ +/* ReplyHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP.v1_0; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.GIOP.ServiceContext; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +import gnu.java.lang.CPStringBuilder; + +/** + * The header of the standard reply. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ReplyHeader + extends gnu.CORBA.GIOP.ReplyHeader +{ + /** + * Return the message status as a string. + */ + public String getStatusString() + { + switch (reply_status) + { + case NO_EXCEPTION : + return "ok"; + + case USER_EXCEPTION : + return "user exception"; + + case SYSTEM_EXCEPTION : + return "system exception"; + + case LOCATION_FORWARD : + return "moved"; + + default : + return null; + } + } + + /** + * Get the string representation of all included contexts. + */ + public String contexts() + { + CPStringBuilder b = new CPStringBuilder(); + for (int i = 0; i < service_context.length; i++) + { + b.append(service_context [ i ].toString()); + b.append(' '); + } + return b.toString(); + } + + /** + * Reads the header from the stream. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param in a stream to read from. + */ + + public void read(AbstractCdrInput in) + { + service_context = ServiceContext.readSequence(in); + request_id = in.read_ulong(); + reply_status = in.read_ulong(); + + in.setCodeSet(CodeSetServiceContext.find(service_context)); + } + + /** + * Returns a short string representation. + * + * @return a string representation. + */ + public String toString() + { + String status = getStatusString(); + if (status == null) + status = "status " + reply_status; + return request_id + ", " + status + " " + contexts(); + } + + /** + * Writes the header to the stream. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param out a stream to write into. + */ + public void write(AbstractCdrOutput out) + { + ServiceContext.writeSequence(out, service_context); + out.write_ulong(request_id); + out.write_ulong(reply_status); + + out.setCodeSet(CodeSetServiceContext.find(service_context)); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java new file mode 100644 index 000000000..d2bea9d88 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_0/RequestHeader.java @@ -0,0 +1,159 @@ +/* RequestHeader.java -- The GIOP 1.0 request message. + 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.GIOP.v1_0; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.GIOP.ServiceContext; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.portable.IDLEntity; + +/** + * The GIOP 1.0 request message. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RequestHeader + extends gnu.CORBA.GIOP.RequestHeader + implements IDLEntity +{ + /** + * Creates an empty request header, setting requesting principal + * to byte[] { 'P' }. + */ + public RequestHeader() + { + requesting_principal = new byte[] { 'P' }; + } + + /** + * Set if the sender expects any response to this message. + */ + public void setResponseExpected(boolean expected) + { + response_expected = expected; + } + + /** + * Return true if response is expected. + */ + public boolean isResponseExpected() + { + return response_expected; + } + + public String bytes(byte[] array) + { + CPStringBuilder b = new CPStringBuilder(); + for (int i = 0; i < array.length; i++) + { + b.append(Integer.toHexString(array [ i ] & 0xFF)); + b.append(" "); + } + return b.toString(); + } + + /** + * Get the string representation of all included contexts. + */ + public String contexts() + { + CPStringBuilder b = new CPStringBuilder(); + for (int i = 0; i < service_context.length; i++) + { + b.append(service_context [ i ].toString()); + b.append(' '); + } + return b.toString(); + } + + /** + * Reads the header from the stream. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param in a stream to read from. + */ + public void read(AbstractCdrInput in) + { + service_context = ServiceContext.readSequence(in); + request_id = in.read_ulong(); + response_expected = in.read_boolean(); + object_key = in.read_sequence(); + operation = in.read_string(); + requesting_principal = in.read_sequence(); + + in.setCodeSet(CodeSetServiceContext.find(service_context)); + } + + /** + * Return a string representation. + */ + public String toString() + { + return "Request " + request_id + ", call '" + operation + "' on " + + bytes(object_key) + ", " + + (response_expected ? "wait response" : "one way") + ", from " + + bytes(requesting_principal) + contexts(); + } + + /** + * Writes the header to the stream. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param out a stream to write into. + */ + public void write(AbstractCdrOutput out) + { + ServiceContext.writeSequence(out, service_context); + out.write_ulong(request_id); + out.write_boolean(response_expected); + out.write_sequence(object_key); + out.write_string(operation); + out.write_sequence(requesting_principal); + + out.setCodeSet(CodeSetServiceContext.find(service_context)); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_2/ReplyHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_2/ReplyHeader.java new file mode 100644 index 000000000..3fc1541d9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_2/ReplyHeader.java @@ -0,0 +1,118 @@ +/* ReplyHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP.v1_2; + +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.GIOP.ServiceContext; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +/** + * GIOP 1.2 reply header. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ReplyHeader + extends gnu.CORBA.GIOP.v1_0.ReplyHeader +{ + /** + * Adds the standard encoding context. + */ + public ReplyHeader() + { + service_context = new ServiceContext[] { CodeSetServiceContext.STANDARD }; + } + + /** + * Return the message status as a string. + */ + public String getStatusString() + { + String s = super.getStatusString(); + if (s != null) + return s; + switch (reply_status) + { + case LOCATION_FORWARD_PERM : + return "moved permanently"; + + case NEEDS_ADDRESSING_MODE : + return "the alternative addressing mode required"; + + default : + return null; + } + } + + /** + * Reads the header from the stream. + * The fields go in different order than in the previous GIOP versions. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param in a stream to read from. + */ + public void read(AbstractCdrInput in) + { + request_id = in.read_ulong(); + reply_status = in.read_ulong(); + service_context = gnu.CORBA.GIOP.ServiceContext.readSequence(in); + + in.setCodeSet(CodeSetServiceContext.find(service_context)); + } + + /** + * Writes the header to the stream. + * The fields go in different order than in the previous GIOP versions. + * + * Sets the code set of this stream to + * the code set, specfied in the header. + * + * @param out a stream to write into. + */ + public void write(AbstractCdrOutput out) + { + out.write_ulong(request_id); + out.write_ulong(reply_status); + gnu.CORBA.GIOP.ServiceContext.writeSequence(out, service_context); + + out.setCodeSet(CodeSetServiceContext.find(service_context)); + } +} diff --git a/libjava/classpath/gnu/CORBA/GIOP/v1_2/RequestHeader.java b/libjava/classpath/gnu/CORBA/GIOP/v1_2/RequestHeader.java new file mode 100644 index 000000000..d083536a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GIOP/v1_2/RequestHeader.java @@ -0,0 +1,222 @@ +/* RequestHeader.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.GIOP.v1_2; + +import gnu.CORBA.Minor; +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.GIOP.ServiceContext; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +import java.io.IOException; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; + +/** + * The GIOP 1.2 request header. The GIOP 1.1 request header + * is the same as GIOP 1.0 request header, if taking the + * alignment into consideration. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RequestHeader + extends gnu.CORBA.GIOP.v1_0.RequestHeader +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Indicates that the object is addressed by the object key. + */ + public static final short KeyAddr = 0; + + /** + * Indicates that the object is addressed by the IOP tagged profile. + */ + public static final short ProfileAddr = 1; + + /** + * Indicates that the objec is addressed by IOR addressing info. + */ + public static final short ReferenceAddr = 2; + + /** + * The response flags of the header. By default, the flags are initialised + * by value 0x3 (response expected). + */ + public byte response_flags = 3; + + /** + * The used addressing method. + */ + public short AddressingDisposition; + + /** + * Adds the standard encoding context. + */ + public RequestHeader() + { + service_context = new ServiceContext[] { CodeSetServiceContext.STANDARD }; + } + + /** + * Set if the sender expects any response to this message. + * Clears or sets the 2 lower bits of flags + * (0 - not expected, 0x3 - expected). + */ + public void setResponseExpected(boolean expected) + { + response_expected = expected; + + if (expected) + response_flags = (byte) (response_flags | 0x3); + else + response_flags = (byte) (response_flags & (~0x3)); + } + + /** + * Return true if response is expected. + * + * @return true if the two lowest bits of the flags are set or + * the response expected is explicitly set to true. + */ + public boolean isResponseExpected() + { + return response_expected || ((response_flags & 0x3) == 0x3); + } + + /** + * Read the header from the given stream. + * + * @param in a stream to read from. + */ + public void read(AbstractCdrInput in) + { + try + { + request_id = in.read_ulong(); + response_flags = (byte) in.read(); + + // Skip 3 reserved octets: + in.skip(3); + + // Read target address. + AddressingDisposition = in.read_ushort(); + + switch (AddressingDisposition) + { + case KeyAddr : + object_key = in.read_sequence(); + break; + + // TODO FIXME add other addressing methods. + case ProfileAddr : + throw new NO_IMPLEMENT("Object addressing by IOP tagged profile"); + + case ReferenceAddr : + throw new NO_IMPLEMENT("Object addressing by IOR addressing info"); + + default : + MARSHAL m = new MARSHAL("Unknow addressing method in request, " + + AddressingDisposition + ); + m.minor = Minor.UnsupportedAddressing; + throw m; + } + + operation = in.read_string(); + service_context = gnu.CORBA.GIOP.ServiceContext.readSequence(in); + + // No requesting principal in this new format. + in.setCodeSet(CodeSetServiceContext.find(service_context)); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.Header; + t.initCause(ex); + throw t; + } + } + + /** + * Return a string representation. + */ + public String toString() + { + return "Request " + request_id + ", call '" + operation + "' on " + + bytes(object_key) + ", " + + (response_expected ? "wait response" : "one way") + + " addressed by " + " method " + AddressingDisposition + "." + + contexts(); + } + + /** + * Write the header to the given stream. + * + * @param out a stream to write into. + */ + public void write(AbstractCdrOutput out) + { + out.write_ulong(request_id); + + out.write(response_flags); + + // Skip 3 reserved octets: + out.write(0); + out.write(0); + out.write(0); + + // Write addressing disposition from IOR. + // TODO FIXME add other addressing methods. + out.write_ushort(KeyAddr); + + out.write_sequence(object_key); + + out.write_string(operation); + + ServiceContext.writeSequence(out, service_context); + + // No requesting principal in this new format. + out.setCodeSet(CodeSetServiceContext.find(service_context)); + } +} diff --git a/libjava/classpath/gnu/CORBA/GeneralHolder.java b/libjava/classpath/gnu/CORBA/GeneralHolder.java new file mode 100644 index 000000000..d4550bf68 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/GeneralHolder.java @@ -0,0 +1,178 @@ +/* universalStreamable.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +import java.io.IOException; + +/** + * This class holds the abstract binary data array of the Streamable + * being stored. It is used to insert and extract into {@link Any} objects + * that have no holder, but have the helper classes. + * Encoding/decoding then must be performed by the helper. This class is + * defined as package private because it is not idiot proof and + * must be used with care. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class GeneralHolder + implements Streamable +{ + /** + * The binary data, stored inside this holder. + */ + private BufferedCdrOutput value = new BufferedCdrOutput(); + + /** + * Create the universal holder that uses the given buffer to store the data. + */ + public GeneralHolder(BufferedCdrOutput buffer) + { + value = buffer; + } + + /** + * Reads into the internal buffer till the end of stream is + * reached. No alignment operations are performed. This operation + * normally reads from the stream, where the single value, + * stored using {@link #_write}, is written. + * + * @throws MARSHALL, if the IOException is thrown during the + * stream operation. + */ + public void _read(InputStream input) + { + try + { + if (input instanceof BufferredCdrInput) + { + BufferredCdrInput b = (BufferredCdrInput) input; + value.write(b.buffer.getBuffer()); + } + else + { + int c; + + do + { + c = input.read(); + if (c >= 0) + value.write(c); + } + while (c >= 0); + } + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.Any; + t.initCause(ex); + throw t; + } + } + + /** + * The type is not known and cannot be returned. + * + * @throws BAD_OPERATION, always. + */ + public TypeCode _type() + { + BAD_OPERATION bad = new BAD_OPERATION(); + bad.minor = Minor.Inappropriate; + throw bad; + } + + /** + * Writes the binary data being stored into the given output + * stream. This operation supposes that the current stream + * position is 0 or satisfies the required alignments anyway. + * + * @throws MARSHAL if the IOExeption is thrown when writing the + * byte array. + */ + public void _write(OutputStream output) + { + try + { + value.buffer.writeTo(output); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.Any; + t.initCause(ex); + throw t; + } + } + + /** + * Get the input stream that reads the fields of the stored value. + */ + InputStream getInputStream() + { + return value.create_input_stream(); + } + + /** + * Clone. + */ + public GeneralHolder Clone() + { + try + { + BufferedCdrOutput nb = new BufferedCdrOutput(value.buffer.size()); + value.buffer.writeTo(nb); + return new GeneralHolder(nb); + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/HolderLocator.java b/libjava/classpath/gnu/CORBA/HolderLocator.java new file mode 100644 index 000000000..edd4d2cf7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/HolderLocator.java @@ -0,0 +1,184 @@ +/* HolderLocator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.AnyHolder; +import org.omg.CORBA.AnySeqHolder; +import org.omg.CORBA.BooleanHolder; +import org.omg.CORBA.BooleanSeqHolder; +import org.omg.CORBA.CharHolder; +import org.omg.CORBA.CharSeqHolder; +import org.omg.CORBA.DoubleHolder; +import org.omg.CORBA.DoubleSeqHolder; +import org.omg.CORBA.FixedHolder; +import org.omg.CORBA.FloatHolder; +import org.omg.CORBA.FloatSeqHolder; +import org.omg.CORBA.IntHolder; +import org.omg.CORBA.LongHolder; +import org.omg.CORBA.LongLongSeqHolder; +import org.omg.CORBA.LongSeqHolder; +import org.omg.CORBA.OctetSeqHolder; +import org.omg.CORBA.PrincipalHolder; +import org.omg.CORBA.ShortHolder; +import org.omg.CORBA.ShortSeqHolder; +import org.omg.CORBA.StringHolder; +import org.omg.CORBA.StringSeqHolder; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodeHolder; +import org.omg.CORBA.ULongLongSeqHolder; +import org.omg.CORBA.ULongSeqHolder; +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 final_type. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class HolderLocator +{ + /** + * 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; + 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 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 final_type. The holder is created with a parameterless + * constructor. + */ + public static Streamable createHolder(TypeCode t) + { + try + { + int kind = t.kind().value(); + int componentKind; + + Streamable holder = null; + + 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; + } + } + catch (Exception ex) + { + throw new Unexpected(ex); + } + + try + { + Object ox = ObjectCreator.createObject(t.id(), "Holder"); + return (Streamable) ox; + } + catch (Exception ex) + { + return null; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/IOR.java b/libjava/classpath/gnu/CORBA/IOR.java new file mode 100644 index 000000000..1a476b094 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/IOR.java @@ -0,0 +1,824 @@ +/* IOR.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.GIOP.CharSets_OSF; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +import gnu.java.lang.CPStringBuilder; + +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; +import java.util.Arrays; +import java.util.zip.Adler32; + +/** + * 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()}. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * + * @see org.mog.CORBA.Object.object_to_string(Object forObject) + * @see string_to_object(String IOR) + */ +public class IOR +{ + /** + * 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. + */ + public static class CodeSet_component + { + /** + * The conversion code sets. + */ + public int[] conversion; + + /** + * The native code set. + */ + public int native_set; + + /** + * Read from the CDR stream. + */ + public void read(org.omg.CORBA.portable.InputStream in) + { + native_set = in.read_ulong(); + conversion = ULongSeqHelper.read(in); + } + + /** + * Get a string representation. + */ + public String toString() + { + CPStringBuilder b = new CPStringBuilder(); + b.append("native " + name(native_set)); + if (conversion != null && conversion.length > 0) + { + b.append(" conversion "); + for (int i = 0; i < conversion.length; i++) + { + b.append(name(conversion[i])); + b.append(' '); + } + } + b.append(' '); + return b.toString(); + } + + /** + * Get a better formatted multiline string representation. + */ + public String toStringFormatted() + { + CPStringBuilder b = new CPStringBuilder(); + b.append("\n Native set " + name(native_set)); + if (conversion != null && conversion.length > 0) + { + b.append("\n Other supported sets:\n "); + for (int i = 0; i < conversion.length; i++) + { + b.append(name(conversion[i])); + b.append(' '); + } + } + b.append("\n"); + return b.toString(); + } + + + /** + * Write into CDR stream. + */ + public void write(org.omg.CORBA.portable.OutputStream out) + { + out.write_long(native_set); + ULongSeqHelper.write(out, conversion); + } + + private String name(int set) + { + return "0x" + Integer.toHexString(set) + " (" + + CharSets_OSF.getName(set) + ") "; + } + } + + /** + * The agreed tag for the Codesets profile. + */ + public static final int TAG_CODE_SETS = 1; + + /** + * Information about narrow character encoding (TCS-C). + */ + public CodeSet_component narrow = new CodeSet_component(); + + /** + * About wide character encoding (TCS-W). + */ + public CodeSet_component wide = new CodeSet_component(); + + /** + * The negotiated coding result for this IOR. Saves time, requred for + * negotiation computations. + */ + public CodeSetServiceContext negotiated; + + /** + * Read the code set profile information from the given input stream. + * + * @param profile a stream to read from. + */ + public void read(AbstractCdrInput profile) + { + BufferredCdrInput encapsulation = profile.read_encapsulation(); + narrow.read(encapsulation); + wide.read(encapsulation); + } + + /** + * Returns a string representation. + */ + public String toString() + { + return "Narrow char: " + narrow + ", Wide char: " + wide; + } + + /** + * Write the code set profile information into the given input stream. + * + * @param profile a stream to write into. + */ + public void write(AbstractCdrOutput profile) + { + AbstractCdrOutput encapsulation = profile.createEncapsulation(); + narrow.write(encapsulation); + wide.write(encapsulation); + try + { + encapsulation.close(); + } + catch (IOException ex) + { + throw new InternalError(); + } + } + } + + /** + * The internet profile. + */ + public class Internet_profile + { + /** + * The agreed tag for the Internet profile. + */ + public static final int TAG_INTERNET_IOP = 0; + + /** + * The host. + */ + public String host; + + /** + * The IIOP version (initialised to 1.2 by default). + */ + public Version version = new Version(1, 2); + + /** + * The port. + */ + 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() + { + CPStringBuilder b = new CPStringBuilder(); + b.append(host); + b.append(":"); + b.append(port); + 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(AbstractCdrOutput out) + { + try + { + // Need to write the Internet profile into the separate + // stream as we must know the size in advance. + AbstractCdrOutput 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.minor = Minor.IOR; + m.initCause(e); + throw m; + } + } + } + + /** + * The standard minor code, indicating that the string to object converstio + * has failed due non specific reasons. + */ + public static final int FAILED = 10; + + /** + * The internet profile of this IOR. + */ + public Internet_profile Internet = new Internet_profile(); + + /** + * The object repository Id. + */ + public String Id; + + /** + * The object key. + */ + public byte[] key; + + /** + * All tagged profiles of this IOR, except the separately defined Internet + * profile. + */ + ArrayList profiles = new ArrayList(); + + /** + * 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. + */ + public IOR() + { + } + + /** + * Parse the provided stringifed reference. + * + * @param stringified_reference in the form of IOR:nnnnnn..... + * + * @return the parsed IOR + * + * @throws BAD_PARAM, minor code 10, if the IOR cannot be parsed. + * + * TODO corballoc and other alternative formats. + */ + public static IOR parse(String stringified_reference) + throws BAD_PARAM + { + try + { + if (!stringified_reference.startsWith("IOR:")) + throw new BAD_PARAM("The string refernce must start with IOR:", + FAILED, CompletionStatus.COMPLETED_NO); + + IOR r = new IOR(); + + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + String x = stringified_reference; + x = x.substring(x.indexOf(":") + 1); + + char cx; + + for (int i = 0; i < x.length(); i = i + 2) + { + cx = (char) Integer.parseInt(x.substring(i, i + 2), 16); + buf.write(cx); + } + + BufferredCdrInput cdr = new BufferredCdrInput(buf.toByteArray()); + + r._read(cdr); + return r; + } + catch (Exception ex) + { + ex.printStackTrace(); + throw new BAD_PARAM(ex + " while parsing " + stringified_reference, + FAILED, CompletionStatus.COMPLETED_NO); + } + } + + /** + * Read the IOR from the provided input stream. + * + * @param c a stream to read from. + * @throws IOException if the stream throws it. + */ + public void _read(AbstractCdrInput c) + throws IOException, BAD_PARAM + { + int endian; + + endian = c.read_long(); + if (endian != 0) + { + Big_Endian = false; + c.setBigEndian(false); + } + _read_no_endian(c); + } + + /** + * 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). + * + * Id is checked for null in AbstractCdrInput 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(AbstractCdrInput c) + throws IOException, BAD_PARAM + { + Id = c.read_string(); + + int n_profiles = c.read_long(); + + if (n_profiles == 0) + { + Id = null; + Internet = null; + return; + } + + for (int i = 0; i < n_profiles; i++) + { + int tag = c.read_long(); + BufferredCdrInput profile = c.read_encapsulation(); + + if (tag == Internet_profile.TAG_INTERNET_IOP) + { + Internet = new Internet_profile(); + Internet.version = Version.read_version(profile); + Internet.host = profile.read_string(); + Internet.port = profile.gnu_read_ushort(); + + key = profile.read_sequence(); + + // Read tagged components. + int n_components = 0; + + try + { + if (Internet.version.since_inclusive(1, 1)) + n_components = profile.read_long(); + + for (int t = 0; t < n_components; t++) + { + int ctag = profile.read_long(); + + if (ctag == CodeSets_profile.TAG_CODE_SETS) + { + 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); + } + } + } + catch (Unexpected ex) + { + 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. + */ + public void _write(AbstractCdrOutput out) + { + // Always use Big Endian. + out.write(0); + _write_no_endian(out); + } + + /** + * 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). + */ + public static void write_null(AbstractCdrOutput out) + { + // Empty Id string. + out.write_string(""); + + // Empty set of profiles. + out.write_long(0); + } + + /** + * 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(AbstractCdrOutput out) + { + // Write repository id. + out.write_string(Id); + + out.write_long(1 + profiles.size()); + + // Write the Internet profile. + out.write_long(Internet_profile.TAG_INTERNET_IOP); + Internet.write(out); + + // Write other profiles. + TaggedProfile tp; + + for (int i = 0; i < profiles.size(); i++) + { + tp = (TaggedProfile) profiles.get(i); + TaggedProfileHelper.write(out, tp); + } + } + + /** + * Returns a human readable string representation of this IOR object. + */ + public String toString() + { + CPStringBuilder b = new CPStringBuilder(); + b.append(Id); + b.append(" at "); + b.append(Internet); + + if (!Big_Endian) + b.append(" (Little endian) "); + + b.append(" Key "); + + for (int i = 0; i < key.length; i++) + { + b.append(Integer.toHexString(key[i] & 0xFF)); + } + + b.append(" "); + b.append(Internet.CodeSets); + + return b.toString(); + } + + /** + * Returns a multiline formatted human readable string representation of + * this IOR object. + */ + public String toStringFormatted() + { + CPStringBuilder b = new CPStringBuilder(); + b.append("\nObject Id:\n "); + b.append(Id); + b.append("\nObject is accessible at:\n "); + b.append(Internet); + + if (Big_Endian) + b.append("\n Big endian encoding"); + else + b.append("\n Little endian encoding."); + + b.append("\nObject Key\n "); + + for (int i = 0; i < key.length; i++) + { + b.append(Integer.toHexString(key[i] & 0xFF)); + } + + b.append("\nSupported code sets:"); + b.append("\n Wide:"); + b.append(Internet.CodeSets.wide.toStringFormatted()); + b.append(" Narrow:"); + b.append(Internet.CodeSets.wide.toStringFormatted()); + + return b.toString(); + } + + /** + * Returs a stringified reference. + * + * @return a newly constructed stringified reference. + */ + public String toStringifiedReference() + { + BufferedCdrOutput out = new BufferedCdrOutput(); + + _write(out); + + CPStringBuilder b = new CPStringBuilder("IOR:"); + + byte[] binary = out.buffer.toByteArray(); + String s; + + for (int i = 0; i < binary.length; i++) + { + s = Integer.toHexString(binary[i] & 0xFF); + if (s.length() == 1) + b.append('0'); + b.append(s); + } + + 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) + { + BufferredCdrInput in = new BufferredCdrInput(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]; + + BufferedCdrOutput out = new BufferedCdrOutput(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); + } + + /** + * Checks for equality. + */ + public boolean equals(Object x) + { + if (x instanceof IOR) + { + boolean keys; + boolean hosts = true; + + IOR other = (IOR) x; + + if (Internet==null || other.Internet==null) + return Internet == other.Internet; + + if (key != null && other.key != null) + keys = Arrays.equals(key, other.key); + else + keys = key == other.key; + + if (Internet != null && Internet.host != null) + if (other.Internet != null && other.Internet.host != null) + hosts = other.Internet.host.equals(Internet.host); + + return keys & hosts && Internet.port==other.Internet.port; + } + else + return false; + } + + /** + * Get the hashcode of this IOR. + */ + public int hashCode() + { + Adler32 adler = new Adler32(); + if (key != null) + adler.update(key); + if (Internet != null) + { + if (Internet.host != null) + adler.update(Internet.host.getBytes()); + adler.update(Internet.port); + } + return (int) adler.getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java new file mode 100644 index 000000000..783e321d7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ClientRequestInterceptors.java @@ -0,0 +1,139 @@ +/* ClientRequestInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.PortableInterceptor.ClientRequestInfo; +import org.omg.PortableInterceptor.ClientRequestInterceptor; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; + +/** + * A block of the all registered ClientRequest interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ClientRequestInterceptors + implements ClientRequestInterceptorOperations +{ + /** + * The array of all registered ClientRequest interceptors. + */ + private final ClientRequestInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public ClientRequestInterceptors(Registrator registrator) + { + interceptors = registrator.getClientRequestInterceptors(); + } + + /** @inheritDoc */ + public void receive_exception(ClientRequestInfo info) + throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_exception(info); + } + } + + /** @inheritDoc */ + public void receive_other(ClientRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_other(info); + } + } + + /** @inheritDoc */ + public void receive_reply(ClientRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_reply(info); + } + } + + /** @inheritDoc */ + public void send_poll(ClientRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_poll(info); + } + } + + /** @inheritDoc */ + public void send_request(ClientRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_request(info); + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java b/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java new file mode 100644 index 000000000..a250ceaa1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ForwardRequestHolder.java @@ -0,0 +1,106 @@ +/* ForwardRequestHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ForwardRequestHelper; + +/** + * A holder for the exception {@link ForwardRequest}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ForwardRequestHolder implements Streamable +{ + /** + * The stored ForwardRequest value. + */ + public ForwardRequest value; + + /** + * Create the unitialised instance, leaving the value field with default + * <code>null</code> value. + */ + public ForwardRequestHolder() + { + } + + /** + * Create the initialised instance. + * + * @param initialValue the value that will be assigned to the + * <code>value</code> field. + */ + public ForwardRequestHolder(ForwardRequest initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = ForwardRequestHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + ForwardRequestHelper.write(output, value); + } + + /** + * Get the typecode of the ForwardRequest. + */ + public TypeCode _type() + { + return ForwardRequestHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java new file mode 100644 index 000000000..67474c173 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/IORInterceptors.java @@ -0,0 +1,189 @@ +/* IORInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.OMGVMCID; +import org.omg.PortableInterceptor.IORInfo; +import org.omg.PortableInterceptor.IORInterceptor; +import org.omg.PortableInterceptor.IORInterceptor_3_0Operations; +import org.omg.PortableInterceptor.ObjectReferenceTemplate; + +/** + * A block of the all registered IOR interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class IORInterceptors implements IORInterceptor_3_0Operations +{ + /** + * The array of all registered IOR interceptors. + */ + private final IORInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public IORInterceptors(Registrator registrator) + { + interceptors = registrator.getIORInterceptors(); + } + + /** + * Call this method for all registered interceptors. + */ + public void establish_components(IORInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].establish_components(info); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } + + /** + * Call this method for all registered CORBA 3.0 interceptors. + */ + public void adapter_manager_state_changed(int adapterManagerId, short adapterState) + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + if (interceptors[i] instanceof IORInterceptor_3_0Operations) + { + ((IORInterceptor_3_0Operations) interceptors[i]). + adapter_manager_state_changed(adapterManagerId, adapterState); + } + } + catch (Exception exc) + { + OBJ_ADAPTER oa = new OBJ_ADAPTER("components_established failed"); + oa.initCause(exc); + oa.minor = 6 | OMGVMCID.value; + throw oa; + } + } + } + + /** + * Call this method for all registered CORBA 3.0 interceptors. + */ + public void adapter_state_changed(ObjectReferenceTemplate[] adapters, short adaptersState) + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + if (interceptors[i] instanceof IORInterceptor_3_0Operations) + { + ((IORInterceptor_3_0Operations) interceptors[i]). + adapter_state_changed(adapters, adaptersState); + } + } + catch (Exception exc) + { + OBJ_ADAPTER oa = new OBJ_ADAPTER("components_established failed"); + oa.initCause(exc); + oa.minor = 6 | OMGVMCID.value; + throw oa; + } + } + } + + /** + * Call this method for all registered CORBA 3.0 interceptors. + * + * @throws OBJ_ADAPTER minor 6 on any failure (as defined by OMG specs). + */ + public void components_established(IORInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + if (interceptors[i] instanceof IORInterceptor_3_0Operations) + { + ((IORInterceptor_3_0Operations) interceptors[i]). + components_established(info); + } + } + catch (Exception exc) + { + OBJ_ADAPTER oa = new OBJ_ADAPTER("components_established failed"); + oa.initCause(exc); + oa.minor = 6 | OMGVMCID.value; + throw oa; + } + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java b/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java new file mode 100644 index 000000000..23ae54a10 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/Registrator.java @@ -0,0 +1,472 @@ +/* Registrator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.Poa.ORB_1_4; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.gnuCodecFactory; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.Object; +import org.omg.IOP.CodecFactory; +import org.omg.PortableInterceptor.ClientRequestInterceptor; +import org.omg.PortableInterceptor.IORInterceptor; +import org.omg.PortableInterceptor.Interceptor; +import org.omg.PortableInterceptor.ORBInitInfo; +import org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName; +import org.omg.PortableInterceptor.ORBInitInfoPackage.InvalidName; +import org.omg.PortableInterceptor.ORBInitializer; +import org.omg.PortableInterceptor.ORBInitializerOperations; +import org.omg.PortableInterceptor.PolicyFactory; +import org.omg.PortableInterceptor.ServerRequestInterceptor; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +/** + * Collects interceptors, references and factories into arrays during + * registration. As the class is security sensitive, the most of the fields are + * private. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Registrator extends LocalObject implements ORBInitInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The agreed properties prefix. + */ + public static final String m_prefix = + "org.omg.PortableInterceptor.ORBInitializerClass."; + + /** + * The initialization - time server request interceptors. + */ + private ArrayList m_server = new ArrayList(); + + /** + * The initialization - time client request interceptors. + */ + private ArrayList m_client = new ArrayList(); + + /** + * The initialization - time ior interceptors. + */ + private ArrayList m_ior = new ArrayList(); + + /** + * The policy factories. + */ + public Hashtable m_policyFactories = new Hashtable(); + + /** + * The registered references. To avoid exposing the ORB's references map, the + * are added by ORB from inside the ORB code. The ORB is responsible for + * taking them from this field between pre_init and post_init. + */ + public TreeMap m_references = new TreeMap(); + + /** + * The initializers. + */ + public ArrayList m_initializers = new ArrayList(); + + /** + * The ORB being intialised. + */ + final ORB_1_4 orb; + + /** + * The argument string array, passed to ORB.init. + */ + final String[] m_args; + + /** + * The codec factory. + */ + final gnuCodecFactory m_codecFactory; + + /** + * Create the interceptor collection from the given properties, using the + * agreed naming convention. + * + * @param an_orb the ORB being initialised. + * @param props the cumulated set of properties where the orb initializer + * pattern is searched. + * @param an_args the argument string array, passed to ORB.init. + */ + public Registrator(ORB_1_4 an_orb, Properties props, String[] an_args) + { + orb = an_orb; + m_args = an_args; + m_codecFactory = new gnuCodecFactory(orb); + checkProperties(props); + checkProperties(System.getProperties()); + checkFile("user.home", null); + checkFile("java.home", "lib"); + } + + /** + * Scan the given properties for the possible interceptors. + */ + private void checkProperties(Properties props) + { + if (props == null) + { + return; + } + + Enumeration names = props.propertyNames(); + java.lang.Object key; + String sk; + + while (names.hasMoreElements()) + { + key = names.nextElement(); + if (key != null) + { + sk = key.toString(); + if (sk.startsWith(m_prefix)) + { + try + { + String cn = sk.substring(m_prefix.length()); + Class iClass = ObjectCreator.forName(cn); + + ORBInitializer initializer = + (ORBInitializer) iClass.newInstance(); + m_initializers.add(initializer); + } + catch (Exception exc) + { + // OMG states we should not throw an exception, but + // this will help the user to detect his error + // in initialiser properties. Should never print during + // normal run. + System.err.println(sk + " failed"); + } + } + } + } + } + + /** + * Check if the property is defined in the existsting file orb.properties. + */ + private void checkFile(String dir, String subdir) + { + try + { + File f = new File(dir); + if (!f.exists()) + { + return; + } + + if (subdir != null) + { + f = new File(f, subdir); + } + f = new File(f, "orb.properties"); + + if (!f.exists()) + { + return; + } + + Properties p = new Properties(); + p.load(new BufferedInputStream(new FileInputStream(f))); + + checkProperties(p); + } + catch (IOException ex) + { + } + } + + /** + * Called by ORB as a pre_init for all initializers. + */ + public void pre_init() + { + Iterator iter = m_initializers.iterator(); + while (iter.hasNext()) + { + ORBInitializerOperations initializer = + (ORBInitializerOperations) iter.next(); + initializer.pre_init(this); + } + } + + /** + * Get the map of the registered references. The ORB calls this method to + * import the references into its references map. + */ + public Map getRegisteredReferences() + { + return m_references; + } + + /** + * Called by ORB as a post-init for all initializers. After this call, the + * interceptor sets are fixed and redundant information is discarded. + */ + public void post_init() + { + Iterator iter = m_initializers.iterator(); + while (iter.hasNext()) + { + ORBInitializerOperations initializer = + (ORBInitializerOperations) iter.next(); + initializer.post_init(this); + } + } + + public ServerRequestInterceptor[] getServerRequestInterceptors() + { + ServerRequestInterceptor[] iServer = + new ServerRequestInterceptor[ m_server.size() ]; + for (int i = 0; i < iServer.length; i++) + { + iServer [ i ] = (ServerRequestInterceptor) m_server.get(i); + } + return iServer; + } + + public ClientRequestInterceptor[] getClientRequestInterceptors() + { + ClientRequestInterceptor[] iClient = + new ClientRequestInterceptor[ m_client.size() ]; + for (int i = 0; i < iClient.length; i++) + { + iClient [ i ] = (ClientRequestInterceptor) m_client.get(i); + } + return iClient; + } + + public IORInterceptor[] getIORInterceptors() + { + IORInterceptor[] iIor = new IORInterceptor[ m_ior.size() ]; + for (int i = 0; i < iIor.length; i++) + { + iIor [ i ] = (IORInterceptor) m_ior.get(i); + } + return iIor; + } + + public void add_client_request_interceptor( + ClientRequestInterceptor interceptor + ) throws DuplicateName + { + add(m_client, interceptor); + } + + public void add_ior_interceptor(IORInterceptor interceptor) + throws DuplicateName + { + add(m_ior, interceptor); + } + + public void add_server_request_interceptor( + ServerRequestInterceptor interceptor + ) throws DuplicateName + { + add(m_server, interceptor); + } + + /** + * Allocate a new slot for request - specific records. + */ + public int allocate_slot_id() + { + return orb.icSlotSize++; + } + + /** + * Add the interceptor to the given collection. + * + * @param list the collection to add. + * @param interceptor the interceptor to add. + */ + private void add(ArrayList list, Interceptor interceptor) + throws DuplicateName + { + if (interceptor.name().length() > 0) + { + Iterator iter = list.iterator(); + Interceptor ic; + + while (iter.hasNext()) + { + ic = (Interceptor) iter.next(); + if (ic.name().equals(interceptor.name())) + { + throw new DuplicateName(interceptor.name()); + } + } + } + list.add(interceptor); + } + + /** + * Get string array, passed to ORB.init. + */ + public String[] arguments() + { + return m_args; + } + + /** + * Get the codec factory. + */ + public CodecFactory codec_factory() + { + return m_codecFactory; + } + + /** + * Get the ORB's id, currently using .toString. + */ + public String orb_id() + { + return "orb_" + orb; + } + + /** + * Register reference. + */ + public void register_initial_reference(String object_name, Object object) + throws InvalidName + { + if (object_name == null) + { + throw new InvalidName("null"); + } + else if (object_name.length() == 0) + { + throw new InvalidName("Empty string"); + } + else if (m_references.containsKey(object_name)) + { + throw new InvalidName(object_name); + } + else + { + m_references.put(object_name, object); + } + } + + /** + * Accumulates the policy factory map. + */ + public void register_policy_factory(int policy_type, + PolicyFactory policy_factory + ) + { + Integer it = new Integer(policy_type); + if (m_policyFactories.containsKey(it)) + { + throw new BAD_INV_ORDER( + "Repetetive registration of the policy factory for type " + + policy_type, + 16, + CompletionStatus.COMPLETED_NO + ); + } + m_policyFactories.put(it, policy_factory); + } + + /** + * Delegates to ORB. + */ + public org.omg.CORBA.Object resolve_initial_references(String object_name) + throws InvalidName + { + try + { + return orb.resolve_initial_references(object_name); + } + catch (org.omg.CORBA.ORBPackage.InvalidName e) + { + InvalidName in = new InvalidName(e.getMessage()); + in.initCause(e); + throw in; + } + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasClientRequestInterceptors() + { + return m_client.size() > 0; + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasServerRequestInterceptors() + { + return m_server.size() > 0; + } + + /** + * Check if any interceptors of this type were registered. + */ + public boolean hasIorInterceptors() + { + return m_ior.size() > 0; + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java b/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java new file mode 100644 index 000000000..5cb5b1ab4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/ServerRequestInterceptors.java @@ -0,0 +1,139 @@ +/* ServerRequestInterceptors.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInfo; +import org.omg.PortableInterceptor.ServerRequestInterceptor; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; + +/** + * A block of the all registered ServerRequest interceptors. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ServerRequestInterceptors + implements ServerRequestInterceptorOperations +{ + /** + * The array of all registered ServerRequest interceptors. + */ + private final ServerRequestInterceptor[] interceptors; + + /** + * Create the interceptor pack with the registerend interceptor array, + * obtained from the registrator. + */ + public ServerRequestInterceptors(Registrator registrator) + { + interceptors = registrator.getServerRequestInterceptors(); + } + + /** @inheritDoc */ + public void receive_request_service_contexts(ServerRequestInfo info) + throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_request_service_contexts(info); + } + } + + /** @inheritDoc */ + public void receive_request(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].receive_request(info); + } + } + + /** @inheritDoc */ + public void send_exception(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_exception(info); + } + } + + /** @inheritDoc */ + public void send_other(ServerRequestInfo info) throws ForwardRequest + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_other(info); + } + } + + /** @inheritDoc */ + public void send_reply(ServerRequestInfo info) + { + for (int i = 0; i < interceptors.length; i++) + { + interceptors [ i ].send_reply(info); + } + } + + /** + * Call destroy on all registered interceptors. + */ + public void destroy() + { + for (int i = 0; i < interceptors.length; i++) + { + try + { + interceptors [ i ].destroy(); + } + catch (Exception exc) + { + // OMG states we should ignore. + } + } + } + + /** + * Get the class name. + */ + public String name() + { + return getClass().getName(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java new file mode 100644 index 000000000..226e7f316 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuClientRequestInfo.java @@ -0,0 +1,337 @@ +/* gnuClientRequestInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuRequest; + +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_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.INV_POLICY; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NVList; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ParameterMode; +import org.omg.CORBA.Policy; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.Dynamic.Parameter; +import org.omg.IOP.ServiceContext; +import org.omg.IOP.TaggedComponent; +import org.omg.IOP.TaggedProfile; +import org.omg.PortableInterceptor.ClientRequestInfo; +import org.omg.PortableInterceptor.InvalidSlot; + +/** + * Client request info. All requests on the client side in Classpath + * implementations are handled via gnuRequest class. This class holds the + * instance of the gnuRequest, accessing the request info this way. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuClientRequestInfo extends LocalObject + implements ClientRequestInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The request structure, from that some methods take the needed information + * directly. The same request structure cannot be reused in parallel threads, + * the submission methods are synchronized. + */ + private final gnuRequest request; + + /** + * Provides possibility to set the wrapped thrown exception explicitly, where + * applicable. + */ + public Any m_wrapped_exception; + + /** + * Create the info on the given request. + */ + public gnuClientRequestInfo(gnuRequest a_request) + { + request = a_request; + } + + /** @inheritDoc */ + public void add_request_service_context(ServiceContext service_context, + boolean replace + ) + { + request.add_request_service_context(service_context, replace); + } + + /** @inheritDoc */ + public TaggedProfile effective_profile() + { + return request.effective_profile(); + } + + /** @inheritDoc */ + public org.omg.CORBA.Object effective_target() + { + return request.effective_target(); + } + + /** @inheritDoc */ + public TaggedComponent get_effective_component(int id) + throws BAD_PARAM + { + return request.get_effective_component(id); + } + + /** @inheritDoc */ + public TaggedComponent[] get_effective_components(int id) + throws BAD_PARAM + { + return request.get_effective_components(id); + } + + /** @inheritDoc */ + public Policy get_request_policy(int type) throws INV_POLICY + { + return request.get_request_policy(type); + } + + /** @inheritDoc */ + public String received_exception_id() + { + try + { + if (m_wrapped_exception != null) + { + return m_wrapped_exception.type().id(); + } + else + { + return request.received_exception_id(); + } + } + catch (BadKind e) + { + throw new Unexpected(e); + } + } + + /** @inheritDoc */ + public Any received_exception() + { + if (m_wrapped_exception != null) + { + return m_wrapped_exception; + } + else + { + return request.received_exception(); + } + } + + /** @inheritDoc */ + public org.omg.CORBA.Object target() + { + return request.target(); + } + + /** @inheritDoc */ + public Parameter[] arguments() + { + request.checkDii(); + + NVList args = request.arguments(); + Parameter[] p = new Parameter[ args.count() ]; + try + { + for (int i = 0; i < p.length; i++) + { + ParameterMode mode; + + switch (args.item(i).flags()) + { + case ARG_IN.value : + mode = ParameterMode.PARAM_IN; + break; + + case ARG_OUT.value : + mode = ParameterMode.PARAM_OUT; + break; + + case ARG_INOUT.value : + mode = ParameterMode.PARAM_INOUT; + break; + + default : + throw new Unexpected(); + } + + p [ i ] = new Parameter(args.item(i).value(), mode); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return p; + } + + /** @inheritDoc */ + public Any result() + { + request.checkDii(); + + Any rt = request.return_value(); + + if (rt == null) + { + ORB orb = request.orb(); + rt = orb.create_any(); + rt.type(orb.get_primitive_tc(TCKind.tk_void)); + return rt; + } + + return request.return_value(); + } + + /** @inheritDoc */ + public String[] contexts() + { + return request.ice_contexts(); + } + + /** @inheritDoc */ + public TypeCode[] exceptions() + { + request.checkDii(); + + ExceptionList ex = request.exceptions(); + TypeCode[] et = new TypeCode[ ex.count() ]; + try + { + for (int i = 0; i < et.length; i++) + { + et [ i ] = ex.item(i); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return et; + } + + /** @inheritDoc */ + public org.omg.CORBA.Object forward_reference() + { + return request.forward_reference(); + } + + /** @inheritDoc */ + public String[] operation_context() + { + return request.operation_context(); + } + + /** @inheritDoc */ + public Any get_slot(int id) throws InvalidSlot + { + return request.get_slot(id); + } + + /** @inheritDoc */ + public String operation() + { + return request.operation(); + } + + /** @inheritDoc */ + public short reply_status() + { + return request.reply_status(); + } + + /** @inheritDoc */ + public int request_id() + { + return request.request_id(); + } + + /** @inheritDoc */ + public boolean response_expected() + { + return request.response_expected(); + } + + /** + * 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 request.sync_scope(); + } + + /** @inheritDoc */ + public ServiceContext get_reply_service_context(int ctx_name) + throws BAD_PARAM + { + return request.get_reply_service_context(ctx_name); + } + + /** @inheritDoc */ + public ServiceContext get_request_service_context(int ctx_name) + throws BAD_PARAM + { + return request.get_request_service_context(ctx_name); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java new file mode 100644 index 000000000..caed69aeb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuIcCurrent.java @@ -0,0 +1,255 @@ +/* gnuIcCurrent.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.Poa.ORB_1_4; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.Current; +import org.omg.PortableInterceptor.CurrentHelper; +import org.omg.PortableInterceptor.InvalidSlot; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +/** + * Supports the "Interceptor current" concept, providing the slot value + * information for the current thread. When making the invocation, this + * information is copied to the Current, returned by ClientRequestInfo. + * + * There is only one instance of this class per ORB. It maintains a thread to + * information map. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIcCurrent extends ObjectImpl implements Current +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, controllin this Current. It provides data about the required size + * of the slot array. + */ + final ORB_1_4 orb; + + /** + * The table, mapping threads to records. + */ + private Hashtable threads = new Hashtable(); + + /** + * An empty array when no slots are defined, computed once. + */ + static final Any[] NO_SLOTS = new Any[ 0 ]; + + /** + * Create the IC current. + */ + public gnuIcCurrent(ORB_1_4 an_orb) + { + orb = an_orb; + } + + /** + * Get the array of POA current repository ids. + * + * @return a single member array, containing value, returned by the + * {@link CurrentHelper#id}, normally + * "IDL:omg.org/PortableInterceptor/Current:1.0". + */ + public String[] _ids() + { + return new String[] { CurrentHelper.id() }; + } + + /** + * Add the entry to the map. + */ + public void put(Thread t, Any[] record) + { + synchronized (threads) + { + threads.put(t, record); + + // Remove non-running threads, avoiding memory leak. + if (threads.size() > 12) + { + Iterator it = threads.entrySet().iterator(); + while (it.hasNext()) + { + Map.Entry e = (Map.Entry) it.next(); + Thread tx = (Thread) e.getKey(); + if (!tx.isAlive()) + { + it.remove(); + } + } + } + } + } + + /** + * Check if this thread is registered. + */ + public boolean has(Thread t) + { + synchronized (threads) + { + return threads.containsKey(t); + } + } + + /** + * Remove the entry from the map. + */ + public void remove(Thread t) + { + synchronized (threads) + { + threads.remove(t); + } + } + + /** + * Get array of all slots, as it is applicable for the current thread. If the + * slots were not previously allocated, they are allocated during this call. + */ + Any[] get_slots() + { + Any[] r; + synchronized (threads) + { + r = (Any[]) threads.get(Thread.currentThread()); + if (r == null) + { + r = new Any[ orb.icSlotSize ]; + + for (int i = 0; i < r.length; i++) + { + Any a = orb.create_any(); + a.type(orb.get_primitive_tc(TCKind.tk_null)); + r [ i ] = a; + } + + put(Thread.currentThread(), r); + } + return r; + } + } + + /** + * Get copu array of all slots, as it is applicable for the current thread. If + * the slots were not previously allocated, they are allocated during this + * call. + */ + public Any[] clone_slots() + { + if (orb.icSlotSize == 0) + { + return NO_SLOTS; + } + else + { + Any[] r = get_slots(); + Any[] copy = new Any[ r.length ]; + + BufferedCdrOutput buf = new BufferedCdrOutput(); + buf.setOrb(orb); + + for (int i = 0; i < copy.length; i++) + { + r [ i ].write_value(buf); + } + + InputStream input = buf.create_input_stream(); + + for (int i = 0; i < copy.length; i++) + { + copy [ i ] = orb.create_any(); + copy [ i ].read_value(input, r [ i ].type()); + } + + return copy; + } + } + + /** + * Get value for the slot with the given id. If the array of Currents has not + * been yet allocated for the current thread, it is allocated during the + * invocation of this method. + */ + public Any get_slot(int slot_id) throws InvalidSlot, BAD_INV_ORDER + { + try + { + return get_slots() [ slot_id ]; + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new InvalidSlot("Slot " + slot_id); + } + } + + /** + * Set value for the slot with the given id. If the array of Currents has not + * been yet allocated for the current thread, it is allocated during the + * invocation of this method. + */ + public void set_slot(int slot_id, Any data) + throws InvalidSlot, BAD_INV_ORDER + { + try + { + get_slots() [ slot_id ] = data; + } + catch (ArrayIndexOutOfBoundsException e) + { + throw new InvalidSlot("Slot " + slot_id); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java new file mode 100644 index 000000000..257c49728 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuIorInfo.java @@ -0,0 +1,156 @@ +/* gnuIorInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.IOR; +import gnu.CORBA.Poa.ORB_1_4; +import gnu.CORBA.Poa.gnuPOA; + +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.Policy; +import org.omg.IOP.TaggedComponent; +import org.omg.PortableInterceptor.IORInfo; +import org.omg.PortableInterceptor.ObjectReferenceFactory; +import org.omg.PortableInterceptor.ObjectReferenceTemplate; + +/** + * Implements IORInfo. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIorInfo extends LocalObject implements IORInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The ORB, to that the IOR is related. + */ + public final ORB_1_4 orb; + + /** + * The POA, to that IOR is related. + */ + public final gnuPOA poa; + + /** + * The IOR itself. + */ + private final IOR ior; + + /** + * Create an instance. + */ + public gnuIorInfo(ORB_1_4 an_orb, gnuPOA a_poa, IOR an_ior) + { + orb = an_orb; + poa = a_poa; + ior = an_ior; + } + + /** + * Add component to tje specified profile of this IOR. + */ + public void add_ior_component_to_profile(TaggedComponent tagged_component, + int profile_id + ) + { + ior.add_ior_component_to_profile(tagged_component, profile_id); + } + + /** + * Add component to all found profiles in this IOR. + */ + public void add_ior_component(TaggedComponent tagged_component) + { + ior.add_ior_component(tagged_component); + } + + /** + * Get the POA policy. + */ + public Policy get_effective_policy(int policy_type) + { + return poa._get_policy(policy_type); + } + + /** + * Return the state of the object POA. + */ + public short state() + { + return (short) poa.the_POAManager().get_state().value(); + } + + /** + * Get the adapter template, associated with this poa. + */ + public ObjectReferenceTemplate adapter_template() + { + return poa.getReferenceTemplate(); + } + + /** + * Get the object factory of the current POA. + */ + public ObjectReferenceFactory current_factory() + { + return poa.getReferenceFactory(); + } + + /** + * Set the object factory of the current POA. + */ + public void current_factory(ObjectReferenceFactory factory) + { + poa.setReferenceFactory(factory); + } + + /** + * The method currently uses system identity hashcode that should be + * different for each object. + */ + public int manager_id() + { + // The System.identityHashCode is also called in gnuPoaManager. + return System.identityHashCode(poa.the_POAManager()); + } +} diff --git a/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java b/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java new file mode 100644 index 000000000..03ad773d9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Interceptor/gnuServerRequestInfo.java @@ -0,0 +1,476 @@ +/* gnuServerRequestInfo.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Interceptor; + +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.GIOP.RequestHeader; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Poa.gnuServantObject; +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuRequest; + +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_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.INV_POLICY; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NO_RESOURCES; +import org.omg.CORBA.NVList; +import org.omg.CORBA.Object; +import org.omg.CORBA.ParameterMode; +import org.omg.CORBA.Policy; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.Dynamic.Parameter; +import org.omg.IOP.ServiceContext; +import org.omg.Messaging.SYNC_WITH_TRANSPORT; +import org.omg.PortableInterceptor.InvalidSlot; +import org.omg.PortableInterceptor.ServerRequestInfo; + +/** + * Implementation of the ServerRequestInfo, associacted with gnuServantObject. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServerRequestInfo extends LocalObject + implements ServerRequestInfo +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * A local object that will serve the invocation. + */ + final gnuServantObject m_object; + + /** + * A message that the given resource is not available using this metod of + * invocation. + */ + static final String not_available = + "The used invocation method provides" + "no access to this resource."; + + /** + * An array of slots. + */ + Any[] m_slots; + + /** + * The request header. + */ + public final RequestHeader m_request_header; + + /** + * The reply header. + */ + public final ReplyHeader m_reply_header; + + /** + * The forward reference, if applicable. + */ + public Object m_forward_reference; + + /** + * The thrown systen exception. + */ + public Exception m_sys_exception; + + /** + * The Any, containing the thrown user exception. + */ + public Any m_usr_exception; + + /** + * The associated request, if any. + */ + public gnuRequest m_request; + + /** + * Create a new instance at the time when it is known which object will serve + * the invocation. + * + * @param an_object a local object, connected to the local servant that will + * serve the invocation. + */ + public gnuServerRequestInfo(gnuServantObject an_object, + RequestHeader a_request_header, ReplyHeader a_reply_header + ) + { + m_object = an_object; + m_request_header = a_request_header; + m_reply_header = a_reply_header; + m_slots = new Any[ m_object.orb.icSlotSize ]; + reset(); + } + + /** + * Set the give slot. + */ + public void set_slot(int id, Any data) throws InvalidSlot + { + try + { + m_slots [ id ] = data; + } + catch (Exception e) + { + InvalidSlot ex = new InvalidSlot("Cannot set slot " + id); + ex.initCause(e); + throw ex; + } + } + + /** + * Get the given slot. + */ + public Any get_slot(int id) throws InvalidSlot + { + try + { + return m_slots [ id ]; + } + catch (Exception e) + { + InvalidSlot ex = new InvalidSlot("Cannot get slot " + id); + ex.initCause(e); + throw ex; + } + } + + /** + * Reset slot data. + */ + public void reset() + { + TypeCode tkNull = m_object.orb.get_primitive_tc(TCKind.tk_null); + for (int i = 0; i < m_slots.length; i++) + { + Any a = m_object.orb.create_any(); + a.type(tkNull); + m_slots [ i ] = a; + } + m_sys_exception = null; + m_usr_exception = null; + } + + /** + * Get the object id (not the object IOR key). + */ + public byte[] object_id() + { + return m_object.Id; + } + + /** + * Check if the target is an instance of the type, represented by the given + * repository Id. + */ + public boolean target_is_a(String id) + { + return m_object._is_a(id); + } + + /** + * Get the POA id. + */ + public byte[] adapter_id() + { + return m_object.poa.id(); + } + + /** + * Get the POA policy of the given type that applies to the object being + * served (request being handled). + */ + public Policy get_server_policy(int type) throws INV_POLICY + { + return m_object.poa._get_policy(type); + } + + /** + * Get the first member of the object repository id array. + */ + public String target_most_derived_interface() + { + return m_object._ids() [ 0 ]; + } + + /** + * Get the name of the operation being performed. + */ + public String operation() + { + if (m_request != null) + { + return m_request.operation(); + } + else + { + return m_request_header.operation; + } + } + + /** + * Not available. + */ + public TypeCode[] exceptions() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available, 1, + CompletionStatus.COMPLETED_MAYBE + ); + } + + m_request.checkDii(); + + ExceptionList ex = m_request.exceptions(); + TypeCode[] et = new TypeCode[ ex.count() ]; + try + { + for (int i = 0; i < et.length; i++) + { + et [ i ] = ex.item(i); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return et; + } + + /** + * Get reply status. + */ + public short reply_status() + { + return (short) m_reply_header.reply_status; + } + + /** + * Get request id. All local requests have request id = -1. + */ + public int request_id() + { + return m_request_header.request_id; + } + + /** + * Check if the client expected any response. + */ + public boolean response_expected() + { + return m_request_header.isResponseExpected(); + } + + /** @inheritDoc */ + public void add_reply_service_context(ServiceContext service_context, + boolean replace + ) + { + m_reply_header.addContext(service_context, replace); + } + + /** + * Get an exception, wrapped into Any. + */ + public Any sending_exception() + { + if (m_usr_exception != null) + { + return m_usr_exception; + } + else if (m_sys_exception != null) + { + Any a = m_object.orb.create_any(); + ObjectCreator.insertException(a, m_sys_exception); + return a; + } + else + { + return null; + } + } + + public org.omg.CORBA.Object forward_reference() + { + return m_forward_reference; + } + + /** @inheritDoc */ + public ServiceContext get_reply_service_context(int ctx_name) + throws BAD_PARAM + { + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_reply_header.service_context + ); + } + + /** @inheritDoc */ + public ServiceContext get_request_service_context(int ctx_name) + throws BAD_PARAM + { + return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name, + m_request_header.service_context + ); + } + + /** + * Not available + */ + public String[] operation_context() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.operation_context(); + } + } + + /** @inheritDoc */ + public Any result() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.return_value(); + } + } + + /** @inheritDoc */ + public String[] contexts() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + else + { + return m_request.ice_contexts(); + } + } + + /** + * Always returns "with transport". + */ + public short sync_scope() + { + return SYNC_WITH_TRANSPORT.value; + } + + /** @inheritDoc */ + public Parameter[] arguments() + { + if (m_request == null) + { + throw new NO_RESOURCES(not_available); + } + + m_request.checkDii(); + + NVList args = m_request.arguments(); + Parameter[] p = new Parameter[ args.count() ]; + try + { + for (int i = 0; i < p.length; i++) + { + ParameterMode mode; + + switch (args.item(i).flags()) + { + case ARG_IN.value : + mode = ParameterMode.PARAM_IN; + break; + + case ARG_OUT.value : + mode = ParameterMode.PARAM_OUT; + break; + + case ARG_INOUT.value : + mode = ParameterMode.PARAM_INOUT; + break; + + default : + throw new Unexpected(); + } + + p [ i ] = new Parameter(args.item(i).value(), mode); + } + } + catch (Bounds e) + { + throw new Unexpected(e); + } + return p; + } + + /** @inheritDoc */ + public String[] adapter_name() + { + return m_object.poa.getReferenceTemplate().adapter_name(); + } + + /** @inheritDoc */ + public String orb_id() + { + return m_object.orb.orb_id; + } + + /** @inheritDoc */ + public String server_id() + { + return OrbFunctional.server_id; + } + +} diff --git a/libjava/classpath/gnu/CORBA/IorDelegate.java b/libjava/classpath/gnu/CORBA/IorDelegate.java new file mode 100644 index 000000000..5f0a59df4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/IorDelegate.java @@ -0,0 +1,425 @@ +/* gnuDelegate.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.GIOP.ReplyHeader; + +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Request; +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; + +/** + * The Classpath implementation of the {@link Delegate} functionality in the + * case, when the object was constructed from an IOR object. The IOR can be + * constructed from the stringified object reference. + * + * There is an different instance of this delegate for each CORBA object. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class IorDelegate extends SimpleDelegate +{ + /** + * Contructs an instance of object using the given IOR. + */ + public IorDelegate(ORB an_orb, IOR an_ior) + { + super(an_orb, an_ior); + } + + /** + * Creates the request to invoke the method on this object. + * + * @param target the object, for that the operation must be invoked. + * @param context context (null allowed) + * @param operation the method name + * @param parameters the method parameters + * @param returns the return value holder + * + * @return the created request. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String operation, NVList parameters, NamedValue returns + ) + { + gnuRequest request = getRequestInstance(target); + + request.setIor(getIor()); + request.set_target(target); + + request.setOperation(operation); + request.set_args(parameters); + request.m_context = context; + request.set_result(returns); + request.setORB(orb); + + return request; + } + + /** + * Creates the request to invoke the method on this object. + * + * @param target the object, for that the operation must be invoked. + * @param context context (null allowed) + * @param operation the method name + * @param parameters the method parameters + * @param returns the return value holder + * + * @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 + ) + { + gnuRequest request = getRequestInstance(target); + + request.setIor(ior); + request.set_target(target); + + request.setOperation(operation); + request.set_args(parameters); + request.m_context = context; + request.set_result(returns); + request.set_exceptions(exceptions); + request.set_context_list(ctx_list); + request.setORB(orb); + + return request; + } + + /** + * 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. + * + * @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). + * + * @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 + { + StreamBasedRequest request = (StreamBasedRequest) output; + while (true) + { + try + { + if (request.response_expected) + { + RawReply response = request.request.submit(); + + // Read reply header. + ReplyHeader rh = response.header.create_reply_header(); + BufferredCdrInput 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, + rh.service_context); + + 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); + + IorObject it = new IorObject(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; + } + } + } + } + } + + /** + * Show exception to interceptor. + */ + void showException(StreamBasedRequest request, BufferredCdrInput 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. + * @param operation the name of the method to invoke. + * + * @return the request. + */ + public Request request(org.omg.CORBA.Object target, String operation) + { + gnuRequest request = getRequestInstance(target); + + request.setIor(ior); + request.set_target(target); + + request.setOperation(operation); + request.setORB(orb); + + return request; + } + + /** + * Create a request to invoke the method of this CORBA object. + * + * @param target the CORBA object, to that this operation must be applied. + * @param operation the name of the method to invoke. + * @param response_expected specifies if this is one way message or the + * response to the message is expected. + * + * @return the stream where the method arguments should be written. + */ + public OutputStream request(org.omg.CORBA.Object target, String operation, + boolean response_expected + ) + { + gnuRequest request = getRequestInstance(target); + + request.setIor(ior); + request.set_target(target); + request.setOperation(operation); + + StreamBasedRequest out = request.getParameterStream(); + out.response_expected = response_expected; + request.setORB(orb); + out.setOrb(orb); + + return out; + } + + /** + * 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. + */ + public void release(org.omg.CORBA.Object target) + { + // Do nothing here. + } + + /** + * 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); + } + + /** + * Checks if the ior is local so far it is easy. + */ + public boolean is_local(org.omg.CORBA.Object self) + { + return false; + } +} diff --git a/libjava/classpath/gnu/CORBA/IorObject.java b/libjava/classpath/gnu/CORBA/IorObject.java new file mode 100644 index 000000000..921d18d00 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/IorObject.java @@ -0,0 +1,118 @@ +/* IorObject.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.ORB; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * Implements an object, constructed from an IOR reference. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class IorObject + extends ObjectImpl + implements IorProvider +{ + /** + * The IOR, from which the object was constructed. + */ + protected final IOR ior; + + /** + * The object id, as defined in IOR. + */ + protected final String[] id; + + /** + * Create the object from the given IOR. + * + * @param an_ior the IOR. + */ + public IorObject(ORB orb, IOR an_ior) + { + ior = an_ior; + _set_delegate(new IorDelegate(orb, ior)); + id = new String[] { ior.Id }; + } + + /** + * Create the object from the given string IOR representation. + * + * @param an_ior the IOR in the string form. + */ + public IorObject(OrbFunctional orb, String an_ior) + { + ior = IOR.parse(an_ior); + _set_delegate(new IorDelegate(orb, ior)); + id = new String[] { ior.Id }; + } + + /** + * Get the IOR of this object. + */ + public IOR getIor() + { + return ior; + } + + public String[] _ids() + { + return id; + } + + /** + * Get a string reference for this object. + * + * @return the class name:IOR profile + */ + public String toString() + { + return getClass().getName() + ":IOR:" + ior; + } + + /** + * Calls realease on the delegate. + */ + protected void finalize() + throws java.lang.Throwable + { + _get_delegate().release(this); + } +} diff --git a/libjava/classpath/gnu/CORBA/IorProvider.java b/libjava/classpath/gnu/CORBA/IorProvider.java new file mode 100644 index 000000000..875b5de1f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/IorProvider.java @@ -0,0 +1,52 @@ +/* IorProvider.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.CORBA; + +/** + * Marks the possibility of the implementing object to return the associated + * IOR. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface IorProvider +{ + /** + * Get the IOR of the associated object. + */ + IOR getIor(); +} diff --git a/libjava/classpath/gnu/CORBA/Minor.java b/libjava/classpath/gnu/CORBA/Minor.java new file mode 100644 index 000000000..8832162bc --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Minor.java @@ -0,0 +1,282 @@ +/* Minor.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + + +package gnu.CORBA; + + +/** + * Provides information and operations, related to about the 20 bit vendor minor + * code Id. This code is included into all CORBA system exceptions and is also + * transferred to remote side. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface Minor +{ + // Note: MARSHAL done. + + /* MARSHAL */ + + /** + * The GNU Classpath VMCID. The last 12 bits can be used to mark up to 4096 + * possible exceptions. + */ + int vendor = 0x47430000; + + /* + * Minor codes form MARSHAL exception. + */ + + /** + * The message being received is not a GIOP message. It does not start from + * the expected magic sequence byte[] { 'G', 'I', 'O', 'P' }. + */ + int Giop = 1 | vendor; + + /** + * The unexpected IOException while reading or writing the GIOP message header + * or the subsequent request or response header + */ + int Header = 2 | vendor; + + /** + * The data stream ended before reading all expected values from it. This + * usually means that the CORBA message is corrupted, but may also indicate + * that the server expects the remote method being invoked to have more or + * different parameters. + */ + int EOF = 3 | vendor; + + /** + * The unexpected IOException while reading or writing the data via Commond + * Data Representation stream. + */ + int CDR = 5 | vendor; + + /** + * The unexpected IOException while reading or writing the Value type. + */ + int Value = 6 | vendor; + + /** + * The unexpected IOException while handling request forwarding. + */ + int Forwarding = 7 | vendor; + + /** + * The unexpected IOException while handling data encapsulation, tagged + * components, tagged profiles, etc. + */ + int Encapsulation = 8 | vendor; + + /** + * The unexpected IOException while inserting or extracting data to/from the + * Any or DynamicAny. + */ + int Any = 9 | vendor; + + /** + * The unexpected UserException in the context where it cannot be handled and + * must be converted to the SystemException. + */ + int UserException = 10 | vendor; + + /** + * While the operation could formally be applied to the target, the OMG + * standard states that it is actually not applicable. For example, some CORBA + * objects like POA are always local and should not be passed to or returned + * from the remote side. + */ + int Inappropriate = 11 | vendor; + + /** + * When reading data, it was discovered that size of the data structure like + * string, sequence or character is written as the negative number. + */ + int Negative = 12 | vendor; + + /** + * Reference to non-existing node in the data grapth while reading the value + * types. + */ + int Graph = 14 | vendor; + + /** + * Unexpected exception was thrown from the IDL type helper while handling the + * object of this type as a boxed value. + */ + int Boxed = 15 | vendor; + + /** + * Unable to instantiate an value type object while reading it from the + * stream. + */ + int Instantiation = 16 | vendor; + + /** + * The header tag of the value type being read from the CDR stream contains an + * unexpected value outside 0x7fffff00 .. 0x7fffffff and also not null and not + * an indirection. + */ + int ValueHeaderTag = 17 | vendor; + + /** + * The header tag flags of the value type being read from the CDR stream make + * the invalid combination (for instance, 0x7fffff04). + */ + int ValueHeaderFlags = 18 | vendor; + + /** + * The value type class, written on the wire, is not compatible with the + * expected class, passed as a parameter to the InputStream.read_value. + */ + int ClassCast = 19 | vendor; + + /** + * Positive or otherwise invalid indirection offset when reading the data + * graph of the value type. + */ + int Offset = 20 | vendor; + + /** + * Errors while reading the chunked value type. + */ + int Chunks = 21 | vendor; + + /** + * No means are provided to write this value type. + */ + int UnsupportedValue = 22 | vendor; + + /** + * The value factory, required for the operation being invoked, is not + * registered with this ORB. + */ + int Factory = 23 | vendor; + + /** + * Unsupported object addressing method in GIOP request header. + */ + int UnsupportedAddressing = 24 | vendor; + + /** + * Invalid stringified object reference (IOR). + */ + int IOR = 25 | vendor; + + /** + * Problems with converting between stubs, ties, interfaces and + * implementations. + */ + int TargetConversion = 26 | vendor; + + /** + * Problems with reading or writing the fields of the value type object. + */ + int ValueFields = 27 | vendor; + + /** + * The instance of the value type is not serializable. + */ + int NonSerializable = 28 | vendor; + + /* BAD_OPERATION */ + + /** + * The remote side requested to invoke the method that is not available on + * that target (client and server probably disagree in the object definition). + */ + int Method = 0 | vendor; + + /** + * Failed to activate the inactive object. + */ + int Activation = 10 | vendor; + + /* + * Any - Attempt to extract from the Any value of the different type that was + * stored into that Any. + */ + + /* ClassCast - Unable to narrow the object into stub. */ + + /** + * The policies, applying to ORB or POA prevent the requested operation. + */ + int Policy = 11 | vendor; + + /** + * Socket related errors like failure to open socket on the expected port, + * failure to get a free port when required and so on. + */ + int Socket = 12 | vendor; + + /** + * The passed value for enumeration is outside the valid range for that + * enumeration. + */ + int Enumeration = 14 | vendor; + + /** + * The passed policy code is outside the valid range of the possible policies + * for the given policy type. + */ + int PolicyType = 15 | vendor; + + /* NO_RESOURCES */ + + /** + * Unable to get a free port for a new socket. Proably too many objects under + * unsuitable POA policy. + */ + int Ports = 20 | vendor; + + /** + * Too many parallel calls (too many parallel threads). The thread control + * prevents malicios client from knocking the server out by suddenly + * submitting large number of requests. + */ + int Threads = 21 | vendor; + + /** + * The IOR starts with file://, http:// or ftp://, but this local or remote + * resource is not accessible. + */ + int Missing_IOR = 22 | vendor; + +} diff --git a/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java b/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java new file mode 100644 index 000000000..e8047b8d7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameDynAnyPairHolder.java @@ -0,0 +1,115 @@ +/* NameDynAnyPairHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameDynAnyPairHelper; + +/** + * A holder for the structure {@link NameDynAnyPair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameDynAnyPairHolder + implements Streamable +{ + /** + * The stored NameDynAnyPair value. + */ + public NameDynAnyPair value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public NameDynAnyPairHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public NameDynAnyPairHolder(NameDynAnyPair initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = NameDynAnyPairHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + NameDynAnyPairHelper.write(output, value); + } + + /** + * Get the typecode of the NameDynAnyPair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameDynAnyPairHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java b/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java new file mode 100644 index 000000000..8bf8ee89d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameDynAnyPairSeqHolder.java @@ -0,0 +1,115 @@ +/* NameDynAnyPairSeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameDynAnyPair; +import org.omg.DynamicAny.NameDynAnyPairSeqHelper; + +/** + * A holder for the sequence of {@link NameDynAnyPair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameDynAnyPairSeqHolder + implements Streamable +{ + /** + * The stored array of <code>NameDynAnyPair</code>. + */ + public NameDynAnyPair[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public NameDynAnyPairSeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public NameDynAnyPairSeqHolder(NameDynAnyPair[] initialValue) + { + value = initialValue; + } + + /** + * The method should read this object from the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _read(InputStream input) + { + value = NameDynAnyPairSeqHelper.read(input); + } + + /** + * The method should write this object to the CDR input stream, but + * (following the JDK 1.5 API) it does not. + * + * @param input a org.omg.CORBA.portable stream to read from. + * + * @specenote Sun throws the same exception. + * + * @throws MARSHAL always. + */ + public void _write(OutputStream output) + { + NameDynAnyPairSeqHelper.write(output, value); + } + + /** + * Get the typecode of the NameDynAnyPair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameDynAnyPairSeqHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/NameValuePairHolder.java b/libjava/classpath/gnu/CORBA/NameValuePairHolder.java new file mode 100644 index 000000000..d757bdb39 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameValuePairHolder.java @@ -0,0 +1,105 @@ +/* NameValuePairHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameValuePair; +import org.omg.DynamicAny.NameValuePairHelper; + +/** + * A holder for the structure {@link NameValuePair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValuePairHolder + implements Streamable +{ + /** + * The stored NameValuePair value. + */ + public NameValuePair value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public NameValuePairHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public NameValuePairHolder(NameValuePair initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = NameValuePairHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + NameValuePairHelper.write(output, value); + } + + /** + * Get the typecode of the NameValuePair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameValuePairHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java b/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java new file mode 100644 index 000000000..5515bd306 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NameValuePairSeqHolder.java @@ -0,0 +1,105 @@ +/* NameValuePairSeqHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.DynamicAny.NameValuePair; +import org.omg.DynamicAny.NameValuePairSeqHelper; + +/** + * A holder for the sequence of {@link NameValuePair}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValuePairSeqHolder + implements Streamable +{ + /** + * The stored array of <code>NameValuePair</code>. + */ + public NameValuePair[] value; + + /** + * Create the unitialised instance, leaving the value array + * with default <code>null</code> value. + */ + public NameValuePairSeqHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the array that will be assigned to + * the <code>value</code> array. + */ + public NameValuePairSeqHolder(NameValuePair[] initialValue) + { + value = initialValue; + } + + /** + * Read the {@link value} array from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = NameValuePairSeqHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + NameValuePairSeqHelper.write(output, value); + } + + /** + * Get the typecode of the NameValuePair. + */ + public org.omg.CORBA.TypeCode _type() + { + return NameValuePairSeqHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/Binding_iterator_impl.java b/libjava/classpath/gnu/CORBA/NamingService/Binding_iterator_impl.java new file mode 100644 index 000000000..108ca270d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/Binding_iterator_impl.java @@ -0,0 +1,141 @@ +/* Binding_iterator.java -- + Copyright (C) 2005, 2006 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.NamingService; + +import gnu.CORBA.SafeForDirectCalls; + +import org.omg.CosNaming.Binding; +import org.omg.CosNaming.BindingHolder; +import org.omg.CosNaming.BindingListHolder; +import org.omg.CosNaming.BindingType; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming._BindingIteratorImplBase; + +/** + * The implementation of the {@link BindingIterator}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Binding_iterator_impl + extends _BindingIteratorImplBase implements SafeForDirectCalls +{ + /** + * The value, returned by the {@link #next_one} when there + * are no bindings available. + */ + private static final Binding no_more_bindings = + new Binding(new NameComponent[ 0 ], BindingType.nobject); + + /** + * The collection of the available bindings. + */ + private final Binding[] bindings; + + /** + * The position of the internal iterator pointer. + */ + private int p; + + public Binding_iterator_impl(Binding[] a_bindings) + { + bindings = a_bindings; + } + + /** + * Disconnect the iterator from its ORB. The iterator will + * no longer be accessible and will be a subject of the + * garbage collection. + */ + public void destroy() + { + _orb().disconnect(this); + } + + /** + * Return the desired amount of bindings. + * + * @param amount the maximal number of bindings to return. + * @param a_list a holder to store the returned bindings. + * + * @return false if there are no more bindings available, + * true otherwise. + */ + public boolean next_n(int amount, BindingListHolder a_list) + { + if (p < bindings.length) + { + int n = bindings.length - p; + if (n > amount) + n = amount; + + a_list.value = new Binding[ n ]; + for (int i = 0; i < n; i++) + a_list.value [ i ] = bindings [ p++ ]; + + return true; + } + else + { + a_list.value = new Binding[ 0 ]; + return false; + } + } + + /** + * Return the next binding. + * + * @param a_binding a holder, where the next binding will be stored. + * + * @return false if there are no more bindings available, true + * otherwise. + */ + public boolean next_one(BindingHolder a_binding) + { + if (p < bindings.length) + { + a_binding.value = (Binding) bindings [ p++ ]; + return true; + } + else + { + a_binding.value = no_more_bindings; + return false; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/Ext.java b/libjava/classpath/gnu/CORBA/NamingService/Ext.java new file mode 100644 index 000000000..d339cb194 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/Ext.java @@ -0,0 +1,232 @@ +/* TransientContextExt.java -- + Copyright (C) 2005, 2006 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.NamingService; + +import gnu.CORBA.SafeForDirectCalls; + +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.Object; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CosNaming.BindingIteratorHolder; +import org.omg.CosNaming.BindingListHolder; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContext; +import org.omg.CosNaming.NamingContextPackage.AlreadyBound; +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotEmpty; +import org.omg.CosNaming.NamingContextPackage.NotFound; +import org.omg.CosNaming._NamingContextExtImplBase; + +/** + * This naming context that adds the the string based extensions, + * defined by {@link NamingContextExt}. The basic functionality + * is handled by the enclosed instance of the {@link NamingContext}. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class Ext + extends _NamingContextExtImplBase implements SafeForDirectCalls +{ + /** + * The older version of the naming context, where all relevant calls + * are forwarded. + */ + private final NamingContext classic; + + /** + * The converter class converts between string and array form of the + * name. + */ + private NameTransformer converter = new NameTransformer(); + + /** + * Create the extensions for the given instance of the context. + * + * @param previous_version the previous version of the naming context. + */ + public Ext(NamingContext previous_version) + { + classic = previous_version; + } + + /** + * Sets a delegate to this context and, if appropriated, also + * sets the same delegate to the enclosing 'classic' context. + * + * @param a_delegate a delegate to set. + */ + public void _set_delegate(Delegate a_delegate) + { + super._set_delegate(a_delegate); + if (classic instanceof ObjectImpl) + ((ObjectImpl) classic)._set_delegate(a_delegate); + } + + /** {@inheritDoc} */ + public void bind(NameComponent[] a_name, Object an_object) + throws NotFound, CannotProceed, InvalidName, AlreadyBound + { + classic.bind(a_name, an_object); + } + + /** {@inheritDoc} */ + public void bind_context(NameComponent[] a_name, NamingContext context) + throws NotFound, CannotProceed, InvalidName, AlreadyBound + { + classic.bind_context(a_name, context); + } + + /** {@inheritDoc} */ + public NamingContext bind_new_context(NameComponent[] a_name) + throws NotFound, AlreadyBound, CannotProceed, + InvalidName + { + return classic.bind_new_context(a_name); + } + + /** {@inheritDoc} */ + public void destroy() + throws NotEmpty + { + classic.destroy(); + } + + /** {@inheritDoc} */ + public void list(int amount, BindingListHolder a_list, + BindingIteratorHolder an_iter + ) + { + classic.list(amount, a_list, an_iter); + } + + /** {@inheritDoc} */ + public NamingContext new_context() + { + return classic.new_context(); + } + + /** {@inheritDoc} */ + public void rebind(NameComponent[] a_name, Object an_object) + throws NotFound, CannotProceed, InvalidName + { + classic.rebind(a_name, an_object); + } + + /** {@inheritDoc} */ + public void rebind_context(NameComponent[] a_name, NamingContext context) + throws NotFound, CannotProceed, InvalidName + { + classic.rebind_context(a_name, context); + } + + /** {@inheritDoc} */ + public Object resolve(NameComponent[] a_name) + throws NotFound, CannotProceed, InvalidName + { + return classic.resolve(a_name); + } + + /** + * Resolves the name, represented in the form of the string. The name + * is first parsed into an array representation, then the call + * is forwarded to the {@link resolve(NameComponent[])}. + * + * @param a_name_string a name to resolve. + * + * @return the resolved object. + * + * @throws NotFound if the name cannot be resolved. + * @throws InvalidName if the name is invalid. + * @throws CannotProceed on unexpected circumstances. + */ + public Object resolve_str(String a_name_string) + throws NotFound, CannotProceed, InvalidName + { + return resolve(to_name(a_name_string)); + } + + /** + * Convert the name string representation into array representation. + * + * @param a_name_string a string to convert. + * @return a converted array of the name components + * + * @throws InvalidName on parsing error. + */ + public NameComponent[] to_name(String a_name_string) + throws InvalidName + { + return converter.toName(a_name_string); + } + + /** + * Convert a name component array representation into string representation. + * + * @param a_name a name to convert. + * + * @return a string form. + * + * @throws InvalidName if the passed name is invalid. + */ + public String to_string(NameComponent[] a_name) + throws InvalidName + { + return converter.toString(a_name); + } + + /** + * This method is not yet implemented. + * FIXME TODO implement it. + */ + public String to_url(String an_address, String a_name_string) + throws org.omg.CosNaming.NamingContextExtPackage.InvalidAddress, + InvalidName + { + throw new NO_IMPLEMENT("Method to_url() not yet implemented."); + } + + /** {@inheritDoc} */ + public void unbind(NameComponent[] a_name) + throws NotFound, CannotProceed, InvalidName + { + classic.unbind(a_name); + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NameComponentComparator.java b/libjava/classpath/gnu/CORBA/NamingService/NameComponentComparator.java new file mode 100644 index 000000000..6116ba94e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NameComponentComparator.java @@ -0,0 +1,98 @@ +/* NameComponentComparator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.NamingService; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CosNaming.NameComponent; + +import java.util.Comparator; + +/** + * This class implements the name component comparator, needed to + * sort and compare the name components in maps and sorted sets. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public final class NameComponentComparator + implements Comparator +{ + /** + * The singleton instance of the name comparator. + */ + public static final NameComponentComparator singleton = new NameComponentComparator(); + + /** + * It is enough to have a singleton. + */ + private NameComponentComparator() + { + } + + /** + * Compare the two names components. + * + * @param nc_a the first name component. + * @param nc_b the second name component. + * + * @return 0 if the name components are equal, non zero value + * as result of comparison otherwise. + * + * @throws BAD_PARAM if one of the components is empty or + * has {@link NameComponent#id} or {@link NameComponent#kind} + * field intialised to null. + */ + public final int compare(Object nc_a, Object nc_b) + { + NameComponent a = (NameComponent) nc_a; + NameComponent b = (NameComponent) nc_b; + + int cn = a.id.compareTo(b.id); + if (cn != 0) + return cn; + return a.kind.compareTo(b.kind); + } + + /** + * All instances of this class are equal. + */ + public boolean equals(Object x) + { + return x instanceof NameComponentComparator; + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NameParser.java b/libjava/classpath/gnu/CORBA/NamingService/NameParser.java new file mode 100644 index 000000000..93e4e3b16 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NameParser.java @@ -0,0 +1,527 @@ +/* NameParser.java -- + Copyright (C) 2005, 2006 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.NamingService; + +import gnu.CORBA.Minor; +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.DATA_CONVERSION; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CosNaming.NamingContext; +import org.omg.CosNaming._NamingContextStub; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLDecoder; +import java.util.StringTokenizer; + +/** + * Parses the alternative IOR representations into our IOR structure. + * + * TODO This parser currently supports only one address per target string. A + * string with the multiple addresses will be accepted, but only the last + * address will be taken into consideration. The fault tolerance is not yet + * implemented. + * + * The key string is filtered using {@link java.net.URLDecoder} that replaces + * the agreed escape sequences by the corresponding non alphanumeric characters. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameParser + extends NameTransformer +{ + /** + * The corbaloc prefix. + */ + public static final String pxCORBALOC = "corbaloc"; + + /** + * The corbaname prefix. + */ + public static final String pxCORBANAME = "corbaname"; + + /** + * The IOR prefix. + */ + public static final String pxIOR = "ior"; + + /** + * The file:// prefix. + */ + public static final String pxFILE = "file://"; + + /** + * The ftp:// prefix. + */ + public static final String pxFTP = "ftp://"; + + /** + * The http:// prefix. + */ + public static final String pxHTTP = "http://"; + + /** + * Marks iiop protocol. + */ + public static final String IIOP = "iiop"; + + /** + * Marks rir protocol. + */ + public static final String RIR = "rir"; + + /** + * The default port value, as specified in OMG documentation. + */ + public static final int DEFAULT_PORT = 2809; + + /** + * The default name. + */ + public static final String DEFAULT_NAME = "NameService"; + + /** + * The string to name converter, initialized on demand. + */ + static NameTransformer converter; + + /** + * The current position. + */ + int p; + + /** + * The address being parsed, splitted into tokens. + */ + String[] t; + + /** + * Parse CORBALOC. + * + * The expected format is: <br> + * 1. corbaloc:[iiop][version.subversion@]:host[:port]/key <br> + * 2. corbaloc:rir:[/key] <br> + * 3. corbaname:[iiop][version.subversion@]:host[:port]/key <br> + * 4. corbaname:rir:[/key] <br> + * 5. file://[file name]<br> + * 6. http://[url]<br> + * 7. ftp://[url]<br> + * + * Protocol defaults to IOP, the object key defaults to the NameService. + * + * @param corbaloc the string to parse. + * @param orb the ORB, needed to create IORs and resolve rir references. + * + * @return the resolved object. + */ + public synchronized org.omg.CORBA.Object corbaloc(String corbaloc, + OrbFunctional orb) + throws BAD_PARAM + { + return corbaloc(corbaloc, orb, 0); + } + + /** + * Parse controlling against the infinite recursion loop. + */ + private org.omg.CORBA.Object corbaloc(String corbaloc, + OrbFunctional orb, int recursion) + { + // The used CORBA specification does not state how many times we should to + //redirect, but the infinite loop may be used to knock out the system. + // by malicious attempt. + if (recursion > 10) + throw new DATA_CONVERSION("More than 10 redirections"); + + if (corbaloc.startsWith(pxFILE)) + return corbaloc(readFile(corbaloc.substring(pxFILE.length())), orb, recursion+1); + else if (corbaloc.startsWith(pxHTTP)) + return corbaloc(readUrl(corbaloc), orb, recursion+1); + else if (corbaloc.startsWith(pxFTP)) + return corbaloc(readUrl(corbaloc), orb, recursion+1); + + boolean corbaname; + + // The version numbers with default values. + int major = 1; + int minor = 0; + + // The host address. + String host; + + // The port. + int port = DEFAULT_PORT; + + // The object key as string. + String key; + + StringTokenizer st = new StringTokenizer(corbaloc, ":@/.,#", true); + + t = new String[st.countTokens()]; + + for (int i = 0; i < t.length; i++) + { + t[i] = st.nextToken(); + } + + p = 0; + + if (t[p].startsWith(pxCORBANAME)) + corbaname = true; + else if (t[p].equalsIgnoreCase(pxCORBALOC)) + corbaname = false; + else if (t[p].equalsIgnoreCase(pxIOR)) + { + IOR ior = IOR.parse(corbaloc); + return orb.ior_to_object(ior); + } + else + throw new DATA_CONVERSION("Unsupported protocol: '" + t[p] + "'"); + + p++; + + if (!t[p++].equals(":")) + throw new BAD_PARAM("Syntax (':' expected after name prefix)"); + + // Check for rir: + if (t[p].equals(RIR)) + { + p++; + if (!t[p++].equals(":")) + throw new BAD_PARAM("':' expected after 'rir'"); + + key = readKey("/"); + + Object object; + try + { + object = orb.resolve_initial_references(key); + return corbaname ? resolve(object) : object; + } + catch (InvalidName e) + { + throw new BAD_PARAM("Unknown initial reference '" + key + "'"); + } + } + else + // Check for iiop. + if (t[p].equals(IIOP) || t[p].equals(":")) + { + IOR ior = new IOR(); + + Addresses: do + { // Read addresses. + if (t[p].equals(":")) + { + p++; + } + else + { + p++; + if (!t[p++].equals(":")) + throw new BAD_PARAM("':' expected after 'iiop'"); + // Check if version is present. + if (t[p + 1].equals(".")) + if (t[p + 3].equals("@")) + { + // Version info present. + try + { + major = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Major version number '" + + t[p - 1] + "'"); + } + p++; // '.' at this point. + try + { + minor = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Major version number '" + + t[p - 1] + "'"); + } + p++; // '@' at this point. + } + } + + ior.Internet.version = new Version(major, minor); + + // Then host data goes till '/' or ':'. + CPStringBuilder bhost = new CPStringBuilder(corbaloc.length()); + while (!t[p].equals(":") && !t[p].equals("/") && !t[p].equals(",")) + bhost.append(t[p++]); + + host = bhost.toString(); + + ior.Internet.host = host; + + if (t[p].equals(":")) + { + // Port specified. + p++; + try + { + port = Integer.parseInt(t[p++]); + } + catch (NumberFormatException e) + { + throw new BAD_PARAM("Invalid port '" + t[p - 1] + "'"); + } + } + + ior.Internet.port = port; + + // Id is not listed. + ior.Id = ""; + + if (t[p].equals(",")) + p++; + else + break Addresses; + } + while (true); + + key = readKey("/"); + ior.key = key.getBytes(); + + org.omg.CORBA.Object object = orb.ior_to_object(ior); + return corbaname ? resolve(object) : object; + } + + else + throw new DATA_CONVERSION("Unsupported protocol '" + t[p] + "'"); + } + + /** + * Read IOR from the file in the local file system. + */ + String readFile(String file) + { + File f = new File(file); + if (!f.exists()) + { + DATA_CONVERSION err = new DATA_CONVERSION(f.getAbsolutePath() + + " does not exist."); + err.minor = Minor.Missing_IOR; + } + try + { + char[] c = new char[(int) f.length()]; + FileReader fr = new FileReader(f); + fr.read(c); + fr.close(); + return new String(c).trim(); + } + catch (IOException ex) + { + DATA_CONVERSION d = new DATA_CONVERSION(); + d.initCause(ex); + d.minor = Minor.Missing_IOR; + throw (d); + } + } + + /** + * Read IOR from the remote URL. + */ + String readUrl(String url) + { + URL u; + try + { + u = new URL(url); + } + catch (MalformedURLException mex) + { + throw new BAD_PARAM("Malformed URL: '" + url + "'"); + } + + try + { + InputStreamReader r = new InputStreamReader(u.openStream()); + + CPStringBuilder b = new CPStringBuilder(); + int c; + + while ((c = r.read()) > 0) + b.append((char) c); + + return b.toString().trim(); + } + catch (Exception exc) + { + DATA_CONVERSION d = new DATA_CONVERSION("Reading " + url + " failed."); + d.minor = Minor.Missing_IOR; + throw d; + } + } + + private org.omg.CORBA.Object resolve(org.omg.CORBA.Object object) + { + NamingContext ns; + String key = "?"; + try + { + if (object instanceof NamingContext) + ns = (NamingContext) object; + else + { + Delegate delegate = ((ObjectImpl) object)._get_delegate(); + ns = new _NamingContextStub(); + ((_NamingContextStub) ns)._set_delegate(delegate); + } + } + catch (Exception ex) + { + BAD_PARAM bad = new BAD_PARAM("The CORBANAME target " + object + + " is not a NamingContext"); + bad.minor = 10; + bad.initCause(ex); + throw bad; + } + + if (converter == null) + converter = new NameTransformer(); + + try + { + key = readKey("#"); + object = ns.resolve(converter.toName(key)); + return object; + } + catch (Exception ex) + { + BAD_PARAM bad = new BAD_PARAM("Wrong CORBANAME '" + key + "'"); + bad.minor = 10; + bad.initCause(ex); + throw bad; + } + } + + private String readKey(String delimiter) + throws BAD_PARAM + { + if (p < t.length) + if (!t[p].equals(delimiter)) + { + if (t[p].equals("#")) + return DEFAULT_NAME; + else + throw new BAD_PARAM("'" + delimiter + "String' expected '" + t[p] + + "' found"); + } + + CPStringBuilder bKey = new CPStringBuilder(); + p++; + + while (p < t.length && !t[p].equals("#")) + bKey.append(t[p++]); + + if (bKey.length() == 0) + return DEFAULT_NAME; + + try + { + return URLDecoder.decode(bKey.toString(), "UTF-8"); + } + catch (UnsupportedEncodingException e) + { + throw new Unexpected("URLDecoder does not support UTF-8", e); + } + } + + static NameParser n = new NameParser(); + + static void corbalocT(String ior, OrbFunctional orb) + { + System.out.println(ior); + System.out.println(n.corbaloc(ior, orb)); + System.out.println(); + } + + public static void main(String[] args) + { + try + { + OrbFunctional orb = (OrbFunctional) ORB.init(args, null); + corbalocT("corbaloc:iiop:1.3@155axyz.com/Prod/aTradingService", orb); + corbalocT("corbaloc:iiop:2.7@255bxyz.com/Prod/bTradingService", orb); + corbalocT("corbaloc:iiop:355cxyz.com/Prod/cTradingService", orb); + corbalocT("corbaloc:iiop:2.7@255bxyz.com/Prod/bTradingService", orb); + corbalocT("corbaloc:iiop:355cxyz.com:7777/Prod/cTradingService", orb); + + corbalocT("corbaloc::556xyz.com:80/Dev/NameService", orb); + corbalocT("corbaloc:iiop:1.2@host1:3076/0", orb); + + corbalocT("corbaloc:rir:/NameService", orb); + corbalocT("corbaloc:rir:/", orb); + corbalocT("corbaloc:rir:", orb); + + corbalocT("corbaloc:rir:/NameService", orb); + corbalocT("corbaloc:rir:/", orb); + corbalocT("corbaloc:rir:", orb); + + corbalocT("corbaloc::555xyz.com,:556xyz.com:80/Dev/NameService", orb); + } + catch (BAD_PARAM e) + { + e.printStackTrace(System.out); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NameTransformer.java b/libjava/classpath/gnu/CORBA/NamingService/NameTransformer.java new file mode 100644 index 000000000..132c5dd8f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NameTransformer.java @@ -0,0 +1,326 @@ +/* NameTransformer.java -- + Copyright (C) 2005, 2006 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.NamingService; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.IntHolder; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContextPackage.InvalidName; + +import java.util.ArrayList; +import java.util.StringTokenizer; + +/** + * This class converts between string and array representations of the + * multi component object names. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameTransformer +{ + /** + * A string, indicating the escape character. + */ + public static final String ESCAPE = "\\"; + + /** + * Convert the string name representation into the array name + * representation. See {@link #toString(NameComponent)} for the + * description of this format. + * + * @param a_name the string form of the name. + * + * @return the array form of the name. + * + * @throws InvalidName if the name cannot be parsed. + */ + public NameComponent[] toName(String a_name) + throws InvalidName + { + ArrayList components = new ArrayList(); + StringTokenizer st = new StringTokenizer(a_name, "./\\", true); + + // Create the buffer array, reserving the last element for null. + String[] n = new String[ st.countTokens() + 1 ]; + + int pp = 0; + while (st.hasMoreTokens()) + n [ pp++ ] = st.nextToken(); + + IntHolder p = new IntHolder(); + + NameComponent node = readNode(p, n); + + while (node != null) + { + components.add(node); + node = readNode(p, n); + } + + NameComponent[] name = new NameComponent[ components.size() ]; + for (int i = 0; i < name.length; i++) + { + name [ i ] = (NameComponent) components.get(i); + } + + NameValidator.check(name); + + return name; + } + + /** + * Converts the name into its string representation, as defined in + * the specification CORBA naming service. + * + * A string representation for the name consists of the name components, + * separated by a slash '/' character (for example, 'a/b/c'). If the + * {@link NameComponent#kind} field is not empty, it is given after + * period ('.'), for example 'a.b/c.d/.' . + * The period alone represents node where part where both + * {@link NameComponent#kind} and {@link NameComponent#id} are empty strings. + * + * If slash or dot are part of the name, they are escaped by backslash ('\'). + * If the backslash itself is part of the name, it is doubled. + * + * @param a_name a name to convert. + * @return a string representation. + */ + public String toString(NameComponent[] a_name) + throws InvalidName + { + NameValidator.check(a_name); + + CPStringBuilder b = new CPStringBuilder(); + + NameComponent n; + + for (int ni = 0; ni < a_name.length; ni++) + { + n = a_name [ ni ]; + appEscaping(b, n.id); + if (n.kind.length() > 0) + { + b.append('.'); + appEscaping(b, n.kind); + } + + if (ni < a_name.length - 1) + b.append('/'); + } + return b.toString(); + } + + /** + * Append the contents of the string to this + * string buffer, inserting the escape sequences, where required. + * + * @param b a buffer to append the contents to. + * @param s a string to append. + */ + private void appEscaping(CPStringBuilder b, String s) + { + char c; + for (int i = 0; i < s.length(); i++) + { + c = s.charAt(i); + switch (c) + { + case '.' : + case '/' : + case '\\' : + b.append('\\'); + b.append(c); + break; + + default : + b.append(c); + break; + } + } + } + + /** + * Assert the end of the current name component. + */ + private void assertEndOfNode(IntHolder p, String[] t) + throws InvalidName + { + if (t [ p.value ] != null) + if (!t [ p.value ].equals("/")) + throw new InvalidName("End of node expected at token " + p.value); + } + + /** + * Read the named component node. After reading the current positon + * advances to the beginning of the next node in an array. + * + * @param p the current position being wrapped inside the passed + * IntHolder. + * + * @param t the text buffer. + * + * @return the created node. + */ + private NameComponent readNode(IntHolder p, String[] t) + throws InvalidName + { + // End of stream has been reached. + if (t [ p.value ] == null) + return null; + + NameComponent n = new NameComponent(); + + if (t [ p.value ].equals(".")) + { + // The 'id' is missing, but the 'kind' may follow. + n.id = ""; + p.value++; + n.kind = readPart(p, t); + assertEndOfNode(p, t); + if (t [ p.value ] != null) + p.value++; + } + else if (t [ p.value ].equals("/")) + { + // This is not allowed here and may happen only + // on two subsequent slashes. + throw new InvalidName("Unexpected '/' token " + p.value); + } + else + { + n.id = readPart(p, t); + + // If some chars follow the id. + if (t [ p.value ] != null) + { + // Dot means that the kind part follows + if (t [ p.value ].equals(".")) + { + p.value++; + n.kind = readPart(p, t); + assertEndOfNode(p, t); + if (t [ p.value ] != null) + p.value++; + } + + // The next name component follows - advance to + // the beginning of the next name component. + else if (t [ p.value ].equals("/")) + { + n.kind = ""; + p.value++; + } + else + throw new InvalidName("Unexpected '" + t [ p.value ] + + "' at token " + p.value + ); + } + else + + // Id, and then end of sequence. + n.kind = ""; + } + + return n; + } + + /** + * Read the name part (id or kind). + * + * @param p the current position. After reading, advances + * to the beginning of the next name fragment. + * + * @param t the string buffer. + * + * @return the name part with resolved escape sequences. + */ + private String readPart(IntHolder p, String[] t) + { + CPStringBuilder part = new CPStringBuilder(); + + while (t [ p.value ] != null && !t [ p.value ].equals(".") && + !t [ p.value ].equals("/") + ) + { + if (t [ p.value ].equals(ESCAPE)) + { + p.value++; + part.append(t [ p.value ]); + } + else + part.append(t [ p.value ]); + + p.value++; + } + + return part.toString(); + } + + public static void main(String[] args) + { + NameComponent a = new NameComponent("a", "ak"); + NameComponent b = new NameComponent("b/z", "b.k"); + NameComponent c = new NameComponent("c", ""); + + NameTransformer sn = new NameTransformer(); + + try + { + String s = sn.toString(new NameComponent[] { a, b, c }); + System.out.println(s); + + //NameComponent[] k = toName("a.k/b.k2/c/d/."); + //NameComponent[] k = toName("a.bc/.b/c.x"); + + NameComponent[] k = sn.toName(s); + System.out.println("ToString"); + + for (int i = 0; i < k.length; i++) + { + System.out.println(k [ i ].id + ":" + k [ i ].kind); + } + } + catch (InvalidName ex) + { + ex.printStackTrace(); + } + } + +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NameValidator.java b/libjava/classpath/gnu/CORBA/NamingService/NameValidator.java new file mode 100644 index 000000000..d7d5a14bb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NameValidator.java @@ -0,0 +1,79 @@ +/* NameValidator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.NamingService; + + +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContextPackage.InvalidName; + +/** + * Checks the given name for validity. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NameValidator +{ + /** + * Check the given name. This method must be package level, as it is + * not defined in the API. + * + * @param name the name to check. + * + * @throws InvalidName if the given name is not valid. + */ + public static void check(NameComponent[] name) + throws InvalidName + { + if (name == null) + throw new InvalidName("name=null"); + + if (name.length == 0) + throw new InvalidName("name.length=0"); + + for (int i = 0; i < name.length; i++) + { + if (name [ i ] == null) + throw new InvalidName("name[" + i + "]=null"); + if (name [ i ].id == null) + throw new InvalidName("name[" + i + "].id=null"); + if (name [ i ].kind == null) + throw new InvalidName("name[" + i + "].kind=null"); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NamingMap.java b/libjava/classpath/gnu/CORBA/NamingService/NamingMap.java new file mode 100644 index 000000000..40fef0a3a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NamingMap.java @@ -0,0 +1,190 @@ +/* NamingMap.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.NamingService; + +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContextPackage.AlreadyBound; +import org.omg.CosNaming.NamingContextPackage.InvalidName; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * The Naming Map maps the single names components into associated objects or + * naming contexts. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NamingMap +{ + /** + * The actual map. + */ + protected final TreeMap map; + + /** + * Creates an instance of the naming map, intialising the comparator + * to the {@link NameComponentComparator}. + */ + public NamingMap() + { + map = new TreeMap(NameComponentComparator.singleton); + } + + /** + * Put the given GIOP object, specifying the given name as a key. + * If the entry with the given name already exists, or if the given + * object is already mapped under another name, the + * {@link AlreadyBound} exception will be thrown. + * + * @param name the name + * @param object the object + */ + public void bind(NameComponent name, org.omg.CORBA.Object object) + throws AlreadyBound, InvalidName + { + if (containsKey(name)) + { + Object x = get(name); + + // Do not throw an exception if the same object is named by + // the same name. + if (x.equals(object)) + throw new AlreadyBound("The name is in use for another object"); + } + else + { + if (containsValue(object)) + throw new AlreadyBound("The object has another name"); + } + + // There are no restrictions in binding the object. + rebind(name, object); + } + + /** + * Checks if this map contains the definition of the given name. + * + * @param key the name to check. + */ + public boolean containsKey(NameComponent key) + { + return map.containsKey(key); + } + + /** + * Checks if this map contains the definition of the given object. + * + * @param object the object to check. + */ + public boolean containsValue(org.omg.CORBA.Object object) + { + return map.containsValue(object); + } + + /** + * Returns the map entry set. + * + * @return the map entry set, containing the instances of the + * Map.Entry. + */ + public Set entries() + { + return map.entrySet(); + } + + /** + * Get the CORBA object, associated with the given name. + * + * @param name the name. + * + * @return the associated object, null if none. + */ + public org.omg.CORBA.Object get(NameComponent name) + { + return (org.omg.CORBA.Object) map.get(name); + } + + /** + * Put the given GIOP object, specifying the given name as a key. + * Remove all pre - existing mappings for the given name and object. + * + * @param name the name. + * @param object + */ + public void rebind(NameComponent name, org.omg.CORBA.Object object) + throws InvalidName + { + // Remove the existing mapping for the given name, if present. + remove(name); + + Iterator iter = entries().iterator(); + Map.Entry item; + + // Remove the existing mapping for the given object, if present. + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + if (item.getValue().equals(object)) + iter.remove(); + } + + map.put(name, object); + } + + /** + * Removes the given name, if present. + * + * @param name a name to remove. + */ + public void remove(NameComponent name) + { + map.remove(name); + } + + /** + * Get the size of the map. + */ + public int size() + { + return map.size(); + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java new file mode 100644 index 000000000..5ccc4d8cc --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java @@ -0,0 +1,146 @@ +/* NamingServiceTransient.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.NamingService; + +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; + +import org.omg.CosNaming.NamingContextExt; + +import java.io.FileOutputStream; +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. + * + * 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>. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class NamingServiceTransient +{ + /** + * The default port (900), on that the naming service starts if no + * -ORBInitialPort is specified in the command line. + */ + public static final int PORT = 900; + + /** + * 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() + { + try + { // NameService + return "NameService".getBytes("UTF-8"); + } + catch (UnsupportedEncodingException ex) + { + throw new InternalError("UTF-8 unsupported"); + } + } + + /** + * Start the naming service on the current host at the given port. + * + * @param portArgument the port on which the service will be + * started, or -1 to use the default port, 900 + * @param fileArgument if non-null, store the IOR string of this + * naming service in a file by this name + */ + public static void start(int portArgument, String fileArgument) + { + int port = PORT; + + if (portArgument > -1) + port = portArgument; + + String iorf = fileArgument; + try + { + // Create and initialize the ORB + final OrbFunctional orb = new OrbFunctional(); + + OrbFunctional.setPort(port); + + // Create the servant and register it with the ORB + NamingContextExt namer = new Ext(new TransientContext()); + + // 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); + PrintStream p = new PrintStream(f); + p.print(ior); + p.close(); + } + + new Thread() + { + public void run() + { + // Wait for invocations from clients. + orb.run(); + } + }.start(); + } + catch (Exception e) + { + System.err.println("ERROR: " + e); + e.printStackTrace(System.err); + } + + // Restore the default value for allocating ports for the subsequent + // objects. + OrbFunctional.setPort(OrbFunctional.DEFAULT_INITIAL_PORT); + } +} diff --git a/libjava/classpath/gnu/CORBA/NamingService/TransientContext.java b/libjava/classpath/gnu/CORBA/NamingService/TransientContext.java new file mode 100644 index 000000000..6ed07d799 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/NamingService/TransientContext.java @@ -0,0 +1,443 @@ +/* nContext.java -- implementation of NamingContext + 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.NamingService; + +import org.omg.CORBA.Object; +import org.omg.CosNaming.Binding; +import org.omg.CosNaming.BindingIteratorHolder; +import org.omg.CosNaming.BindingListHolder; +import org.omg.CosNaming.BindingType; +import org.omg.CosNaming.NameComponent; +import org.omg.CosNaming.NamingContext; +import org.omg.CosNaming.NamingContextOperations; +import org.omg.CosNaming.NamingContextPackage.AlreadyBound; +import org.omg.CosNaming.NamingContextPackage.CannotProceed; +import org.omg.CosNaming.NamingContextPackage.InvalidName; +import org.omg.CosNaming.NamingContextPackage.NotEmpty; +import org.omg.CosNaming.NamingContextPackage.NotFound; +import org.omg.CosNaming.NamingContextPackage.NotFoundReason; +import org.omg.CosNaming._NamingContextImplBase; + +import gnu.CORBA.SafeForDirectCalls; + +import java.util.Iterator; +import java.util.Map; + +/** + * This class implements the transient naming service, defined by + * {@link NamingContext}. The 'transient' means that the service does + * not store its state into the persistent memory. If the service is + * restarted, the named objects must be re-registered again. + * + * TODO Write the persistent naming service. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class TransientContext + extends _NamingContextImplBase + implements NamingContext, NamingContextOperations, SafeForDirectCalls +{ + /** + * Use serial version UID for interoperability. + */ + private static final long serialVersionUID = 2; + + /** + * The already named contexts. + */ + protected final NamingMap named_contexts; + + /** + * The already named objects. + */ + protected final NamingMap named_objects; + + /** + * Create the naming conetxt with default (transient) naming maps. + */ + public TransientContext() + { + this(new NamingMap(), new NamingMap()); + } + + /** + * Create the naming conetxt with the two provided naming maps. + * + * @param context_map the map for contexts + * @param object_map the map for objectss + */ + public TransientContext(NamingMap context_map, NamingMap object_map) + { + named_contexts = context_map; + named_objects = object_map; + } + + /** + * Gives the object a name, valid in this context. + * + * @param a_name the name, being given to the object. + * @param an_object the object, being named. + * + * @throws AlreadyBound if the object is already named in this context. + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public void bind(NameComponent[] a_name, Object an_object) + throws NotFound, CannotProceed, InvalidName, AlreadyBound + { + if (a_name.length == 1) + named_objects.bind(a_name [ 0 ], an_object); + else + { + NamingContext context = + (NamingContext) named_contexts.get(a_name [ 0 ]); + context.bind(getSuffix(a_name), an_object); + } + } + + /** + * Gives a child context name, valid in this context. + * + * @param a_name the name, being given to the child context. + * @param a_context the child context being named. + * + * @throws AlreadyBound if the child context is already named in + * the current context. + */ + public void bind_context(NameComponent[] a_name, NamingContext a_context) + throws NotFound, CannotProceed, InvalidName, AlreadyBound + { + if (a_name.length == 1) + named_contexts.bind(a_name [ 0 ], a_context); + else + { + NamingContext context = + (NamingContext) named_contexts.get(a_name [ 0 ]); + context.bind_context(getSuffix(a_name), a_context); + } + } + + /** + * Create a new context and give it a given name (bound it) + * in the current context. + * + * The context being created is returned by calling + * {@link #new_context()}. + * + * @param a_name the name being given to the new context. + * + * @return the newly created context. + * + * @throws AlreadyBound if the name is already in use. + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public NamingContext bind_new_context(NameComponent[] a_name) + throws NotFound, AlreadyBound, CannotProceed, + InvalidName + { + if (named_contexts.containsKey(a_name [ 0 ]) || + named_objects.containsKey(a_name [ 0 ]) + ) + throw new AlreadyBound(); + + NamingContext child = new_context(); + bind_context(a_name, child); + return child; + } + + /** + * Destroy this context (must be empty). + * @throws NotEmpty if the context being destroyed is not empty. + */ + public void destroy() + throws NotEmpty + { + if (named_contexts.size() > 0 || named_objects.size() > 0) + throw new NotEmpty(); + } + + /** + * Iterate over all bindings, defined in this namind context. + * + * @param amount the maximal number of context to return in the + * holder a_list. The remaining bindings are accessible via iterator + * an_iter. If the parameter amount is zero, all bindings are accessed only + * via this iterator. + * + * This implementation list contexts first, then objects. + * + * @param a_list the holder, where the returned bindigs are stored. + * @param an_iter the iterator that can be used to access the remaining + * bindings. + */ + public void list(int amount, BindingListHolder a_list, + BindingIteratorHolder an_iter + ) + { + int nb = named_contexts.size() + named_objects.size(); + int nl = nb; + if (nl > amount) + nl = amount; + + a_list.value = new Binding[ nl ]; + + Iterator contexts = named_contexts.entries().iterator(); + Iterator objects = named_objects.entries().iterator(); + + // Create a binding list. + for (int i = 0; i < nl; i++) + { + if (contexts.hasNext()) + a_list.value [ i ] = mkBinding(contexts.next(), BindingType.ncontext); + else if (objects.hasNext()) + a_list.value [ i ] = mkBinding(objects.next(), BindingType.nobject); + else + throw new InternalError(); + } + + // Create an iterator. + Binding[] remainder = new Binding[ nb - nl ]; + int p = 0; + + while (contexts.hasNext()) + remainder [ p++ ] = mkBinding(contexts.next(), BindingType.ncontext); + + while (objects.hasNext()) + remainder [ p++ ] = mkBinding(objects.next(), BindingType.nobject); + + Binding_iterator_impl bit = new Binding_iterator_impl(remainder); + _orb().connect(bit); + an_iter.value = bit; + } + + /** + * Creates a new naming context, not bound to any name. + */ + public NamingContext new_context() + { + Ext context = new Ext(new TransientContext()); + + // Connect the context to the current ORB: + _orb().connect(context); + return context; + } + + /** + * Names or renames the object. + * + * @param a_name the new name, being given to the object + * in the scope of the current context. If the object is already + * named in this context, it is renamed. + * + * @param an_object the object, being named. + * + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public void rebind(NameComponent[] a_name, Object an_object) + throws NotFound, CannotProceed, InvalidName + { + if (a_name.length == 1) + named_objects.rebind(a_name [ 0 ], an_object); + else + { + NamingContext context = + (NamingContext) named_contexts.get(a_name [ 0 ]); + context.rebind(getSuffix(a_name), an_object); + } + } + + /** + * Names or renames the child context. + * If the child context is already named in + * the current context, it is renamed. The the name being given is in + * use, the old meaning of the name is discarded. + * + * @param a_name the name, being given to the child context in the scope + * of the current context. + * + * @param a_context the child context being named. + * + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public void rebind_context(NameComponent[] a_name, NamingContext a_context) + throws NotFound, CannotProceed, InvalidName + { + if (a_name.length == 1) + named_contexts.rebind(a_name [ 0 ], a_context); + else + { + NamingContext context = + (NamingContext) named_contexts.get(a_name [ 0 ]); + context.rebind_context(getSuffix(a_name), a_context); + } + } + + /** + * Get the object, bound to the specified name in this + * context. The given object must match the bound + * name. + * + * This implementation resolves the names as defined in specification + * of the CORBA naming service. This means, if the beginning of the + * name can be resolved to some naming context, the request is + * forwarded to this context, passing the unresolved name part as a + * parameter. In this way, it is possible to have a hierarchy of the + * naming services. The central services resolve the the beginning + * of the name. The local services resolve the remaining nodes of the + * name that may be relevant to some local details. It can be three or + * more ranks of the naming services. + * + * @param a_name the object name. + * + * @return the object, matching this name. The client + * usually casts or narrows (using the helper) the returned value + * to the more specific type. + * + * @throws NotFound if the name cannot be resolved. + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public Object resolve(NameComponent[] a_name) + throws NotFound, CannotProceed, InvalidName + { + NameValidator.check(a_name); + + if (a_name.length > 1) + return resolveSubContext(a_name); + else + { + // A single node name. + org.omg.CORBA.Object object; + + object = named_objects.get(a_name [ 0 ]); + if (object != null) + return object; + + object = named_contexts.get(a_name [ 0 ]); + if (object != null) + return object; + } + + throw new NotFound(NotFoundReason.missing_node, a_name); + } + + /** + * Removes the name from the binding context. + * + * @param a_name a name to remove. + * + * @throws InvalidName if the name has zero length or otherwise invalid. + */ + public void unbind(NameComponent[] a_name) + throws NotFound, CannotProceed, InvalidName + { + NameValidator.check(a_name); + + // Single node name - handle it. + if (a_name.length == 1) + { + if (named_objects.containsKey(a_name [ 0 ])) + named_objects.remove(a_name [ 0 ]); + else if (named_contexts.containsKey(a_name [ 0 ])) + named_contexts.remove(a_name [ 0 ]); + else + throw new NotFound(NotFoundReason.missing_node, a_name); + } + else + { + // Handle the first node and forward the command. + NamingContext subcontext = + (NamingContext) named_contexts.get(a_name [ 0 ]); + + if (subcontext == null) + throw new NotFound(NotFoundReason.missing_node, a_name); + + subcontext.unbind(getSuffix(a_name)); + } + } + + /** + * Get the name suffix, discarding the first member. + */ + private NameComponent[] getSuffix(NameComponent[] a_name) + { + NameComponent[] suffix = new NameComponent[ a_name.length - 1 ]; + System.arraycopy(a_name, 1, suffix, 0, suffix.length); + return suffix; + } + + /** + * Create a binding. + * + * @param an_entry the entry, defining the bound object. + * @param type the binding type. + * @return the created binding. + */ + private Binding mkBinding(java.lang.Object an_entry, BindingType type) + { + Map.Entry entry = (Map.Entry) an_entry; + Binding b = new Binding(); + + // The name component has always only one node (the current context) + b.binding_name = new NameComponent[] { (NameComponent) entry.getKey() }; + b.binding_type = type; + return b; + } + + /** + * Find the context, bound to the first name of the given + * name, and pass the remainder (without the first node) + * of the name for that context to resolve. + * + * @param a_name the name to resolve. + * + * @return the resolved context + */ + private Object resolveSubContext(NameComponent[] a_name) + throws NotFound, CannotProceed, InvalidName + { + // A multiple node name. + // This context resolves the first node only. + NamingContext context = (NamingContext) named_contexts.get(a_name [ 0 ]); + if (context == null) + throw new NotFound(NotFoundReason.missing_node, a_name); + + NameComponent[] suffix = getSuffix(a_name); + + return context.resolve(suffix); + } +} diff --git a/libjava/classpath/gnu/CORBA/ObjectCreator.java b/libjava/classpath/gnu/CORBA/ObjectCreator.java new file mode 100644 index 000000000..292495a1f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ObjectCreator.java @@ -0,0 +1,590 @@ +/* ObjectCreator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.UnknownExceptionCtxHandler; +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.CDR.AbstractCdrInput; +import gnu.CORBA.GIOP.ServiceContext; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.classpath.VMStackWalker; + +import org.omg.CORBA.Any; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.CompletionStatusHelper; +import org.omg.CORBA.MARSHAL; +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.IDLEntity; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ValueBase; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.rmi.CORBA.Util; + +/** + * 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) + */ +public class ObjectCreator +{ + /** + * The standard OMG prefix. + */ + public static final String OMG_PREFIX = "omg.org/"; + + /** + * The standard java prefix. + */ + public static final String JAVA_PREFIX = "org.omg."; + + /** + * The prefix for classes that are placed instide the gnu.CORBA namespace. + */ + public static final String CLASSPATH_PREFIX = "gnu.CORBA."; + + /** + * Maps classes to they IDL or RMI names. Computing RMI name is an expensive + * operations, so frequently used RMI keys are reused. The map must be weak to + * ensure that the class can be unloaded, when applicable. + */ + public static Map m_names = new WeakHashMap(); + + /** + * Maps IDL strings into known classes. The map must be weak to ensure that + * the class can be unloaded, when applicable. + */ + public static Map m_classes = new WeakHashMap(); + + /** + * Maps IDL types to they helpers. + */ + public static Map m_helpers = new WeakHashMap(); + + /** + * 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. + */ + public static java.lang.Object createObject(String idl, String suffix) + { + synchronized (m_classes) + { + Class known = (Class) (suffix == null ? m_classes.get(idl) + : m_classes.get(idl + 0xff + suffix)); + Object object; + + if (known != null) + { + try + { + return known.newInstance(); + } + catch (Exception ex) + { + RuntimeException rex = new RuntimeException(idl + " suffix " + + suffix, ex); + throw rex; + } + } + else + { + if (suffix == null) + suffix = ""; + try + { + known = forName(toClassName(JAVA_PREFIX, idl) + suffix); + object = known.newInstance(); + } + catch (Exception ex) + { + try + { + known = forName(toClassName(CLASSPATH_PREFIX, idl) + + suffix); + object = known.newInstance(); + } + catch (Exception exex) + { + return null; + } + } + m_classes.put(idl + 0xff + suffix, known); + return object; + } + } + } + + /** + * Read the system exception from the given stream. + * + * @param input the CDR stream to read from. + * @param contexts the service contexts in request/reply header/ + * + * @return the exception that has been stored in the stream (IDL name, minor + * code and completion status). + */ + public static SystemException readSystemException(InputStream input, + ServiceContext[] contexts) + { + SystemException exception; + + String idl = input.read_string(); + int minor = input.read_ulong(); + CompletionStatus completed = CompletionStatusHelper.read(input); + + try + { + exception = (SystemException) createObject(idl, null); + exception.minor = minor; + exception.completed = completed; + } + catch (Exception ex) + { + UNKNOWN u = new UNKNOWN("Unsupported system exception " + idl, minor, + completed); + u.initCause(ex); + throw u; + } + + try + { + // If UnknownExceptionInfo is present in the contexts, read it and + // set as a cause of this exception. + ServiceContext uEx = ServiceContext.find( + ServiceContext.UnknownExceptionInfo, contexts); + + if (uEx != null) + { + BufferredCdrInput in = new BufferredCdrInput(uEx.context_data); + in.setOrb(in.orb()); + if (input instanceof AbstractCdrInput) + { + ((AbstractCdrInput) input).cloneSettings(in); + } + + Throwable t = UnknownExceptionCtxHandler.read(in, contexts); + exception.initCause(t); + } + } + catch (Exception ex) + { + // Unsupported context format. Do not terminate as the user program may + // not need it. + } + + return exception; + } + + /** + * 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. + * @param input the stream to read from. + * + * @return the loaded exception. + * @return null if the helper class cannot be found. + */ + public static UserException readUserException(String idl, InputStream input) + { + try + { + Class helperClass = findHelper(idl); + + Method read = helperClass.getMethod("read", + new Class[] { org.omg.CORBA.portable.InputStream.class }); + + return (UserException) read.invoke(null, new Object[] { input }); + } + catch (MARSHAL mex) + { + // This one is ok to throw + throw mex; + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } + } + + /** + * Gets the helper class name from the string like + * 'IDL:test/org/omg/CORBA/ORB/communication/ourUserException:1.0' + * + * @param IDL the idl name. + */ + public static String toHelperName(String IDL) + { + String s = IDL; + int a = s.indexOf(':') + 1; + int b = s.lastIndexOf(':'); + + s = IDL.substring(a, b); + + if (s.startsWith(OMG_PREFIX)) + s = JAVA_PREFIX + s.substring(OMG_PREFIX.length()); + + return s.replace('/', '.') + "Helper"; + } + + /** + * Writes the system exception data to CDR output stream. + * + * @param output a stream to write data to. + * @param ex an exception to write. + */ + public static void writeSystemException(OutputStream output, + SystemException ex) + { + String exIDL = getRepositoryId(ex.getClass()); + output.write_string(exIDL); + output.write_ulong(ex.minor); + CompletionStatusHelper.write(output, ex.completed); + } + + /** + * Converts the given IDL name to class name. + * + * @param IDL the idl name. + * + */ + protected static String toClassName(String prefix, String IDL) + { + String s = IDL; + int a = s.indexOf(':') + 1; + int b = s.lastIndexOf(':'); + + s = IDL.substring(a, b); + + if (s.startsWith(OMG_PREFIX)) + s = prefix + s.substring(OMG_PREFIX.length()); + + return s.replace('/', '.'); + } + + /** + * 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. + * + * @return the matching class or null if no such is available. + */ + public static Class Idl2class(String IDL) + { + synchronized (m_classes) + { + Class c = (Class) m_classes.get(IDL); + + if (c != null) + return c; + else + { + String s = IDL; + int a = s.indexOf(':') + 1; + int b = s.lastIndexOf(':'); + + s = IDL.substring(a, b); + + if (s.startsWith(OMG_PREFIX)) + s = JAVA_PREFIX + s.substring(OMG_PREFIX.length()); + + String cn = s.replace('/', '.'); + + try + { + c = forName(cn); + m_classes.put(IDL, c); + return c; + } + catch (ClassNotFoundException ex) + { + return null; + } + } + } + } + + /** + * 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. + * + * @return instantiated object instance or null if such attempt was not + * successful. + */ + public static java.lang.Object Idl2Object(String IDL) + { + Class cx = Idl2class(IDL); + + try + { + if (cx != null) + return cx.newInstance(); + else + return null; + } + catch (Exception ex) + { + return null; + } + } + + /** + * Convert the class name to IDL or RMI name (repository id). If the class + * inherits from IDLEntity, ValueBase or SystemException, returns repository + * Id in the IDL:(..) form. If it does not, returns repository Id in the + * RMI:(..) form. + * + * @param cx the class for that the name must be computed. + * + * @return the idl or rmi name. + */ + public static synchronized String getRepositoryId(Class cx) + { + String name = (String) m_names.get(cx); + if (name != null) + return name; + + String cn = cx.getName(); + if (!(IDLEntity.class.isAssignableFrom(cx) + || ValueBase.class.isAssignableFrom(cx) || SystemException.class.isAssignableFrom(cx))) + { + // Not an IDL entity. + name = Util.createValueHandler().getRMIRepositoryID(cx); + } + else + { + if (cn.startsWith(JAVA_PREFIX)) + cn = OMG_PREFIX + + cn.substring(JAVA_PREFIX.length()).replace('.', '/'); + else if (cn.startsWith(CLASSPATH_PREFIX)) + cn = OMG_PREFIX + + cn.substring(CLASSPATH_PREFIX.length()).replace('.', '/'); + + name = "IDL:" + cn + ":1.0"; + } + m_names.put(cx, name); + return name; + } + + /** + * 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 = 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 + { + BufferedCdrOutput output = new BufferedCdrOutput(); + + String m_exception_id = getRepositoryId(exception.getClass()); + output.write_string(m_exception_id); + output.write_ulong(exception.minor); + CompletionStatusHelper.write(output, exception.completed); + + String name = getDefaultName(m_exception_id); + + GeneralHolder h = new GeneralHolder(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"); + } + + /** + * Find helper for the class with the given name. + */ + public static Class findHelper(String idl) + { + synchronized (m_helpers) + { + Class c = (Class) m_helpers.get(idl); + if (c != null) + return c; + try + { + String helper = toHelperName(idl); + c = forName(helper); + + m_helpers.put(idl, c); + return c; + } + catch (Exception ex) + { + return null; + } + } + } + + /** + * Load the class with the given name. This method tries to use the context + * class loader first. If this fails, it searches for the suitable class + * loader in the caller stack trace. This method is a central point where all + * requests to find a class by name are delegated. + */ + public static Class forName(String className) throws ClassNotFoundException + { + try + { + return Class.forName(className, true, + Thread.currentThread().getContextClassLoader()); + } + catch (ClassNotFoundException nex) + { + /** + * Returns the first user defined class loader on the call stack, or + * null when no non-null class loader was found. + */ + Class[] ctx = VMStackWalker.getClassContext(); + for (int i = 0; i < ctx.length; i++) + { + // Since we live in a class loaded by the bootstrap + // class loader, getClassLoader is safe to call without + // needing to be wrapped in a privileged action. + ClassLoader cl = ctx[i].getClassLoader(); + try + { + if (cl != null) + return Class.forName(className, true, cl); + } + catch (ClassNotFoundException nex2) + { + // Try next. + } + } + } + throw new ClassNotFoundException(className); + } +} diff --git a/libjava/classpath/gnu/CORBA/OctetHolder.java b/libjava/classpath/gnu/CORBA/OctetHolder.java new file mode 100644 index 000000000..06d7538d7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/OctetHolder.java @@ -0,0 +1,129 @@ +/* OctetHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.typecodes.PrimitiveTypeCode; + +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; + +/** + * A holder for CORBA <code>octet</code> that is mapped into + * java <code>long</code>. + * + * The holders have several application areas. The end user usually + * sees them implementing CORBA methods where the primitive type + * is passed by reference. While CORBA (or, for example, C) supports + * this, the java does not and a wrapper class is required. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public final class OctetHolder + implements Streamable +{ + /** + * The default type code for this holder. + */ + private static final TypeCode t_octet = + new PrimitiveTypeCode(TCKind.tk_octet); + + /** + * The <code>long</code> (CORBA <code>octet</code>) value, + * held by this OctetHolder. + */ + public byte value; + + /** + * Constructs an instance of OctetHolder, + * initializing {@link #value} to <code>0 </code>. + */ + public OctetHolder() + { + } + + /** + * Constructs an instance of OctetHolder, + * initializing {@link #value} to the given <code>octed</code> (byte). + * + * @param initial_value a value that will be assigned to the + * {@link #value} field. + */ + public OctetHolder(byte initial_value) + { + value = initial_value; + } + + /** + * Fill in the {@link value } field by reading the required data + * from the given stream. For <code>octet</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.InputStream#read_octet}. + * + * @param input the input stream to read from. + */ + public void _read(InputStream input) + { + value = input.read_octet(); + } + + /** + * Returns the TypeCode, corresponding the CORBA type that is stored + * using this holder. + */ + public TypeCode _type() + { + return t_octet; + } + + /** + * Write the {@link value } field to the given stream. + * For <code>octet</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.OutputStream#write_octet(long) }. + * + * @param output the output stream to write into. + */ + public void _write(OutputStream output) + { + output.write_octet(value); + } +} diff --git a/libjava/classpath/gnu/CORBA/OrbFocused.java b/libjava/classpath/gnu/CORBA/OrbFocused.java new file mode 100644 index 000000000..de5d49e36 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/OrbFocused.java @@ -0,0 +1,375 @@ +/* OrbFocused.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.Poa.ORB_1_4; + +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.NO_RESOURCES; +import org.omg.CORBA.portable.InvokeHandler; + +import java.applet.Applet; +import java.net.ServerSocket; +import java.util.Iterator; +import java.util.Properties; +import java.util.Random; +import java.util.StringTokenizer; + +/** + * This class implements the ORB that uses a single port or the restricted port + * range for all its objects. It is required to for use together with various + * firewalls that does not allow opening multiple randomly selected ports, as + * the defauld CORBA implementation used to do. The firewal must be configured + * to allow CORBA to work on one fixed port or (for better performance) on a + * small fixed range of ports. This does not restrict the maximal number of the + * connected objects as the objects can share the same port. + * + * The used port or the used port range can be specified via property + * gnu.CORBA.ListenerPort. The value of this property is a single port or range + * of ports, boundary values (inclusive) being separeted by dash (for instance, + * "1245-1250"). + * + * It is possible to instantiate multiple instances of the focused ORBs and + * combine them with the ordinary ORBs. If you instantiate several instances of + * the focused ORBs on the same host, they used port sets should not overlap. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class OrbFocused + extends ORB_1_4 +{ + /** + * The name of the fixed port range property. The presence of this property + * indicates that the default focused ORB must be used. + */ + public static final String LISTENER_PORT = "gnu.CORBA.ListenerPort"; + + /** + * The start of the range of the available ports, inclusive. + */ + int m_ports_from = -1; + + /** + * The end of the range of the available ports, inclusive. + */ + int m_ports_to = -1; + + /** + * The requests to port are served in parallel threads. + */ + static final int PARALLEL = 0; + + /** + * The requests to port are served in the same thread. + */ + static final int SEQUENTIAL = 1; + + /** + * The random number generator to get a random port in the valid range. + */ + Random m_random = new Random(); + + /** + * Parse the "gnu.CORBA.ListenerPort" property and initialize the valid port + * set range. + */ + public void setPortRange(String property) + { + int from, to; + try + { + StringTokenizer st = new StringTokenizer(property, " -"); + if (st.countTokens() == 1) + from = to = Integer.parseInt(st.nextToken()); + else + { + from = Integer.parseInt(st.nextToken()); + to = Integer.parseInt(st.nextToken()); + m_random = new Random(); + } + setPortRange(from, to); + } + catch (Exception ex) + { + throw new BAD_PARAM("Unable to parse port range '" + property + "'"); + } + } + + /** + * Set the port range. + * + * @param from - start of the port range, inclusive. + * @param to - end of the port range, inclusive. + */ + public void setPortRange(int from, int to) + { + if (from < 0 || to < 0 || to < from) + throw new BAD_PARAM("Invalid range"); + m_ports_from = from; + m_ports_to = to; + } + + /** + * Get the port from the previously specified usage range. + */ + int getPortFromRange(int attempt) + { + if (m_ports_from == m_ports_to) + return m_ports_from; + else if (m_ports_to - m_ports_from < RANDOM_PORT_ATTEMPTS) + return m_ports_from + (attempt % (m_ports_to - m_ports_from + 1)); + else + return m_random.nextInt(m_ports_to - m_ports_from + 1) + m_ports_from; + } + + /** + * Get the shared port server where the new object can be added. This may + * result reusing the existing server or instantiating a new server. If the + * new server is instantiated and the ORB is already running, the server is + * started. + */ + protected portServer getPortServer(int type) + { + portServer p; + + int n; + if (m_ports_from < m_ports_to) + n = RANDOM_PORT_ATTEMPTS; + else + n = 1; + + Ports: for (int a = 0; a < n; a++) + { + int port = getPortFromRange(a); + for (int i = 0; i < portServers.size(); i++) + { + p = (portServer) portServers.get(i); + if (p.s_port == port) + { + return p; + } + } + // The server is not yet instantiated. Instantiate. + try + { + // Check if the port is ok: + ServerSocket s = socketFactory.createServerSocket(port); + s.close(); + + portServer shared; + + switch (type) + { + case PARALLEL: + shared = new portServer(port); + break; + + case SEQUENTIAL: + shared = new sharedPortServer(port); + break; + + default: + throw new InternalError("Invalid server type " + type); + } + + portServers.add(shared); + + if (running) + shared.start(); + + return shared; + } + catch (Exception ex) + { + // Port is taken or probably other problems. + continue Ports; + } + } + throw new NO_RESOURCES("No free port available at " + m_ports_from + "-" + + m_ports_to, Minor.Ports, CompletionStatus.COMPLETED_NO); + } + + /** + * 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)}. + */ + public void run() + { + if (m_ports_from < 0 || m_ports_to < 0) + throw new BAD_INV_ORDER("For " + getClass().getName() + " " + + LISTENER_PORT + " property must be set"); + + running = true; + + // Start all port servers. In the current subclass, the portServers + // collection must be already filled in. + Iterator iter = portServers.iterator(); + + while (iter.hasNext()) + { + portServer subserver = (portServer) iter.next(); + + if (!subserver.isAlive()) + { + // Reuse the current thread for the last portServer. + if (!iter.hasNext()) + { + // Discard the iterator. + iter = null; + subserver.run(); + return; + } + else + subserver.start(); + } + } + } + + /** + * Get free port from the allowed range. This method instantiates the port + * server for the returned port. + */ + public int getFreePort() + throws BAD_OPERATION + { + portServer s = getPortServer(PARALLEL); + return s.s_port; + } + + /** + * 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) + { + shared = (sharedPortServer) getPortServer(SEQUENTIAL); + identities.put(identity, shared); + if (running) + { + shared.start(); + } + } + + Connected_objects.cObject ref = connected_objects.add(key, object, + shared.s_port, identity); + IOR ior = createIOR(ref); + prepareObject(object, ior); + } + + /** + * In this type of ORB, the service is started by {@link #getPortServer}. The + * method below is not in use and should return without action. + */ + public void startService(IOR ior) + { + } + + /** + * Set parameters (additionally search for the port range property). + */ + protected void set_parameters(Applet applet, Properties props) + { + super.set_parameters(applet, props); + String lp = applet.getParameter(LISTENER_PORT); + if (lp != null) + setPortRange(lp); + } + + /** + * Set parameters (additionally search for the port range property). + */ + protected void set_parameters(String[] args, Properties props) + { + super.set_parameters(args, props); + String lp = null; + + String lpKey = "-" + LISTENER_PORT; + + if (args != null) + if (args.length >= 2) + { + for (int i = 0; i < args.length - 1; i++) + if (args[i].equals(lpKey)) + lp = args[i + 1]; + } + + if (lp != null) + setPortRange(lp); + + } + + /** + * Additionally set the port range property, when applicable. + */ + protected void useProperties(Properties props) + { + super.useProperties(props); + String lp = props.getProperty(LISTENER_PORT); + if (lp != null) + setPortRange(lp); + } + +} diff --git a/libjava/classpath/gnu/CORBA/OrbFunctional.java b/libjava/classpath/gnu/CORBA/OrbFunctional.java new file mode 100644 index 000000000..88848dd1b --- /dev/null +++ b/libjava/classpath/gnu/CORBA/OrbFunctional.java @@ -0,0 +1,1794 @@ +/* OrbFunctional.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.UnknownExceptionCtxHandler; +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +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.NamingService.NameParser; +import gnu.CORBA.NamingService.NamingServiceTransient; +import gnu.CORBA.Poa.gnuForwardRequest; +import gnu.CORBA.interfaces.SocketFactory; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_RESOURCES; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.Request; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.UNKNOWN; +import org.omg.CORBA.WrongTransaction; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.UnknownException; +import org.omg.CosNaming.NamingContextExt; +import org.omg.CosNaming.NamingContextExtHelper; + +import java.applet.Applet; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +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; +import java.util.Properties; +import java.util.Random; +import java.util.StringTokenizer; +import java.util.TreeMap; + +/** + * The ORB implementation, capable to handle remote invocations on the + * 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 OrbFunctional extends OrbRestricted +{ + /** + * 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. + */ + protected class portServer + extends Thread + { + /** + * The number of the currently running parallel threads. + */ + int running_threads; + + /** + * The port on that this portServer is listening for requests. + */ + int s_port; + + /** + * The server socket of this portServer. + */ + ServerSocket service; + + /** + * True if the serving node must shutdown due call of the close_now(). + */ + boolean terminated; + + /** + * Create a new portServer, serving on specific port. + */ + portServer(int _port) + { + s_port = _port; + setDaemon(true); + try + { + service = socketFactory.createServerSocket(s_port); + } + catch (IOException ex) + { + BAD_OPERATION bad = new BAD_OPERATION( + "Unable to open the server socket at " + s_port); + bad.minor = Minor.Socket; + bad.initCause(ex); + throw bad; + } + } + + /** + * Enter the serving loop (get request/process it). All portServer normally + * terminate thy threads when the OrbFunctional.running is set to false. + */ + public void run() + { + while (running) + { + try + { + tick(); + } + catch (SocketException ex) + { + // May be thrown when the service is closed by + // the close_now(). + if (terminated) + return; + } + catch (Exception iex) + { + // Wait. Do not terminate the + // service due potentially transient error. + try + { + Thread.sleep(TWAIT_SERVER_ERROR_PAUSE); + } + catch (InterruptedException ex) + { + } + } + } + } + + /** + * 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() + { + try + { + terminated = true; + service.close(); + } + catch (Exception ex) + { + // This may happen if the service has not been opened or + // cannot be closed. Return without action. + } + } + + /** + * If the thread is no longer in use, close the socket (if opened). + */ + protected void finalize() + { + close_now(); + } + } + + /** + * A server, responsible for listening on requests on some local port and + * serving multiple requests (probably to the different objects) on the same + * thread. + */ + protected 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; + + /** + * When trying to open the socket on a random port, start of the interval to + * try. + */ + public static int RANDOM_PORT_FROM = 1024; + + /** + * When trying to open the socket on a random port, end of the interval to + * try. + */ + public static int RANDOM_PORT_TO = 4024; + + /** + * The number of attempts to try when opening random port. + */ + public static int RANDOM_PORT_ATTEMPTS = 64; + + /** + * 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"; + + /** + * The property, defining the IOR of the intial reference to resolve. + */ + public static final String REFERENCE = "org.omg.CORBA.ORBInitRef"; + + /** + * 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. + */ + public static final String NS_HOST = "org.omg.CORBA.ORBInitialHost"; + + /** + * The string, defining the naming service initial reference. + */ + public static final String NAME_SERVICE = "NameService"; + + /** + * Defines the ORB ID that is accessible by IOR interceptors. + */ + public static final String ORB_ID = "org.omg.CORBA.ORBid"; + + + /** + * Defines the SERVER ID that is accessible by IOR interceptors. + */ + public static final String SERVER_ID = "org.omg.CORBA.ServerId"; + + /** + * 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. + */ + 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. + */ + public static String AFTER_RECEIVING = + "gnu.classpath.CORBA.TOUT_AFTER_RECEIVING"; + + /** + * The server waits for this duration after the potentially transient error + * during its servicing cycle. + */ + public static String SERVER_ERROR_PAUSE = + "gnu.classpath.CORBA.SERVER_ERROR_PAUSE"; + + /** + * The address of the local host. + */ + 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. + */ + public 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. + */ + public 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. + */ + public int TOUT_AFTER_RECEIVING = 40 * 60 * 1000; + + /** + * The server waits for this duration after the potentially transient error + * during its servicing cycle. + */ + public int TWAIT_SERVER_ERROR_PAUSE = 5000; + + /** + * 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 Id of this ORB. + */ + public String orb_id = "orb_"+hashCode(); + + /** + * The Id of this Server. This field is defined static to ensure it has + * the same value over all ORB's in this machine. + */ + public static String server_id = "server_"+OrbFunctional.class.hashCode(); + + /** + * The map of the already conncted 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. + */ + protected Version max_version; + + /** + * 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. + */ + protected Map initial_references = new TreeMap(); + + /** + * The currently active portServers. + */ + protected ArrayList portServers = new ArrayList(); + + /** + * The host, on that the name service is expected to be running. + */ + 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. + */ + private static int Port = DEFAULT_INITIAL_PORT; + + /** + * 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 + * invocations. + */ + protected Asynchron asynchron = new Asynchron(); + + /** + * The list of the freed ports. The ORB reuses ports, when possible. + */ + protected LinkedList freed_ports = new LinkedList(); + + /** + * 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; + + /** + * The producer of the client and server sockets for this ORB. + */ + public SocketFactory socketFactory = DefaultSocketFactory.Singleton; + + /** + * Create the instance of the Functional ORB. + */ + public OrbFunctional() + { + try + { + LOCAL_HOST = ns_host = InetAddress.getLocalHost().getHostAddress(); + initial_references.put("CodecFactory", new gnuCodecFactory(this)); + } + catch (UnknownHostException ex) + { + BAD_OPERATION bad = + new BAD_OPERATION("Unable to open the server socket."); + bad.initCause(ex); + throw bad; + } + } + + /** + * 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. + */ + public Version getMaxVersion() + { + return max_version; + } + + /** + * 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. + */ + public int getFreePort() + throws BAD_OPERATION + { + ServerSocket s; + int a_port; + + try + { + // If there are some previously freed ports, use them first. + if (!freed_ports.isEmpty()) + { + Integer free = (Integer) freed_ports.getLast(); + freed_ports.removeLast(); + s = socketFactory.createServerSocket(free.intValue()); + s.close(); + return free.intValue(); + } + } + catch (Exception ex) + { + // This may be thrown if the request for the new port has arrived + // before the current service is completly shutdown. + // OK then, use a new port. + } + + for (a_port = Port; a_port < Port + 20; a_port++) + { + try + { + s = socketFactory.createServerSocket(a_port); + s.close(); + Port = a_port + 1; + return a_port; + } + catch (IOException ex) + { + // Repeat the loop if this exception has been thrown. + } + } + + Random rand = new Random(); + // Try any random port in the interval RANDOM_PORT_FROM.RANDOM_PORT_TO. + int range = RANDOM_PORT_TO - RANDOM_PORT_FROM; + IOException ioex = null; + for (int i = 0; i < RANDOM_PORT_ATTEMPTS; i++) + { + try + { + a_port = RANDOM_PORT_FROM + rand.nextInt(range); + s = socketFactory.createServerSocket(a_port); + s.close(); + return a_port; + } + catch (IOException ex) + { + // Repeat the loop if this exception has been thrown. + ioex = ex; + } + } + + NO_RESOURCES bad = new NO_RESOURCES("Unable to open the server socket."); + bad.minor = Minor.Ports; + if (ioex != null) + bad.initCause(ioex); + throw bad; + } + + /** + * 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. + */ + public static void setPort(int a_Port) + { + Port = a_Port; + } + + /** + * 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. + * + * @param object the object, must implement the {@link InvokeHandler}) + * interface. + * + * @throws BAD_PARAM if the object does not implement the + * {@link InvokeHandler}). + */ + public void connect(org.omg.CORBA.Object object) + { + int a_port = getFreePort(); + + Connected_objects.cObject ref = connected_objects.add(object, a_port); + IOR ior = createIOR(ref); + prepareObject(object, ior); + if (running) + startService(ior); + } + + /** + * 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. + * + * @param object the object, must implement the {@link InvokeHandler}) + * interface. + * @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}). + */ + public void connect(org.omg.CORBA.Object object, byte[] key) + { + int a_port = getFreePort(); + + Connected_objects.cObject ref = + connected_objects.add(key, object, a_port, null); + IOR ior = createIOR(ref); + prepareObject(object, ior); + if (running) + startService(ior); + } + + /** + * 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). + */ + public void startService(IOR ior) + { + portServer p = new portServer(ior.Internet.port); + portServers.add(p); + p.start(); + } + + /** + * Destroy this server, releasing the occupied resources. + */ + public void 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. + * + * @param object the object to disconnect. + */ + public void disconnect(org.omg.CORBA.Object object) + { + Connected_objects.cObject rmKey = null; + + // Handle the case when it is possible to get the object key. + // Handle the case when the object is known, but not local. + if (object instanceof ObjectImpl) + { + Delegate delegate = ((ObjectImpl) object)._get_delegate(); + if (delegate instanceof SimpleDelegate) + { + byte[] key = ((SimpleDelegate) delegate).getIor().key; + rmKey = connected_objects.get(key); + } + } + + // Try to find and disconned the object that is not an instance of the + // object implementation. + if (rmKey == null) + rmKey = connected_objects.getKey(object); + if (rmKey != null) + { + // Find and stop the corresponding portServer. + portServer p; + StopService: + for (int i = 0; i < portServers.size(); i++) + { + p = (portServer) portServers.get(i); + if (p.s_port == rmKey.port && !(p instanceof sharedPortServer)) + { + p.close_now(); + freed_ports.addFirst(new Integer(rmKey.port)); + break StopService; + } + connected_objects.remove(rmKey.key); + } + } + } + + /** + * 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. + */ + public org.omg.CORBA.Object find_local_object(IOR ior) + { + // Must be the same host. + if (!ior.Internet.host.equals(LOCAL_HOST)) + return null; + + return find_connected_object(ior.key, ior.Internet.port); + } + + /** + * List the initially available CORBA objects (services). + * + * @return a list of services. + * + * @see resolve_initial_references(String) + */ + public String[] list_initial_services() + { + String[] refs = new String[ initial_references.size() ]; + int p = 0; + + Iterator iter = initial_references.keySet().iterator(); + while (iter.hasNext()) + { + 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. + * + * @param forObject 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. + * + * @see string_to_object(String) + */ + public String object_to_string(org.omg.CORBA.Object forObject) + { + // Handle the case when the object is known, but not local. + if (forObject instanceof ObjectImpl) + { + Delegate delegate = ((ObjectImpl) forObject)._get_delegate(); + if (delegate instanceof SimpleDelegate) + return ((SimpleDelegate) delegate).getIor().toStringifiedReference(); + } + + // Handle the case when the object is local. + Connected_objects.cObject rec = connected_objects.getKey(forObject); + + if (rec == null) + throw new BAD_PARAM("The object " + forObject + + " has not been previously connected to this ORB" + ); + + IOR ior = createIOR(rec); + + return ior.toStringifiedReference(); + } + + /** + * 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. + */ + public org.omg.CORBA.Object resolve_initial_references(String name) + throws InvalidName + { + org.omg.CORBA.Object object = null; + try + { + object = (org.omg.CORBA.Object) initial_references.get(name); + if (object == null && name.equals(NAME_SERVICE)) + { + object = getDefaultNameService(); + if (object != null) + initial_references.put(NAME_SERVICE, object); + } + } + catch (Exception ex) + { + InvalidName err = new InvalidName(name); + err.initCause(ex); + throw err; + } + if (object != null) + return object; + else + throw new InvalidName("Not found: '" + name + "'"); + } + + /** + * 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)}. + */ + public void run() + { + CollocatedOrbs.registerOrb(this); + try + { + running = true; + + // Instantiate the port server for each socket. + Iterator iter = connected_objects.entrySet().iterator(); + Map.Entry m; + Connected_objects.cObject obj; + + while (iter.hasNext()) + { + m = (Map.Entry) iter.next(); + obj = (Connected_objects.cObject) m.getValue(); + + portServer subserver; + + if (obj.identity == null) + { + subserver = new portServer(obj.port); + portServers.add(subserver); + } + else + 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(); + } + } + } + finally + { + CollocatedOrbs.unregisterOrb(this); + } + } + + /** + * Start the server in a new thread, if not already running. This method is + * used to ensure that the objects being transfered will be served from the + * remote side, if required. If the ORB is started using this method, it + * starts as a daemon thread. + */ + public void ensureRunning() + { + final OrbFunctional THIS = this; + + if (!running) + { + Thread t = new Thread() + { + public void run() + { + THIS.run(); + } + }; + t.setDaemon(true); + t.start(); + } + } + + /** + * Shutdown the ORB server. + * + * @param wait_for_completion if true, the current thread is suspended until + * the shutdown process is complete. + */ + public void shutdown(boolean wait_for_completion) + { + super.shutdown(wait_for_completion); + running = false; + + if (!wait_for_completion) + { + for (int i = 0; i < portServers.size(); i++) + { + portServer p = (portServer) portServers.get(i); + p.close_now(); + } + } + } + + /** + * 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 an_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) + { + 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) + { + // Check maybe the local object on another ORB, but same VM. + object = CollocatedOrbs.searchLocalObject(ior); + if (object == null) + { + // Surely remote object. + ObjectImpl impl = StubLocator.search(this, ior); + try + { + if (impl._get_delegate() == null) + impl._set_delegate(new IorDelegate(this, ior)); + } + catch (BAD_OPERATION ex) + { + // Some colaborants may throw this exception + // in response to the attempt to get the unset delegate. + impl._set_delegate(new IorDelegate(this, ior)); + } + + object = impl; + } + } + return object; + } + + /** + * 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); + + IOR ior = new IOR(); + ior.Id = NamingContextExtHelper.id(); + ior.Internet.host = ns_host; + ior.Internet.port = ns_port; + ior.key = NamingServiceTransient.getDefaultKey(); + + IorObject iorc = new IorObject(this, ior); + NamingContextExt namer = NamingContextExtHelper.narrow(iorc); + initial_references.put(NAME_SERVICE, namer); + return namer; + } + + /** + * 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. + * @param port the port where the object is connected. + * + * @return the connected object, null if none. + */ + protected org.omg.CORBA.Object find_connected_object(byte[] key, int port) + { + Connected_objects.cObject ref = connected_objects.get(key); + if (ref == null) + return null; + if (port >= 0 && ref.port != port) + return null; + else + return ref.object; + } + + /** + * Set the ORB parameters. This method is normally called from + * {@link #init(Applet, Properties)}. + * + * @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>. + */ + protected void set_parameters(Applet app, Properties props) + { + useProperties(props); + + String[][] para = app.getParameterInfo(); + if (para != null) + { + for (int i = 0; i < para.length; i++) + { + 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], "="); + initial_references.put(st.nextToken(), + string_to_object(st.nextToken())); + } + + if (para[i][0].equals(ORB_ID)) + orb_id = para[i][1]; + + if (para[i][0].equals(SERVER_ID)) + server_id = para[i][1]; + + 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)) + ns_port = Integer.parseInt(para[i][1]); + } + catch (NumberFormatException ex) + { + BAD_PARAM bad = new BAD_PARAM("Invalid " + NS_PORT + + "property, unable to parse '" + props.getProperty(NS_PORT) + + "'"); + bad.initCause(ex); + throw bad; + } + } + } + } + + /** + * 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 + * application. + * + * @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 != null) && 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]; + + if (para[i].endsWith("ServerId")) + server_id = para[i++]; + else if (para[i].endsWith("ORBid")) + orb_id = para[i++]; + + 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); + } + + /** + * 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; + ior.Internet.port = ref.port; + + if (ref.object instanceof ObjectImpl) + { + ObjectImpl imp = (ObjectImpl) ref.object; + if (imp._ids().length > 0) + ior.Id = imp._ids() [ 0 ]; + } + if (ior.Id == null) + ior.Id = ref.object.getClass().getName(); + + ior.Internet.host = CollocatedOrbs.localHost; + ior.Internet.port = ref.port; + + return ior; + } + + /** + * Prepare object for connecting it to this ORB. + * + * @param object the object being connected. + * + * @throws BAD_PARAM if the object does not implement the + * {@link InvokeHandler}). + */ + protected void prepareObject(org.omg.CORBA.Object object, IOR ior) + throws BAD_PARAM + { + /* + * 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) + { + ObjectImpl impl = (ObjectImpl) object; + try + { + if (impl._get_delegate() == null) + impl._set_delegate(new SimpleDelegate(this, ior)); + } + catch (BAD_OPERATION ex) + { + // Some colaborants may throw this exception. + impl._set_delegate(new SimpleDelegate(this, ior)); + } + } + } + + /** + * Write the response message. + * + * @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. + * + * @throws IOException + */ + private void respond_to_client(OutputStream net_out, + MessageHeader msh_request, RequestHeader rh_request, + ResponseHandlerImpl handler, SystemException sysEx + ) throws IOException + { + // Set the reply header properties. + ReplyHeader reply = handler.reply_header; + + if (sysEx != null) + reply.reply_status = ReplyHeader.SYSTEM_EXCEPTION; + else if (handler.isExceptionReply()) + reply.reply_status = ReplyHeader.USER_EXCEPTION; + else + reply.reply_status = ReplyHeader.NO_EXCEPTION; + reply.request_id = rh_request.request_id; + + BufferedCdrOutput out = + new BufferedCdrOutput(50 + handler.getBuffer().buffer.size()); + out.setOrb(this); + + out.setOffset(msh_request.getHeaderSize()); + + reply.write(out); + + 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(); + + msh_reply.version = msh_request.version; + msh_reply.message_type = MessageHeader.REPLY; + msh_reply.message_size = out.buffer.size(); + + // Write the reply. + msh_reply.write(net_out); + out.buffer.writeTo(net_out); + net_out.flush(); + } + + /** + * 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. + BufferedCdrOutput out = new BufferedCdrOutput(); + 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. + * + * @param serverSocket the ORB server socket. + * + * @throws MARSHAL + * @throws IOException + */ + void serve(final portServer p, ServerSocket serverSocket) + throws MARSHAL, IOException + { + final Socket service; + service = serverSocket.accept(); + + // Tell the server there are no more resources. + if (p.running_threads >= MAX_RUNNING_THREADS) + { + serveStep(service, true); + return; + } + + new Thread() + { + public void run() + { + try + { + synchronized (p) + { + p.running_threads++; + } + serveStep(service, false); + } + finally + { + synchronized (p) + { + p.running_threads--; + } + } + } + }.start(); + } + + /** + * 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. + * + * @param service the opened client socket. + * @param no_resources if true, the "NO RESOURCES" exception is thrown to the + * client. + */ + void serveStep(Socket service, boolean no_resources) + { + try + { + Serving: while (true) + { + InputStream in = service.getInputStream(); + service.setSoTimeout(TOUT_START_READING_MESSAGE); + + MessageHeader msh_request = new MessageHeader(); + + try + { + msh_request.read(in); + } + catch (MARSHAL ex) + { + // This exception may be thrown due closing the connection. + return; + } + + 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; + } + } + + byte[] r = msh_request.readMessage(in, service, TOUT_WHILE_READING, + TOUT_AFTER_RECEIVING); + + if (msh_request.message_type == MessageHeader.REQUEST) + { + RequestHeader rh_request; + + BufferredCdrInput cin = new BufferredCdrInput(r); + cin.setOrb(this); + cin.setVersion(msh_request.version); + cin.setOffset(msh_request.getHeaderSize()); + cin.setBigEndian(msh_request.isBigEndian()); + + rh_request = msh_request.create_request_header(); + + // Read header and auto set the charset. + rh_request.read(cin); + + // in 1.2 and higher, align the current position at + // 8 octet boundary. + if (msh_request.version.since_inclusive(1, 2)) + { + cin.align(8); + + // find the target object. + } + + InvokeHandler target = (InvokeHandler) find_connected_object( + rh_request.object_key, -1); + + // Prepare the reply header. This must be done in advance, + // as the size must be known for handler to set alignments + // correctly. + ReplyHeader rh_reply = msh_request.create_reply_header(); + + // TODO log errors about not existing objects and methods. + ResponseHandlerImpl handler = new ResponseHandlerImpl( + this, msh_request, rh_reply, rh_request); + + SystemException sysEx = null; + + try + { + if (no_resources) + { + NO_RESOURCES no = new NO_RESOURCES("Too many parallel calls"); + no.minor = Minor.Threads; + throw no; + } + if (target == null) + 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 (UnknownException uex) + { + sysEx = new UNKNOWN("Unknown", 2, + CompletionStatus.COMPLETED_MAYBE); + sysEx.initCause(uex.originalEx); + + org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply(); + + rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext( + rh_reply.service_context, uex.originalEx, ech); + + ObjectCreator.writeSystemException(ech, sysEx); + } + catch (SystemException ex) + { + sysEx = ex; + + org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply(); + + rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext( + rh_reply.service_context, ex, ech); + + ObjectCreator.writeSystemException(ech, ex); + } + catch (Exception except) + { + // This should never happen under normal operation and + // can only indicate errors in user object implementation. + // We inform the user. + except.printStackTrace(); + + sysEx = new UNKNOWN("Unknown", 2, + CompletionStatus.COMPLETED_MAYBE); + sysEx.initCause(except); + + org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply(); + + rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext( + rh_reply.service_context, except, ech); + + ObjectCreator.writeSystemException(ech, sysEx); + } + + // Write the response. + if (rh_request.isResponseExpected()) + { + OutputStream sou = service.getOutputStream(); + respond_to_client(sou, msh_request, rh_request, handler, + sysEx); + } + } + else if (msh_request.message_type == MessageHeader.CLOSE_CONNECTION + || msh_request.message_type == MessageHeader.MESSAGE_ERROR) + { + CloseMessage.close(service.getOutputStream()); + service.close(); + return; + } + + if (service != null && !service.isClosed()) + + // Wait for the subsequent invocations on the + // same socket for the TANDEM_REQUEST duration. + service.setSoTimeout(TANDEM_REQUESTS); + else + return; + } + } + catch (SocketException ex) + { + // OK. + return; + } + catch (IOException ioex) + { + // Network error, probably transient. + // TODO log it. + return; + } + finally + { + try + { + if (service!=null && !service.isClosed()) + service.close(); + } + catch (IOException ioex) + { + // OK. + } + } + } + + /** + * Set the ORB parameters from the properties that were accumulated + * from several locations. + */ + protected void useProperties(Properties props) + { + if (props != null) + { + 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)); + if (props.containsKey(SERVER_ERROR_PAUSE)) + TWAIT_SERVER_ERROR_PAUSE = + Integer.parseInt(props.getProperty(SERVER_ERROR_PAUSE)); + } + catch (NumberFormatException ex) + { + throw new BAD_PARAM("Invalid " + NS_PORT + + "property, unable to parse '" + props.getProperty(NS_PORT) + + "'" + ); + } + + if (props.containsKey(SocketFactory.PROPERTY)) + { + String factory = null; + try + { + factory = props.getProperty(SocketFactory.PROPERTY); + if (factory!=null) + socketFactory = (SocketFactory) + ObjectCreator.forName(factory).newInstance(); + } + catch (Exception ex) + { + BAD_PARAM p = new BAD_PARAM("Bad socket factory "+factory); + p.initCause(ex); + throw p; + } + } + + if (props.containsKey(ORB_ID)) + orb_id = props.getProperty(ORB_ID); + + if (props.containsKey(SERVER_ID)) + server_id = props.getProperty(SERVER_ID); + + Enumeration en = props.elements(); + while (en.hasMoreElements()) + { + String item = (String) en.nextElement(); + if (item.equals(REFERENCE)) + initial_references.put(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. + * + * 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. + */ + public Request get_next_response() throws org.omg.CORBA.WrongTransaction + { + return asynchron.get_next_response(); + } + + /** + * 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. + */ + public boolean poll_next_response() + { + return asynchron.poll_next_response(); + } + + /** + * 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. + * + * @see #poll_next_response() + * @see #get_next_response() + * @see Request#send_deferred() + */ + public void send_multiple_requests_deferred(Request[] requests) + { + asynchron.send_multiple_requests_deferred(requests); + } + + /** + * 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. + * + * @param requests the prepared array of requests. + * + * @see Request#send_oneway() + */ + public void send_multiple_requests_oneway(Request[] requests) + { + asynchron.send_multiple_requests_oneway(requests); + } + + /** + * Set the flag, forcing all server threads to terminate. + */ + protected void finalize() throws java.lang.Throwable + { + running = false; + super.finalize(); + } + + /** + * Get the number of objects that are connected to this ORB. + * + * @return the number of objects, connected to this ORB. + */ + public int countConnectedObjects() + { + return connected_objects.size(); + } +} diff --git a/libjava/classpath/gnu/CORBA/OrbRestricted.java b/libjava/classpath/gnu/CORBA/OrbRestricted.java new file mode 100644 index 000000000..35f0b1724 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/OrbRestricted.java @@ -0,0 +1,583 @@ +/* RestrictedORB.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.typecodes.AliasTypeCode; +import gnu.CORBA.typecodes.ArrayTypeCode; +import gnu.CORBA.typecodes.PrimitiveTypeCode; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.typecodes.StringTypeCode; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.Environment; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.Request; +import org.omg.CORBA.StructMember; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +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.IORInterceptor_3_0Operations; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; + +import java.applet.Applet; + +import java.util.Hashtable; +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. + * + * 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 OrbRestricted extends org.omg.CORBA_2_3.ORB +{ + /** + * The singleton instance of this ORB. + */ + public static final ORB Singleton = new OrbRestricted(); + + /** + * The cumulated listener for all IOR interceptors. Interceptors are used by + * {@link gnu.CORBA.Poa.ORB_1_4}. + */ + public IORInterceptor_3_0Operations 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(); + + /** + * The policy factories. + */ + protected Hashtable policyFactories = new Hashtable(); + + /** + * Create a new instance of the RestrictedORB. This is used in derived classes + * only. + */ + protected OrbRestricted() + { + } + + /** {@inheritDoc} */ + public TypeCode create_alias_tc(String id, String name, TypeCode typecode) + { + return new AliasTypeCode(typecode, id, name); + } + + /** {@inheritDoc} */ + public Any create_any() + { + gnuAny any = new gnuAny(); + any.setOrb(this); + return any; + } + + /** {@inheritDoc} */ + public TypeCode create_array_tc(int length, TypeCode element_type) + { + ArrayTypeCode p = + new ArrayTypeCode(TCKind.tk_array, element_type); + p.setLength(length); + return p; + } + + /** {@inheritDoc} */ + public ContextList create_context_list() + { + return new gnuContextList(); + } + + /** {@inheritDoc} */ + public TypeCode create_enum_tc(String id, String name, String[] values) + { + RecordTypeCode r = new RecordTypeCode(TCKind.tk_enum); + for (int i = 0; i < values.length; i++) + { + r.field().name = values [ i ]; + } + + r.setId(id); + r.setName(name); + + return r; + } + + /** {@inheritDoc} */ + public Environment create_environment() + { + return new gnuEnvironment(); + } + + /** {@inheritDoc} */ + public ExceptionList create_exception_list() + { + return new gnuExceptionList(); + } + + /** {@inheritDoc} */ + public TypeCode create_exception_tc(String id, String name, + StructMember[] members + ) + { + RecordTypeCode r = new RecordTypeCode(TCKind.tk_except); + r.setId(id); + r.setName(name); + + for (int i = 0; i < members.length; i++) + { + r.add(members [ i ]); + } + + return r; + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public TypeCode create_interface_tc(String id, String name) + { + no(); + return null; + } + + /** {@inheritDoc} */ + public NVList create_list(int count) + { + return new gnuNVList(count); + } + + /** {@inheritDoc} */ + public NamedValue create_named_value(String s, Any any, int flags) + { + return new gnuNamedValue(); + } + + /** {@inheritDoc} */ + public OutputStream create_output_stream() + { + BufferedCdrOutput stream = new BufferedCdrOutput(); + stream.setOrb(this); + return stream; + } + + /** {@inheritDoc} */ + public TypeCode create_sequence_tc(int bound, TypeCode element_type) + { + ArrayTypeCode p = + new ArrayTypeCode(TCKind.tk_sequence, element_type); + p.setLength(bound); + return p; + } + + /** {@inheritDoc} */ + public TypeCode create_string_tc(int bound) + { + StringTypeCode p = new StringTypeCode(TCKind.tk_string); + p.setLength(bound); + return p; + } + + /** {@inheritDoc} */ + public TypeCode create_struct_tc(String id, String name, + StructMember[] members + ) + { + RecordTypeCode r = new RecordTypeCode(TCKind.tk_struct); + r.setId(id); + r.setName(name); + + for (int i = 0; i < members.length; i++) + { + r.add(members [ i ]); + } + + return r; + } + + /** {@inheritDoc} */ + 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++) + { + r.add(members [ i ]); + } + + return r; + } + + /** {@inheritDoc} */ + public TypeCode create_wstring_tc(int bound) + { + StringTypeCode p = new StringTypeCode(TCKind.tk_wstring); + p.setLength(bound); + return p; + } + + /** {@inheritDoc} */ + public TypeCode get_primitive_tc(TCKind tcKind) + { + try + { + return TypeKindNamer.getPrimitveTC(tcKind); + } + catch (BadKind ex) + { + throw new BAD_PARAM("This is not a primitive type code: " + + tcKind.value() + ); + } + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public String[] list_initial_services() + { + no(); + throw new InternalError(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public String object_to_string(org.omg.CORBA.Object forObject) + { + no(); + throw new InternalError(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @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 + { + no(); + throw new InternalError(); + } + + /** + * Shutdown the ORB server. + * + * For RestrictedORB, returns witout action. + */ + public void run() + { + } + + /** + * Shutdown the ORB server. + * + * For RestrictedORB, returns witout action. + */ + public void shutdown(boolean wait_for_completion) + { + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public org.omg.CORBA.Object string_to_object(String IOR) + { + no(); + throw new InternalError(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + protected void set_parameters(Applet app, Properties props) + { + no(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + protected void set_parameters(String[] args, Properties props) + { + no(); + } + + /** + * Throws an exception, stating that the given method is not supported by the + * Restricted ORB. + */ + private final void no() + { + // Apart the programming errors, this can only happen if the + // malicious code is trying to do that it is not allowed. + throw new NO_IMPLEMENT("Use init(args, props) for the functional version."); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public Request get_next_response() throws org.omg.CORBA.WrongTransaction + { + no(); + throw new InternalError(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public boolean poll_next_response() + { + no(); + throw new InternalError(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public void send_multiple_requests_deferred(Request[] requests) + { + no(); + } + + /** + * This method is not allowed for a RestrictedORB. + * + * @throws NO_IMPLEMENT, always. + */ + public void send_multiple_requests_oneway(Request[] requests) + { + no(); + } + + /** + * Register the value factory under the given repository id. + */ + public ValueFactory register_value_factory(String repository_id, + ValueFactory factory + ) + { + factories.put(repository_id, factory); + return factory; + } + + /** + * Unregister the value factroy. + */ + public void unregister_value_factory(String id) + { + factories.remove(id); + } + + /** + * 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. + * + * @param repository_id a repository id. + * + * @return a found value factory, null if none. + */ + public ValueFactory lookup_value_factory(String repository_id) + { + ValueFactory f = (ValueFactory) factories.get(repository_id); + if (f != null) + { + return f; + } + + f = (ValueFactory) ObjectCreator.createObject(repository_id, + "DefaultFactory" + ); + if (f != null) + { + 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(); + } + + /** + * Create a typecode, representing a tree-like structure. + * This structure contains a member that is a sequence of the same type, + * as the structure itself. You can imagine as if the folder definition + * contains a variable-length array of the enclosed (nested) folder + * definitions. In this way, it is possible to have a tree like + * structure that can be transferred via CORBA CDR stream. + * + * @deprecated It is easier and clearler to use a combination of + * create_recursive_tc and create_sequence_tc instead. + * + * @param bound the maximal expected number of the nested components + * on each node; 0 if not limited. + * + * @param offset the position of the field in the returned structure + * that contains the sequence of the structures of the same field. + * The members before this field are intialised using parameterless + * StructMember constructor. + * + * @return a typecode, defining a stucture, where a member at the + * <code>offset</code> position defines an array of the identical + * structures. + * + * @see #create_recursive_tc(String) + * @see #create_sequence_tc(int, TypeCode) + */ + public TypeCode create_recursive_sequence_tc(int bound, int offset) + { + RecordTypeCode r = new RecordTypeCode(TCKind.tk_struct); + for (int i = 0; i < offset; i++) + r.add(new StructMember()); + + TypeCode recurs = new PrimitiveTypeCode(TCKind.tk_sequence); + + r.add(new StructMember("", recurs, null)); + return r; + } + + /** + * Get the default context of this ORB. This is an initial root of all + * contexts. + * + * The default method returns a new context with the empty name and + * no parent context. + * + * @return the default context of this ORB. + */ + public Context get_default_context() + { + return new gnuContext("", null); + } + +} diff --git a/libjava/classpath/gnu/CORBA/Poa/AOM.java b/libjava/classpath/gnu/CORBA/Poa/AOM.java new file mode 100644 index 000000000..4b2264f3c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/AOM.java @@ -0,0 +1,406 @@ +/* AOM.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.ByteArrayComparator; + +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.Servant; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Implements the conception of the Active Object Map. + * If the POA supports the RETAIN policy, it maintains an Active + * Object Map, that associates Object Ids with active servants. + * Each association constitutes an active object. We use a single map + * for all POAs on the given orb. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class AOM +{ + /** + * The reference data about the object, placed on the AOM. + */ + public class Obj + { + /** + * Create an initialised instance. + */ + Obj(gnuServantObject _object, byte[] _key, Servant _servant, gnuPOA _poa) + { + object = _object; + key = _key; + servant = _servant; + poa = _poa; + } + + /** + * The object. + */ + public final gnuServantObject object; + + /** + * The servant, serving the given object. + */ + public Servant servant; + + /** + * The local servant that once served this object. + * This field is used by {@link ForwardedServant} when it discovers that + * the forwarding chaing returns back to the original location. + * It should not be used anywhere else. + */ + Servant primary_servant; + + /** + * The POA, where the object is connected. + */ + public final gnuPOA poa; + + /** + * The object key. + */ + public final byte[] key; + + /** + * If true, this entry is deactivated. + */ + public boolean deactivated; + + /** + * Set the servant value, preserving any non null + * value as the primary servant. + */ + public void setServant(Servant s) + { + if (primary_servant == null) + primary_servant = s; + servant = s; + } + + /** + * Get the servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Get the deactivation state. + */ + public boolean isDeactiveted() + { + return deactivated; + } + + /** + * Set the deactivation state. + */ + public void setDeactivated(boolean state) + { + deactivated = state; + } + } + + /** + * The free number to give for the next instance. + * This field is incremented each time the + * new collection of the connected objects is created. + * Each collection has its own unique instance number. + */ + private static long free_id; + + /** + * The map of the all connected objects, maps the object key to the + * object. + */ + Map objects = new TreeMap(new ByteArrayComparator()); + + /** + * Get the record of the stored object. If the object is mapped several times + * under the different keys, one of the mappings is used. + * + * @param stored_object the stored object + * + * @return the record about the stored object, null if this object is not + * stored here. + */ + public Obj findObject(org.omg.CORBA.Object stored_object) + { + if (stored_object == null) + return null; + + Map.Entry item; + Iterator iter; + Obj ref; + + if (stored_object instanceof ObjectImpl) + { + // If the delegate is available, search by delegate. + Delegate d = ((ObjectImpl) stored_object)._get_delegate(); + Delegate d2; + + if (d != null) + { + iter = objects.entrySet().iterator(); + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + d2 = ref.object._get_delegate(); + + if (d == d2 || (d2 != null && d2.equals(d))) + return ref; + } + } + } + + // For other objects (or if not possible to get the delegate), + // search by .equals + iter = objects.entrySet().iterator(); + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (stored_object.equals(ref.object)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. If the servant is mapped to + * several objects, this returns the first found occurence. + * + * @param servant a servant to find. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Find the reference info for the given servant. + * If the servant is mapped to several objects, this + * returns the first found occurence. + * + * @param servant a servant to find. + * @param speficies if to search for the inactive (true) or active + * (false) servant. A servant with unmatching activity is ignored + * by this method. + * + * @return the servant/object/POA binding or null if no such found. + */ + public Obj findServant(Servant servant, boolean inactive) + { + if (servant == null) + return null; + + Map.Entry item; + Iterator iter = objects.entrySet().iterator(); + Obj ref; + + while (iter.hasNext()) + { + item = (Map.Entry) iter.next(); + ref = (Obj) item.getValue(); + if (ref.deactivated == inactive) + if (ref.servant != null) + if (servant.equals(ref.servant)) + return ref; + } + return null; + } + + /** + * Add the new object to the repository. The object key is + * generated automatically. + * + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the poa, where the object is connected. + * + * @return the newly created object record. + */ + public Obj add(gnuServantObject object, Servant servant, gnuPOA poa) + { + return add(generateObjectKey(object), object, servant, poa); + } + + /** + * Add the new object to the repository. + * + * @param key the object key. + * @param object the object to add. + * @param servant a servant, serving the given object. + * @param poa the POA, where the object is connected. + */ + public Obj add(byte[] key, gnuServantObject object, Servant servant, + gnuPOA poa + ) + { + Obj rec = new Obj(object, key, servant, poa); + objects.put(key, rec); + return rec; + } + + /** + * Add the new object to the repository. + * + * @param delegate the delegate, providing data about the servant, key, POA + * and object. + * @param port the port that this object would take. + */ + public Obj add(ServantDelegateImpl delegate) + { + Obj rec = + new Obj(delegate.object, delegate.servant_id, delegate.servant, + delegate.poa + ); + objects.put(delegate.servant_id, rec); + return rec; + } + + /** + * Put back the definition structure that has probably been removed earlier. + */ + public void put(Obj obj) + { + objects.put(obj.key, obj); + } + + /** + * Get the stored object. + * + * @param key the key (in the byte array form). + * + * @return the matching object, null if none is matching. + */ + public Obj get(byte[] key) + { + return (Obj) objects.get(key); + } + + /** + * Get the map key set. + */ + public Set keySet() + { + return objects.keySet(); + } + + /** + * Remove the given object, indiciating it by the key. + * + * @param object the object to remove. + */ + public void remove(byte[] key) + { + objects.remove(key); + } + + /** + * Generate the object key, unique in the currently + * running java virtual machine. The passed object + * parameter is currently not in use. + * + * @return the generated key. + */ + protected byte[] generateObjectKey(org.omg.CORBA.Object object) + { + byte[] key; + + // The repetetive keys cannot be generated, but theoretically + // the same keys can be passed when calling add(byte[]...). + // Hence we check if the key is not already in the map and, + // if it is, use the subsequent value. + do + { + key = getFreeId(); + } + while (objects.containsKey(key)); + return key; + } + + /** + * Get the next free 8 byte id, surely unique between calls of this + * method for the currently running virtual machine. + */ + public static synchronized byte[] getFreeId() + { + byte[] r = new byte[ 8 ]; + + // Start from the faster-changing. + r [ 0 ] = ((byte) (0xff & free_id)); + r [ 1 ] = ((byte) (0xff & (free_id >> 8))); + r [ 2 ] = ((byte) (0xff & (free_id >> 16))); + r [ 3 ] = ((byte) (0xff & (free_id >> 24))); + r [ 4 ] = ((byte) (0xff & (free_id >> 32))); + r [ 5 ] = ((byte) (0xff & (free_id >> 40))); + r [ 6 ] = ((byte) (0xff & (free_id >> 48))); + r [ 7 ] = ((byte) (0xff & (free_id >> 56))); + + free_id++; + + return r; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java b/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java new file mode 100644 index 000000000..5468d2292 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/AccessiblePolicy.java @@ -0,0 +1,62 @@ +/* AccessiblePolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.Policy; + +/** + * The Classpath implementation of the policy, providing the policy + * value and the code of the policy type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface AccessiblePolicy + extends Policy +{ + /** + * Get the value of this policy + */ + java.lang.Object getValue(); + + /** + * Get the integer code of this policy value. + */ + int getCode(); + +} diff --git a/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java b/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java new file mode 100644 index 000000000..4ee02995d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/DynamicImpHandler.java @@ -0,0 +1,85 @@ +/* DynamicImpHandler.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.DynamicImplementation; + +/** + * The InvokeHandler, indicating, that the target is a dynamic + * implementation rather than an invoke handler. These two + * types are not substitutable, but in some methods have possibility + * just to handle them differently. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class DynamicImpHandler + implements InvokeHandler +{ + /** + * The servant that is a dynamic implementation rather than + * invoke handler. + */ + public final DynamicImplementation servant; + + /** + * Create a new instance, wrapping some dyn implementation. + * @param _servant + */ + public DynamicImpHandler(DynamicImplementation _servant) + { + servant = _servant; + } + + /** + * We cannot invoke properly without having parameter info. + * + * @throws BAD_OPERATION, always. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + { + throw new BAD_OPERATION(servant + " is not an InvokeHandler."); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java new file mode 100644 index 000000000..a85173526 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardRequestHolder.java @@ -0,0 +1,107 @@ +/* ForwardRequestHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.ForwardRequestHelper; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableServer.ForwardRequest; + +/** +* A holder for the exception {@link ForwardRequest}. + +* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +*/ +public class ForwardRequestHolder + implements Streamable +{ + /** + * The stored ForwardRequest value. + */ + public ForwardRequest value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public ForwardRequestHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public ForwardRequestHolder(ForwardRequest initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = ForwardRequestHelper.read(input); + } + + /** + * Get the typecode of the ForwardRequest. + */ + public TypeCode _type() + { + return ForwardRequestHelper.type(); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + ForwardRequestHelper.write(output, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java new file mode 100644 index 000000000..c54a02654 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ForwardedServant.java @@ -0,0 +1,209 @@ +/* ForwardedServant.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.IOR; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.IorObject; +import gnu.CORBA.Minor; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; + +import java.io.IOException; + +/** + * A "virtual servant", delegating all invocation to the wrapped + * object (usually remote). Used in cases when it is necessary to + * handle the request forwarding. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ForwardedServant + extends Servant + implements InvokeHandler +{ + /** + * The reference object, handling requests. + */ + public final ObjectImpl ref; + + /** + * Create an instance, forwarding requests to the given object. + */ + ForwardedServant(ObjectImpl a_ref) + { + ref = a_ref; + } + + /** + * Create an instance of the forwarded servant. + * + * @param a_ref a reference where request should be forwarded. + * + * @return a created forwarded servant or null if the parameter + * forwards request to itself. Returning null will force to find + * a right servant in one of many possible ways, depending on + * policies. + */ + public static Servant create(org.omg.CORBA.Object a_ref) + { + try + { + ObjectImpl fto = (ObjectImpl) a_ref; + + // Check maybe the remote side forwarded back to our local object. + if (fto instanceof IorObject) + { + IorObject iref = (IorObject) fto; + + // Check maybe the IOR is local. + ORB t_orb = iref._orb(); + if (t_orb instanceof ORB_1_4) + { + ORB_1_4 orb = (ORB_1_4) t_orb; + Delegate d = iref._get_delegate(); + if (d instanceof IorDelegate) + { + IorDelegate ird = (IorDelegate) iref._get_delegate(); + IOR ior = ird.getIor(); + if (orb.LOCAL_HOST.equalsIgnoreCase(ior.Internet.host)) + { + AOM.Obj rx = orb.rootPOA.findIorKey(ior.key); + if (rx != null) + { + if (rx.object == fto || + rx.object._is_equivalent(fto) + ) + return rx.primary_servant; + else + fto = (ObjectImpl) rx.object; + } + } + } + } + } + return new ForwardedServant(fto); + } + catch (ClassCastException ex) + { + throw new BAD_PARAM("ObjectImpl required but " + a_ref + " passed ", + 0x5005, CompletionStatus.COMPLETED_NO + ); + } + } + + /** + * Forward the call to the wrapped object. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler handler + ) + throws SystemException + { + org.omg.CORBA.portable.InputStream in = null; + org.omg.CORBA.portable.OutputStream out = null; + try + { + try + { + out = ref._request(method, true); + + // Transfer request information. + int b; + while ((b = input.read()) >= 0) + { + out.write(b); + } + in = ref._invoke(out); + + // Read the returned data. + out = handler.createReply(); + while ((b = in.read()) >= 0) + { + out.write(b); + } + } + catch (IOException io_ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Forwarding; + m.initCause(io_ex); + throw m; + } + } + catch (ApplicationException ex) + { + in = ex.getInputStream(); + + String _id = ex.getId(); + throw new MARSHAL(_id, 5101, CompletionStatus.COMPLETED_NO); + } + catch (RemarshalException remarsh) + { + _invoke(method, input, handler); + } + finally + { + ref._releaseReply(in); + } + return out; + } + + /** + * Delegates to the wrapped object. + */ + public String[] _all_interfaces(POA poa, byte[] key) + { + return ref._ids(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java b/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java new file mode 100644 index 000000000..b415034a3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/InvalidPolicyHolder.java @@ -0,0 +1,106 @@ +/* InvalidPolicyHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; +import org.omg.PortableServer.POAPackage.InvalidPolicy; +import org.omg.PortableServer.POAPackage.InvalidPolicyHelper; + +/** +* A holder for the exception {@link InvalidPolicy}. + +* @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +*/ +public class InvalidPolicyHolder + implements Streamable +{ + /** + * The stored InvalidPolicy value. + */ + public InvalidPolicy value; + + /** + * Create the unitialised instance, leaving the value field + * with default <code>null</code> value. + */ + public InvalidPolicyHolder() + { + } + + /** + * Create the initialised instance. + * @param initialValue the value that will be assigned to + * the <code>value</code> field. + */ + public InvalidPolicyHolder(InvalidPolicy initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + * + * @param input the org.omg.CORBA.portable stream to read. + */ + public void _read(InputStream input) + { + value = InvalidPolicyHelper.read(input); + } + + /** + * Write the stored value into the CDR stream. + * + * @param output the org.omg.CORBA.portable stream to write. + */ + public void _write(OutputStream output) + { + InvalidPolicyHelper.write(output, value); + } + + /** + * Get the typecode of the InvalidPolicy. + */ + public TypeCode _type() + { + return InvalidPolicyHelper.type(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java new file mode 100644 index 000000000..7b42fde1e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalDelegate.java @@ -0,0 +1,385 @@ +/* LocalDelegate.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.CDR.AbstractCdrOutput; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.StreamBasedRequest; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Request; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.RemarshalException; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; + +import java.util.Arrays; + +/** + * A local delegate, transferring all object requests to the locally available + * servant. This class is involved in handling the method invocations on the + * local object, obtained by POA.create_reference_with_id. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalDelegate + extends org.omg.CORBA_2_3.portable.Delegate + implements IorProvider +{ + /** + * The same servant as an invocation handler. + */ + gnuServantObject object; + + String operation; + + public final gnuPOA poa; + + final byte[] Id; + + /** + * Create a local delegate, forwarding requests to the servant that must also + * be an invocation handler. + */ + public LocalDelegate(gnuServantObject an_object, gnuPOA a_poa, byte[] an_id) + { + object = an_object; + poa = a_poa; + Id = an_id; + } + + /** + * Get the IOR of the connected object. + */ + public IOR getIor() + { + return object.getIor(); + } + + public Request request(org.omg.CORBA.Object target, String method) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq; + } + + public void release(org.omg.CORBA.Object target) + { + } + + public boolean is_equivalent(org.omg.CORBA.Object target, + org.omg.CORBA.Object other) + { + if (target == other) + return true; + else if (target instanceof ObjectImpl && other instanceof ObjectImpl) + { + org.omg.CORBA.portable.Delegate a = null; + org.omg.CORBA.portable.Delegate b = null; + try + { + a = ((ObjectImpl) target)._get_delegate(); + b = ((ObjectImpl) other)._get_delegate(); + } + catch (Exception ex) + { + // Unable to get one of the delegates. + return false; + } + if (a instanceof LocalDelegate && b instanceof LocalDelegate) + { + byte[] k1 = ((LocalDelegate) a).Id; + byte[] k2 = ((LocalDelegate) b).Id; + return Arrays.equals(k1, k2); + } + else + return false; + } + else + return false; + } + + /** + * Always return false. + */ + public boolean non_existent(org.omg.CORBA.Object target) + { + return false; + } + + /** + * Get hash code. + */ + public int hash(org.omg.CORBA.Object target, int maximum) + { + return hashCode() % maximum; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean is_a(org.omg.CORBA.Object a_servant, String idl_id) + { + String[] maybe = object._ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe[i].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return <code>this</code>. + */ + public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target) + { + return target; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns, + ExceptionList exceptions, ContextList ctx_list) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + rq.set_exceptions(exceptions); + rq.set_context_list(ctx_list); + return rq; + } + + /** + * Create request for using with DII. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String method, NVList parameters, NamedValue returns) + { + operation = method; + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.set_args(parameters); + rq.set_result(returns); + return rq; + } + + /** + * Not in use. + */ + public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target) + { + throw new NO_IMPLEMENT(); + } + + /** + * Create a request to invoke the method of this CORBA object. + * + * @param operation the name of the method to invoke. + * @param response_expected specifies if this is one way message or the + * response to the message is expected. + * + * @return the stream where the method arguments should be written. + */ + public org.omg.CORBA.portable.OutputStream request( + org.omg.CORBA.Object target, String method, boolean response_expected) + { + operation = method; + + // Check if the object is not explicitly deactivated. + AOM.Obj e = poa.aom.get(Id); + if (e != null && e.isDeactiveted()) + { + if (poa.servant_activator != null || poa.servant_locator != null) + { + // This will force the subsequent activation. + object.setServant(null); + e.setServant(null); + e.setDeactivated(false); + } + else + throw new OBJECT_NOT_EXIST("Deactivated"); + } + + LocalRequest rq = new LocalRequest(object, poa, Id); + rq.setOperation(method); + rq.setORB(orb(target)); + return rq.getParameterStream(); + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String method, CookieHolder cookie) + { + return object.getHandler(method, cookie, false); + } + + /** + * Return the ORB of the associated POA. The parameter is not in use. + */ + public ORB orb(org.omg.CORBA.Object target) + { + return poa.orb(); + } + + /** + * Make an invocation. + * + * @param target not in use. + * @param output the stream request that should be returned by + * {@link #m_request} in this method. + * @throws ApplicationException if the use exception is thrown by the servant + * method. + */ + public InputStream invoke(org.omg.CORBA.Object target, OutputStream output) + throws ApplicationException + { + try + { + StreamBasedRequest sr = (StreamBasedRequest) output; + + LocalRequest lr = (LocalRequest) sr.request; + InvokeHandler handler = lr.object.getHandler(lr.operation(), lr.cookie, + false); + + if (handler instanceof DynamicImpHandler) + { + // The local request known how to handle it, but the different + // method must be called. + lr.invoke(); + + // The encapsulation will inherit orb, endian, charsets, etc. + AbstractCdrOutput buf = sr.createEncapsulation(); + + // Write all request parameters to the buffer stream. + if (lr.env().exception() != null) + { + try + { + UnknownUserException uex = (UnknownUserException) lr.env().exception(); + throw new ApplicationException(uex.except.type().id(), + uex.except.create_input_stream()); + } + catch (BadKind ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + if (lr.return_value() != null) + lr.return_value().write_value(buf); + + NamedValue a; + try + { + for (int i = 0; i < lr.arguments().count(); i++) + { + a = lr.arguments().item(i); + if (a.flags() == ARG_INOUT.value + || a.flags() == ARG_INOUT.value) + { + a.value().write_value(buf); + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + + return buf.create_input_stream(); + } + else + { + LocalRequest lrq = (LocalRequest) sr.request; + return lrq.s_invoke(handler); + } + } + catch (gnuForwardRequest f) + { + try + { + return ((ObjectImpl) f.forward_reference)._invoke(f.forward_reference._request( + operation, true)); + } + catch (RemarshalException e) + { + // Never thrown in this place by Classpath implementation. + throw new NO_IMPLEMENT(); + } + } + } + + public void releaseReply(org.omg.CORBA.Object target, InputStream input) + { + release(target); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java new file mode 100644 index 000000000..ca5b57b00 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalRequest.java @@ -0,0 +1,687 @@ +/* LocalRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.GIOP.MessageHeader; +import gnu.CORBA.GIOP.v1_2.ReplyHeader; +import gnu.CORBA.GIOP.v1_2.RequestHeader; +import gnu.CORBA.Interceptor.gnuClientRequestInfo; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.gnuAny; +import gnu.CORBA.gnuRequest; +import gnu.CORBA.StreamHolder; +import gnu.CORBA.StreamBasedRequest; + +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.UnknownUserException; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.ApplicationException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ClientRequestInterceptorOperations; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +/** + * Directs the invocation to the locally available servant. The POA servant does + * not longer implement the CORBA object and cannot be substituted directly. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalRequest extends gnuRequest implements ResponseHandler, + CurrentOperations +{ + /** + * Used by servant locator, if involved. + */ + CookieHolder cookie; + + /** + * The object Id. + */ + final byte[] Id; + + /** + * The message header (singleton is sufficient). + */ + private static final MessageHeader header = new MessageHeader(); + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise. + */ + boolean exceptionReply; + + /** + * The buffer to write into. + */ + BufferedCdrOutput buffer; + + /** + * The responsible POA. + */ + final gnuPOA poa; + + /** + * The servant delegate to obtain the handler. + */ + gnuServantObject object; + + /** + * Used (reused) with dynamic implementation. + */ + LocalServerRequest serverRequest; + + /** + * Create an instance of the local request. + */ + public LocalRequest(gnuServantObject local_object, gnuPOA a_poa, byte[] an_id) + { + Id = an_id; + poa = a_poa; + + // Instantiate the cookie holder only if required. + if (poa.servant_locator != null) + { + cookie = new CookieHolder(); + } + object = local_object; + prepareStream(); + } + + /** + * Make an invocation and return a stream from where the results can be read + * and throw ApplicationException, where applicable. + */ + org.omg.CORBA.portable.InputStream s_invoke(InvokeHandler handler) + throws ApplicationException + { + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + return input; + } + else + { + input.mark(500); + + String id = input.read_string(); + try + { + input.reset(); + } + catch (IOException ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + throw new ApplicationException(id, input); + } + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + + /** + * Make an invocation and return a stream from where the results can be read. + * + * @param handler the invoke handler (can be null, then it is obtained self + * dependently). + */ + public org.omg.CORBA.portable.InputStream v_invoke(InvokeHandler handler) + { + // Check maybe POA is in the discarding mode (will throw TRANSIENT if it is). + poa.checkDiscarding(); + + // Local request must be intercepted both by server and request + // interceptors. + boolean s_intercept = false; + ServerRequestInterceptorOperations s_interceptor = null; + gnuServerRequestInfo s_info = null; + + boolean c_intercept = false; + ClientRequestInterceptorOperations c_interceptor = null; + gnuClientRequestInfo c_info = null; + + try + { + if (poa.m_orb.iServer != null || poa.m_orb.iClient != null) + { + setORB(poa.m_orb); + + // These two are only needed with interceptors. + m_rqh = new RequestHeader(); + m_rqh.operation = m_operation; + m_rph = new ReplyHeader(); + + m_rqh.object_key = object.Id; + m_rph.request_id = m_rqh.request_id; + } + + if (poa.m_orb.iClient != null) + { + c_interceptor = poa.m_orb.iClient; + + c_info = new gnuClientRequestInfo(this); + c_intercept = true; + + c_interceptor.send_request(c_info); + + m_target = object; + } + + if (poa.m_orb.iServer != null) + { + s_interceptor = poa.m_orb.iServer; + + s_info = new gnuServerRequestInfo(object, m_rqh, m_rph); + s_info.m_request = this; + + s_intercept = true; + + s_interceptor.receive_request_service_contexts(s_info); + } + + if (handler == null) + { + handler = object.getHandler(operation(), cookie, false); + } + + BufferedCdrOutput request_part = new BufferedCdrOutput(); + + request_part.setOrb(orb()); + + if (m_args != null && m_args.count() > 0) + { + write_parameters(header, request_part); + + if (m_parameter_buffer != null) + { + throw new BAD_INV_ORDER("Please either add parameters or " + + "write them into stream, but not both " + "at once." + ); + } + } + + if (m_parameter_buffer != null) + { + write_parameter_buffer(header, request_part); + } + + Servant servant; + + if (handler instanceof Servant) + { + servant = (Servant) handler; + } + else + { + throw new BAD_OPERATION("Unexpected handler type " + handler); + } + + org.omg.CORBA.portable.InputStream input = + request_part.create_input_stream(); + + // Ensure the servant (handler) has a delegate set. + ServantDelegateImpl sd = null; + + Delegate d = null; + + try + { + d = servant._get_delegate(); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof ServantDelegateImpl) + { + // If the delegate is already set, try to reuse the existing + // instance. + sd = (ServantDelegateImpl) d; + if (sd.object != object) + { + sd = new ServantDelegateImpl(servant, poa, Id); + } + } + else + { + sd = new ServantDelegateImpl(servant, poa, Id); + } + servant._set_delegate(sd); + + try + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.put(Thread.currentThread(), this); + } + + try + { + if (s_intercept) + { + s_interceptor.receive_request(s_info); + } + handler._invoke(m_operation, input, this); + + // Handler is casted into i_handler. + if ((s_intercept || c_intercept) && isExceptionReply()) + { + s_info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + m_rph.reply_status = ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = new gnuAny(); + OutputStream buf = getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + m_exception_id = uex_idl; + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, in); + + m_environment.exception(exception); + ObjectCreator.insertWithHelper(a, exception); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new StreamHolder( + buf.create_input_stream() + ) + ); + + RecordTypeCode r = + new RecordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName(uex_idl)); + } + + s_info.m_usr_exception = a; + c_info.m_wrapped_exception = a; + s_interceptor.send_exception(s_info); + c_interceptor.receive_exception(c_info); + } + else + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + s_interceptor.send_reply(s_info); + } + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.NO_EXCEPTION; + c_interceptor.receive_reply(c_info); + } + } + } + catch (SystemException sys_ex) + { + if (s_intercept) + { + s_info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + s_info.m_sys_exception = sys_ex; + s_interceptor.send_exception(s_info); + } + + if (c_intercept) + { + m_rph.reply_status = ReplyHeader.SYSTEM_EXCEPTION; + + Any a = new gnuAny(); + if (ObjectCreator.insertSysException(a, sys_ex)) + { + c_info.m_wrapped_exception = a; + } + c_interceptor.receive_exception(c_info); + } + + throw sys_ex; + } + } + finally + { + ORB o = orb(); + if (o instanceof ORB_1_4) + { + ((ORB_1_4) o).currents.remove(Thread.currentThread()); + } + } + + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(object.Id, poa, operation(), + cookie.value, object.getServant() + ); + } + return buffer.create_input_stream(); + } + + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward = s_info.m_forward_reference; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward = fex2.forward; + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + // May be thrown during activation. + if (s_intercept) + { + Forwarding: + while (true) + { + s_info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + s_info.m_forward_reference = fex.forward_reference; + try + { + s_interceptor.send_other(s_info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + s_info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + + if (c_intercept) + { + this.m_rph.reply_status = ReplyHeader.LOCATION_FORWARD; + this.m_forwarding_target = fex.forward_reference; + try + { + c_interceptor.receive_other(c_info); + } + catch (ForwardRequest fex2) + { + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + throw fex; + } + } + + /** + * Make an invocation and store the result in the fields of this Request. Used + * with DII only. + */ + public void invoke() + { + InvokeHandler handler = object.getHandler(operation(), cookie, false); + + if (handler instanceof DynamicImpHandler) + { + DynamicImplementation dyn = ((DynamicImpHandler) handler).servant; + if (serverRequest == null) + { + serverRequest = new LocalServerRequest(this); + } + try + { + poa.m_orb.currents.put(Thread.currentThread(), this); + dyn.invoke(serverRequest); + } + finally + { + poa.m_orb.currents.remove(Thread.currentThread()); + } + } + else + { + org.omg.CORBA.portable.InputStream input = v_invoke(handler); + + if (!exceptionReply) + { + NamedValue arg; + + // Read return value, if set. + if (m_result != null) + { + m_result.value().read_value(input, m_result.value().type()); + } + + // Read returned parameters, if set. + if (m_args != null) + { + for (int i = 0; i < m_args.count(); i++) + { + try + { + arg = m_args.item(i); + + // Both ARG_INOUT and ARG_OUT have this binary flag set. + if ((arg.flags() & ARG_OUT.value) != 0) + { + arg.value().read_value(input, arg.value().type()); + } + } + catch (Bounds ex) + { + Unexpected.error(ex); + } + } + } + } + else// User exception reply + { + // Prepare an Any that will hold the exception. + gnuAny exc = new gnuAny(); + + exc.insert_Streamable(new StreamHolder(input)); + + UnknownUserException unuex = new UnknownUserException(exc); + m_environment.exception(unuex); + } + } + } + + /** + * Get an output stream for providing details about the exception. Before + * returning the stream, the handler automatically writes the message header + * and the reply about exception header, but not the message header. + * + * @return the stream to write exception details into. + */ + public OutputStream createExceptionReply() + { + exceptionReply = true; + prepareStream(); + return buffer; + } + + /** + * Get an output stream for writing a regular reply (not an exception). + * + * Before returning the stream, the handler automatically writes the regular + * reply header, but not the message header. + * + * @return the output stream for writing a regular reply. + */ + public OutputStream createReply() + { + exceptionReply = false; + prepareStream(); + return buffer; + } + + /** + * Get the buffer, normally containing the written reply. The reply includes + * the reply header (or the exception header) but does not include the message + * header. + * + * The stream buffer can also be empty if no data have been written into + * streams, returned by {@link #createReply()} or + * {@link #createExceptionReply()}. + * + * @return the CDR output stream, containing the written output. + */ + BufferedCdrOutput getBuffer() + { + return buffer; + } + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise (usually no-exception reply). + */ + boolean isExceptionReply() + { + return exceptionReply; + } + + /** + * Compute the header offset, set the correct version number and codeset. + */ + private void prepareStream() + { + buffer = new BufferedCdrOutput(); + buffer.setOrb(orb()); + } + + /** + * Get the parameter stream, where the invocation arguments should be written + * if they are written into the stream directly. + */ + public StreamBasedRequest getParameterStream() + { + m_parameter_buffer = new StreamBasedRequest(); + m_parameter_buffer.request = this; + m_parameter_buffer.setOrb(poa.orb()); + return m_parameter_buffer; + } + + public byte[] get_object_id() throws NoContext + { + return Id; + } + + public POA get_POA() throws NoContext + { + return poa; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java new file mode 100644 index 000000000..714e029fe --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/LocalServerRequest.java @@ -0,0 +1,199 @@ +/* LocalServerRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.gnuNamedValue; + +import org.omg.CORBA.ARG_INOUT; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.Context; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ServerRequest; +import org.omg.CORBA.UnknownUserException; + +/** + * Used to make local invocations via LocalRequest. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class LocalServerRequest + extends ServerRequest +{ + /** + * The local request, on the base of that this instance is created. + */ + final LocalRequest request; + + /** + * Create a new instance. + */ + public LocalServerRequest(LocalRequest _request) + { + request = _request; + } + + /** + * Get the argument list that can be modified. + */ + public void params(NVList args) + { + arguments(args); + } + + /** + * Get contexts. + */ + public Context ctx() + { + return request.ctx(); + } + + /** + * Get the operatin being performed. + */ + public String operation() + { + return request.operation(); + } + + /** + * Get the argument list that can be modified. + * The direction depends on the size of the passed list. + * The empty list is filled with the request arguments. + * The non-empty list is used to set the request arguments. + */ + public void arguments(NVList args) + { + NVList l = request.arguments(); + NamedValue a; + + try + { + if (args.count() == 0) + { + // Transfer to the passed parameter. + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + args.add_value(a.name(), a.value(), a.flags()); + } + } + else + { + // Transfer from the passed parameter. + if (l.count() != args.count()) + throw new BAD_PARAM("Argument number mismatch, current " + + l.count() + ", passed " + args.count() + ); + try + { + for (int i = 0; i < l.count(); i++) + { + a = l.item(i); + if (a.flags() == ARG_INOUT.value || + a.flags() == ARG_OUT.value + ) + { + ((gnuNamedValue) a).setValue(args.item(i).value()); + } + } + } + catch (ClassCastException cex) + { + InternalError ierr = new InternalError(); + ierr.initCause(cex); + throw ierr; + } + } + } + catch (Bounds ex) + { + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + } + + /** + * Set the result. + */ + public void set_result(Any result) + { + gnuNamedValue g = new gnuNamedValue(); + g.setValue(result); + g.setFlags(ARG_OUT.value); + request.set_result(g); + } + + /** + * Get the name of the method being called. + */ + public String op_name() + { + return request.operation(); + } + + /** + * Set the exception that has been thrown. + */ + public void set_exception(Any exc) + { + request.env().exception(new UnknownUserException(exc)); + } + + /** + * Set the result. + */ + public void result(Any r) + { + set_result(r); + } + + /** + * Set the exception. + */ + public void except(Any exc) + { + set_exception(exc); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java new file mode 100644 index 000000000..360537e2c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ORB_1_4.java @@ -0,0 +1,293 @@ +/* ORB_1_4.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.IOR; +import gnu.CORBA.Connected_objects.cObject; +import gnu.CORBA.DynAn.gnuDynAnyFactory; +import gnu.CORBA.Interceptor.ClientRequestInterceptors; +import gnu.CORBA.Interceptor.IORInterceptors; +import gnu.CORBA.Interceptor.Registrator; +import gnu.CORBA.Interceptor.ServerRequestInterceptors; +import gnu.CORBA.Interceptor.gnuIcCurrent; +import gnu.CORBA.Interceptor.gnuIorInfo; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Policy; +import org.omg.CORBA.PolicyError; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.PolicyFactory; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.POAPackage.InvalidPolicy; + +import java.applet.Applet; +import java.util.Properties; + +/** + * The ORB, supporting POAs that are the feature of jdk 1.4. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ORB_1_4 + extends OrbFunctional +{ + /** + * The root POA. + */ + public final gnuPOA rootPOA; + + /** + * Maps the active threads to the invocation data ("POA Current's"). + */ + public gnuPoaCurrent currents = new gnuPoaCurrent(); + + /** + * Maps the active threads to the interceptor data ("Interceptor Current's"). + */ + public gnuIcCurrent ic_current = new gnuIcCurrent(this); + + /** + * Creates dynamic anys. + */ + public gnuDynAnyFactory factory = new gnuDynAnyFactory(this); + + /** + * Calls the parent constructor and additionally puts the "RootPOA", + * "RootPOAManager", "POACurrent" and "DynAnyFactory" into initial references. + */ + public ORB_1_4() + { + super(); + try + { + rootPOA = new gnuPOA(null, "RootPOA", null, StandardPolicies.rootPoa(), this); + } + catch (InvalidPolicy ex) + { + // Invalid default policy set. + InternalError ierr = new InternalError(); + ierr.initCause(ex); + throw ierr; + } + initial_references.put("RootPOA", rootPOA); + initial_references.put("RootPOAManager", rootPOA.the_POAManager()); + initial_references.put("POACurrent", currents); + initial_references.put("DynAnyFactory", factory); + initial_references.put("PICurrent", ic_current); + } + + /** + * If the super method detects that the object is not connected to this ORB, + * try to find and activate the object. + */ + public String object_to_string(org.omg.CORBA.Object forObject) + { + try + { + return super.object_to_string(forObject); + } + catch (Exception ex) + { + try + { + AOM.Obj exists = rootPOA.findObject(forObject); + if (exists == null) + throw new OBJECT_NOT_EXIST(forObject == null ? "null" + : forObject.toString()); + else if (exists.poa instanceof gnuPOA) + ((gnuPOA) exists.poa).connect_to_orb(exists.key, forObject); + else + exists.poa.create_reference_with_id(exists.key, + ((ObjectImpl) exists.object)._ids()[0]); + } + catch (Exception bex) + { + BAD_PARAM bad = new BAD_PARAM("Unable to activate " + forObject); + bad.initCause(bex); + throw bad; + } + + return super.object_to_string(forObject); + } + } + + /** + * Destroy all poas and then call the superclass method. + */ + public void destroy() + { + // This will propagate through the whole POA tree. + rootPOA.destroy(true, false); + + super.destroy(); + } + + /** + * Do interceptor registration. + * + * @param properties the properties, between those names the agreed prefix + * "org.omg.PortableInterceptor.ORBInitializerClass." is searched. + * + * @param args the string array, passed to the ORB.init + */ + protected void registerInterceptors(Properties properties, String[] args) + { + Registrator registrator = new Registrator(this, properties, args); + + policyFactories = registrator.m_policyFactories; + + registrator.pre_init(); + initial_references.putAll(registrator.getRegisteredReferences()); + registrator.post_init(); + + if (registrator.hasIorInterceptors()) + iIor = new IORInterceptors(registrator); + + if (registrator.hasServerRequestInterceptors()) + iServer = new ServerRequestInterceptors(registrator); + + if (registrator.hasClientRequestInterceptors()) + iClient = new ClientRequestInterceptors(registrator); + + policyFactories = registrator.m_policyFactories; + } + + /** + * Create IOR and allow registered interceptors to add additional components. + */ + protected IOR createIOR(cObject ref) + throws BAD_OPERATION + { + IOR ior = super.createIOR(ref); + if (iIor != null) + { + AOM.Obj obj = rootPOA.findIorKey(ior.key); + + gnuPOA poa; + + // Null means that the object was connected to the ORB directly. + if (obj == null) + poa = rootPOA; + else + poa = obj.poa; + + gnuIorInfo info = new gnuIorInfo(this, poa, ior); + + // This may modify the ior. + iIor.establish_components(info); + iIor.components_established(info); + } + return ior; + } + + /** + * Create policy using the previously registered factory. + */ + public Policy create_policy(int type, Any value) + throws PolicyError + { + Integer policy = new Integer(type); + + PolicyFactory forge = (PolicyFactory) policyFactories.get(policy); + if (forge == null) + throw new PolicyError("No factory registered for policy " + type, + (short) type); + else + return forge.create_policy(type, value); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(Applet app, Properties props) + { + super.set_parameters(app, props); + registerInterceptors(props, new String[0]); + } + + /** + * Set the parameters and then register interceptors. + */ + protected void set_parameters(String[] para, Properties props) + { + super.set_parameters(para, props); + registerInterceptors(props, para); + } + + /** + * This method is called by RMI-IIOP {@link javax.rmi.Tie#orb(ORB)}, passing + * <code>this</code> as parameter. The ORB will try to connect that tie as + * one of its objects, if it is not already connected. If the wrapper is an + * instance of Servant this method also activates the root poa (if not already + * active). + */ + public void set_delegate(java.lang.Object wrapper) + { + if (wrapper instanceof org.omg.CORBA.Object) + { + org.omg.CORBA.Object object = (org.omg.CORBA.Object) wrapper; + if (connected_objects.getKey(object) == null) + connect(object); + } + else if (wrapper instanceof Servant) + { + Servant s = (Servant) wrapper; + if (rootPOA.findServant(s) == null) + try + { + rootPOA.servant_to_reference(s); + if (rootPOA.the_POAManager().get_state().value() == State._HOLDING) + rootPOA.the_POAManager().activate(); + } + catch (Exception e) + { + BAD_OPERATION bad = new BAD_OPERATION("Unable to connect " + + wrapper + " to " + this); + throw bad; + } + } + } + +} diff --git a/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java b/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java new file mode 100644 index 000000000..2123a1c9c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/ServantDelegateImpl.java @@ -0,0 +1,232 @@ +/* ServantDelegateImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.Unexpected; + +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ORBPackage.InvalidName; +import org.omg.CORBA.Object; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAHelper; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.portable.Delegate; + +/** + * The implementation of the servant delegate for the locally existing + * servant.The associated servant that must also implement the + * {@link InvokeHandler} interface. Each servant requires a separate + * instance of this delegate and can serve a single object only. + * Hence the fields are final, but the delegate is typically reused + * unless the same servant is connected to different objects. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class ServantDelegateImpl + implements Delegate +{ + /** + * The servant, associated with this object. + */ + final Servant servant; + + /** + * The servant (not object) id. + */ + final byte[] servant_id; + + /** + * The POA, where the servant is connected. + */ + final gnuPOA poa; + + /** + * The object, exposed as an object, served by this servant. + */ + final gnuServantObject object; + + /** + * Create the delegat for the servant that will be connected to the + * given poa. The method is normally called from inside of gnuPOA. + * The constructor sets the newly created delegate as the delegate to this + * servant by calling Servant._set_delegate. + * + * @param a_poa the poa. + * @param a_servant the servant. + * @param a_servant_id the servant id. + */ + public ServantDelegateImpl(Servant a_servant, gnuPOA a_poa, byte[] a_servant_id) + { + poa = a_poa; + servant = a_servant; + servant_id = a_servant_id; + servant._set_delegate(this); + object = + new gnuServantObject(servant, servant_id, (ORB_1_4) servant._orb(), a_poa); + object._set_delegate(new LocalDelegate(object, poa, a_servant_id)); + } + + /** + * Check if this object could be named by the given repository id. + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this + * object. + */ + public boolean is_a(Servant a_servant, String idl_id) + { + same(a_servant); + + String[] maybe = object.repository_ids; + if (maybe == null) + maybe = servant._all_interfaces(poa, object.Id); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + return true; + } + return false; + } + + /** + * Return the ORB's default POA. + */ + public POA default_POA(Servant a_servant) + { + same(a_servant); + try + { + return POAHelper.narrow(orb(a_servant).resolve_initial_references("RootPOA")); + } + catch (InvalidName ex) + { + throw new Unexpected(ex); + } + } + + /** + * Get ORB. + */ + public ORB orb(Servant a_servant) + { + same(a_servant); + return poa.orb(); + } + + /** + * Get the object, exposing the servant. + */ + public Object this_object(Servant a_servant) + { + same(a_servant); + try + { + return poa.aom.get(poa.m_orb.currents.get_object_id()).object; + } + catch (NoContext ex) + { + return object; + } + } + + /** + * Not supported. + * + * @specnote Same as for Sun up till 1.5 inclusive. + */ + public Object get_interface_def(Servant a_servant) + { + same(a_servant); + throw new NO_IMPLEMENT(); + } + + /** + * Get the Id of the object being currently served. + */ + public byte[] object_id(Servant a_servant) + { + same(a_servant); + try + { + byte[] id = poa.m_orb.currents.get_object_id(); + return id; + } + catch (NoContext ex) + { + return object.Id; + } + } + + /** + * Always returns false; + */ + public boolean non_existent(Servant a_servant) + { + same(a_servant); + return false; + } + + /** + * Return the associated POA. + */ + public POA poa(Servant a_servant) + { + same(a_servant); + try + { + return poa.m_orb.currents.get_POA(); + } + catch (NoContext ex) + { + return poa; + } + } + + /** + * Checks if the passed servant is the same as the servant, associated with + * this delegate. This class requires a single servant per delegate. + */ + void same(Servant some_servant) + { + if (servant != some_servant) + throw new InternalError("Only one servant per delegate is supported."); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java b/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java new file mode 100644 index 000000000..6b84031f1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/StandardPolicies.java @@ -0,0 +1,128 @@ +/* StandardPolicies.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.Policy; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.ThreadPolicyValue; + +import java.util.ArrayList; + +/** + * Contains the frequently uset POA policy sets. The policy + * arrays are package private for security reasons, the cloned + * copies are returned. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class StandardPolicies +{ + /** + * The default policy set, as defined in OMG specs. This is also + * the policy set for the root POA. + */ + private static final AccessiblePolicy[] rootPOASet = + new AccessiblePolicy[] + { + new gnuThreadPolicy(ThreadPolicyValue.ORB_CTRL_MODEL), + new gnuLifespanPolicy(LifespanPolicyValue.TRANSIENT), + new gnuIdUniquenessPolicy(IdUniquenessPolicyValue.UNIQUE_ID), + new gnuIdAssignmentPolicy(IdAssignmentPolicyValue.SYSTEM_ID), + new gnuServantRetentionPolicy(ServantRetentionPolicyValue.RETAIN), + new gnuRequestProcessingPolicy(RequestProcessingPolicyValue.USE_ACTIVE_OBJECT_MAP_ONLY), + new gnuImplicitActivationPolicy(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + }; + + /** + * Return the policy set, applicable for the root POA, as defined + * in OMG specs. + */ + public static Policy[] rootPoa() + { + Policy[] p = new Policy[ rootPOASet.length ]; + System.arraycopy(rootPOASet, 0, p, 0, p.length); + return p; + } + + /** + * Convert the potentially incomplete policy array into array, containing + * the complete policy set. + * + * @param policies the policy list, may be incomplete (even zero size). + * + * @return the complete policy array. The missing, but needed policies + * are added with they default values. + */ + public static Policy[] withDefault(Policy[] policies) + { + ArrayList current = new ArrayList(rootPOASet.length); + Policy p_default; + boolean specified; + + for (int i = 0; i < rootPOASet.length; i++) + { + p_default = rootPOASet [ i ]; + specified = false; + ForThis: + for (int j = 0; j < policies.length; j++) + { + if (policies [ j ].policy_type() == p_default.policy_type()) + { + specified = true; + current.add(policies [ j ]); + break ForThis; + } + } + if (!specified) + current.add(p_default.copy()); + } + + Policy[] complete = new Policy[ current.size() ]; + for (int i = 0; i < complete.length; i++) + { + complete [ i ] = (Policy) current.get(i); + } + return complete; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java new file mode 100644 index 000000000..fc64e6bb1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuAdapterActivator.java @@ -0,0 +1,81 @@ +/* gnuAdapterActivator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.LocalObject; +import org.omg.PortableServer.AdapterActivator; +import org.omg.PortableServer.POA; + +/** + * Defines a simple adapter activator. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuAdapterActivator + extends LocalObject + implements AdapterActivator +{ + /** + * Create a new POA on the parent, using the parent policy set + * from the suitable parent of grandparend and with independent + * POA manager (passing null to the createPOA). + * + * @param parent a parent. Either this parent or one of its + * grandparents must be gnuAbstractPOA, able to provide a + * policy set. + * + * @param child_name the name of the child being created. + * + * @return true on success or false if no gnuAbstractPOA + * found till the root poa. + */ + public boolean unknown_adapter(POA parent, String child_name) + { + try + { + POA n = parent.create_POA(child_name, null, StandardPolicies.rootPoa()); + n.the_POAManager().activate(); + } + catch (Exception ex) + { + return false; + } + return true; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java new file mode 100644 index 000000000..01c6cccd5 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuForwardRequest.java @@ -0,0 +1,90 @@ +/* gnuForwardRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.GIOP.ReplyHeader; + +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * The class, indicating that the request should be forwarded to another + * target. We cannot use ForwardRequest because the exception is throws + * from methods that does not declare throwing it. Hence must be + * RuntimeException. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuForwardRequest + extends RuntimeException +{ + /** + * Use serialVersionUID (v1.4) for interoperability. + */ + private static final long serialVersionUID = -1L; + + /** + * The object reference, indicating the new location of the invocation target. + */ + public ObjectImpl forward_reference; + + /** + * This information shows if we use LOCATION_FORWARD or + * LOCATION_FORWARD_PERM in request. By defalult, LOCATION_FORWARD + * is always used. To use LOCATION_FORWARD_PERM, this exception should + * be thrown from the servant manager instead of ForwardRequest, + * with this field set to ReplyHeader.LOCATION_FORWARD_PERM. + */ + public byte forwarding_code = ReplyHeader.LOCATION_FORWARD; + + /** + * Create the ForwardRequest with explaining message and + * initialising the object reference to the given value. + * + * @param why a string, explaining, why this exception has been thrown. + * @param a_forward_reference a value for forward_reference. + */ + public gnuForwardRequest(org.omg.CORBA.Object a_forward_reference) + { + if (a_forward_reference instanceof ObjectImpl) + this.forward_reference = (ObjectImpl) a_forward_reference; + else + throw new BAD_PARAM("ObjectImpl expected"); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java new file mode 100644 index 000000000..1234abce6 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdAssignmentPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdAssignmentPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID; +import org.omg.PortableServer.IdAssignmentPolicy; +import org.omg.PortableServer.IdAssignmentPolicyValue; + +/** + * Implementation of the id assignment policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdAssignmentPolicy + extends _PolicyImplBase + implements IdAssignmentPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdAssignmentPolicy(IdAssignmentPolicyValue v) + { + super(ID_ASSIGNMENT_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdAssignmentPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdAssignmentPolicyValue value() + { + return (IdAssignmentPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java new file mode 100644 index 000000000..21d8c54c4 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuIdUniquenessPolicy.java @@ -0,0 +1,80 @@ +/* gnuIdUniquenessPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.ID_UNIQUENESS_POLICY_ID; +import org.omg.PortableServer.IdUniquenessPolicy; +import org.omg.PortableServer.IdUniquenessPolicyValue; + +/** + * Implementation of the id uniqueness policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuIdUniquenessPolicy + extends _PolicyImplBase + implements IdUniquenessPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuIdUniquenessPolicy(IdUniquenessPolicyValue v) + { + super(ID_UNIQUENESS_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/IdUniquenessPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public IdUniquenessPolicyValue value() + { + return (IdUniquenessPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java new file mode 100644 index 000000000..96ce42708 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuImplicitActivationPolicy.java @@ -0,0 +1,80 @@ +/* gnuImplicitActivationPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.IMPLICIT_ACTIVATION_POLICY_ID; +import org.omg.PortableServer.ImplicitActivationPolicy; +import org.omg.PortableServer.ImplicitActivationPolicyValue; + +/** + * Implementation of the implicit activation policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuImplicitActivationPolicy + extends _PolicyImplBase + implements ImplicitActivationPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuImplicitActivationPolicy(ImplicitActivationPolicyValue v) + { + super(IMPLICIT_ACTIVATION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ImplicitActivationPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ImplicitActivationPolicyValue value() + { + return (ImplicitActivationPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java new file mode 100644 index 000000000..6efb9d603 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuLifespanPolicy.java @@ -0,0 +1,80 @@ +/* gnuLifespanPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.LIFESPAN_POLICY_ID; +import org.omg.PortableServer.LifespanPolicy; +import org.omg.PortableServer.LifespanPolicyValue; + +/** + * The implementation of the life span policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuLifespanPolicy + extends _PolicyImplBase + implements LifespanPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuLifespanPolicy(LifespanPolicyValue v) + { + super(LIFESPAN_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/LifespanPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public LifespanPolicyValue value() + { + return (LifespanPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java new file mode 100644 index 000000000..5d323305a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOA.java @@ -0,0 +1,1817 @@ +/* gnuAbstractPOA.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.java.lang.CPStringBuilder; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Object; +import org.omg.CORBA.Policy; +import org.omg.CORBA.SetOverrideType; +import org.omg.CORBA.TRANSIENT; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableInterceptor.NON_EXISTENT; +import org.omg.PortableInterceptor.ObjectReferenceFactory; +import org.omg.PortableInterceptor.ObjectReferenceTemplate; +import org.omg.PortableInterceptor.ObjectReferenceTemplateHelper; +import org.omg.PortableServer.AdapterActivator; +import org.omg.PortableServer.ForwardRequest; +import org.omg.PortableServer.IdAssignmentPolicy; +import org.omg.PortableServer.IdAssignmentPolicyValue; +import org.omg.PortableServer.IdUniquenessPolicy; +import org.omg.PortableServer.IdUniquenessPolicyValue; +import org.omg.PortableServer.ImplicitActivationPolicy; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.LifespanPolicy; +import org.omg.PortableServer.LifespanPolicyValue; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.RequestProcessingPolicy; +import org.omg.PortableServer.RequestProcessingPolicyValue; +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantActivator; +import org.omg.PortableServer.ServantLocator; +import org.omg.PortableServer.ServantManager; +import org.omg.PortableServer.ServantRetentionPolicy; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.ThreadPolicy; +import org.omg.PortableServer.ThreadPolicyValue; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.POAPackage.AdapterAlreadyExists; +import org.omg.PortableServer.POAPackage.AdapterNonExistent; +import org.omg.PortableServer.POAPackage.InvalidPolicy; +import org.omg.PortableServer.POAPackage.NoServant; +import org.omg.PortableServer.POAPackage.ObjectAlreadyActive; +import org.omg.PortableServer.POAPackage.ObjectNotActive; +import org.omg.PortableServer.POAPackage.ServantAlreadyActive; +import org.omg.PortableServer.POAPackage.ServantNotActive; +import org.omg.PortableServer.POAPackage.WrongAdapter; +import org.omg.PortableServer.POAPackage.WrongPolicy; + +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; + +/** + * Our POA implementation. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPOA + extends LocalObject + implements POA, ObjectReferenceFactory +{ + /** + * The object reference template, associated with this POA. + * + * @since 1.5 + */ + class RefTemplate implements ObjectReferenceTemplate + { + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + RefTemplate() + { + // The adapter name is computed once. + ArrayList names = new ArrayList(); + names.add(the_name()); + + POA poa = the_parent(); + while (poa != null) + { + names.add(poa.the_name()); + poa = poa.the_parent(); + } + + // Fill in the string array in reverse (more natural) order, + // root POA first. + m_adapter_name = new String[names.size()]; + + for (int i = 0; i < m_adapter_name.length; i++) + m_adapter_name[i] = (String) names.get(m_adapter_name.length - i - 1); + } + + /** + * The adapter name + */ + final String[] m_adapter_name; + + /** + * Get the name of this POA. + */ + public String[] adapter_name() + { + return (String[]) m_adapter_name.clone(); + } + + /** + * Get the ORB id. + */ + public String orb_id() + { + return m_orb.orb_id; + } + + /** + * Get the server id. + */ + public String server_id() + { + return OrbFunctional.server_id; + } + + /** + * Create the object. + */ + public Object make_object(String repositoryId, byte[] objectId) + { + return create_reference_with_id(objectId, repositoryId); + } + + /** + * Get the array of truncatible repository ids. + */ + public String[] _truncatable_ids() + { + return ref_template_ids; + } + } + + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The adapter reference template. + */ + ObjectReferenceTemplate refTemplate; + + /** + * The reference template repository ids. Defined outside the class as it + * cannot have static members. + */ + final static String[] ref_template_ids = + new String[] { ObjectReferenceTemplateHelper.id() }; + + /** + * The active object map, mapping between object keys, objects and servants. + */ + public final AOM aom = new AOM(); + + /** + * The children of this POA. + */ + final ArrayList children = new ArrayList(); + + /** + * The name of this POA. + */ + final String name; + + /** + * The parent of this POA (null for the root POA). + */ + final POA parent; + + /** + * The ior key signature, indicating, that the ior key is encoded using + * internal agreements of this implementation (0x'free'). + */ + static final int SIGNATURE = 0x66726565; + + /** + * The adapter activator for this POA, null if no activator is set. + */ + AdapterActivator m_activator; + + /** + * The POA manager for this POA. + */ + POAManager m_manager; + + /** + * The servant manager (servant activator) for this POA. + */ + ServantActivator servant_activator; + + /** + * The servant manager (servant locator) for this POA. + */ + ServantLocator servant_locator; + + /** + * The default servant, if on is in use. + */ + Servant default_servant; + + /** + * The cached poa id value, computed once. + */ + private byte[] m_poa_id; + + /** + * The all policy values that apply to this POA. + * The used policy values are singletons, unique between policies. + */ + private final HashSet m_policies; + + /** + * An array of the set policies. + */ + Policy[] s_policies; + + /** + * The ORB, where the POA is connected. + */ + final ORB_1_4 m_orb; + + /** + * When true, the POA is being destroyed or is destroyed. + */ + boolean m_inDestruction; + + /** + * True if the active object map is used by this POA. + * The value is moved into separate boolean value due + * necessity of the frequent checks. + */ + public final boolean retain_servant; + + /** + * The object reference factory, used to create the new object + * references. + */ + ObjectReferenceFactory m_object_factory = this; + + /** + * Create a new abstract POA. + * + * @param a_parent the parent of this POA. + * @param a_name a name for this POA. + * @param a_manager a manager for this POA. If null, a new + * {@link gnuPOAManager} will be instantiated. + * @param a_policies an array of policies that apply to this POA. + * @param an_orb an ORB for this POA. + */ + public gnuPOA(gnuPOA a_parent, String a_name, POAManager a_manager, + Policy[] a_policies, ORB_1_4 an_orb + ) + throws InvalidPolicy + { + // Add default policies. + Policy[] all_policies = StandardPolicies.withDefault(a_policies); + + name = a_name; + parent = a_parent; + m_orb = an_orb; + + if (a_manager != null) + m_manager = a_manager; + else + m_manager = new gnuPOAManager(); + + if (m_manager instanceof gnuPOAManager) + { + gnuPOAManager g = (gnuPOAManager) m_manager; + g.addPoa(this); + } + + m_policies = new HashSet(all_policies.length); + + s_policies = new Policy[ all_policies.length ]; + for (int i = 0; i < s_policies.length; i++) + { + s_policies [ i ] = all_policies [ i ].copy(); + m_policies.add(((AccessiblePolicy) s_policies [ i ]).getValue()); + } + + retain_servant = applies(ServantRetentionPolicyValue.RETAIN); + + validatePolicies(a_policies); + + refTemplate = new RefTemplate(); + } + + /** + * Wait while at least one of the threads in this POA is actively + * processing one of requests. + */ + public void waitWhileRunning() + { + // First pause. + long time = 1; + + // Maximal duration between checks. + long max = 500; + + boolean runs; + + do + { + runs = m_orb.currents.has(this); + + if (runs) + { + // Avoid taking CPU resources + // from the thread that is running. + try + { + Thread.sleep(time); + time = time * 2; + if (time > max) + time = max; + } + catch (InterruptedException ex) + { + } + } + } + while (runs); + } + + /** + * Etherealize all objects, associated with this POA. Invoked from the + * {@link gnuPOAManager} only if it is known that the servant_activator + * holds non-null value. + */ + protected void etherealizeAll() + { + if (servant_activator == null) + return; + + ArrayList keys = new ArrayList(); + keys.addAll(aom.keySet()); + + byte[] key; + AOM.Obj obj; + boolean last; + for (int i = 0; i < keys.size(); i++) + { + key = (byte[]) keys.get(i); + obj = aom.get(key); + + if (obj.poa == this) + { + aom.remove(key); + + if (!obj.isDeactiveted()) + { + // Check if the servant still stays under the other key. + last = aom.findServant(obj.servant) == null; + servant_activator.etherealize(obj.key, this, obj.servant, true, + last + ); + } + } + } + } + + /** + * Create an instance of the POA with the given features. + * This method is not responsible for duplicate checking + * or adding the returned instance to any possible table. + * + * @param child_name the name of the poa being created. + * @param a_manager the poa manager (never null). + * @param policies the array of policies. + * @param an_orb the ORB for this POA. + * + * @return the created POA. + * + * @throws InvalidPolicy for conflicting or otherwise invalid policies.| + */ + protected POA createPoaInstance(String child_name, POAManager a_manager, + Policy[] policies, ORB_1_4 an_orb + ) + throws InvalidPolicy + { + POAManager some_manager = + a_manager == null ? new gnuPOAManager() : a_manager; + + if (some_manager instanceof gnuPOAManager) + { + ((gnuPOAManager) some_manager).addPoa(this); + } + + return new gnuPOA(this, child_name, some_manager, policies, an_orb); + } + + /** + * Check if the given policy value applies to this POA. + * + * @param policy_value a policy value to check. The policy values are + * singletons and unique between the different policies, so the policy + * type is not passed. + * + * @return true if the policy value applies, false otherwise. + */ + public final boolean applies(java.lang.Object policy_value) + { + return m_policies.contains(policy_value); + } + + /** + * Check for the presence of the required policy. + * + * @param policy_value a policy value to check. + * + * @throws WrongPolicy if the required policy value is not applicable. + */ + public final void required(java.lang.Object policy_value) + throws WrongPolicy + { + if (!applies(policy_value)) + throw new WrongPolicy(policy_value + " policy required."); + } + + /** + * Check for the absence of the given policy. + * + * @param policy_value a policy value to check. + * + * @throws WrongPolicy if the passed policy value is applicable. + */ + public final void excluding(java.lang.Object policy_value) + throws WrongPolicy + { + if (applies(policy_value)) + throw new WrongPolicy(policy_value + " policy applies."); + } + + /** + * Find and optionally activate the child POA with the given name. + * + * @param poa_name the name of the POA to find. + * @param activate_it if the child with the specified name is not found + * or inactive and this parameter is true, the target POA activator is + * invoked to activate that child. If this succeeds, that child POA + * is returned. + * + * @throws AdapterNonExistent if no active child with the given name + * is found and one of the following is true: + * a) the target POA has no associated + * {@link AdapterActivator}. b) that activator fails to activate the + * child POA. c) <code>activate_id</code> = false. + */ + public POA find_POA(String poa_name, boolean activate_it) + throws AdapterNonExistent + { + POA child; + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(poa_name)) + return child; + } + + if (activate_it && m_activator != null) + { + boolean activated = m_activator.unknown_adapter(this, poa_name); + if (!activated) + throw new AdapterNonExistent(poa_name + " activation failed."); + + // Tha activator should add the child to the childrent table. + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(poa_name)) + return child; + } + throw new AdapterNonExistent(poa_name + " not created. "); + } + else + throw new AdapterNonExistent(poa_name); + } + + /** + * Generate the Object Id for the given servant and add the servant to the + * Active Object Map using this Id a a key. If the servant activator is set, + * its incarnate method will be called. + * + * @param a_servant a servant that would serve the object with the returned + * Object Id. If null is passed, under apporoprate policies the servant + * activator is invoked. + * + * @return the generated objert Id for the given servant. + * + * @throws ServantAlreadyActive if this servant is already in the Active + * Object Map and the UNIQUE_ID policy applies. + * + * @throws WrongPolicy if the required policies SYSTEM_ID and RETAIN do not + * apply to this POA. + */ + public byte[] activate_object(Servant a_servant) + throws ServantAlreadyActive, WrongPolicy + { + checkDiscarding(); + required(ServantRetentionPolicyValue.RETAIN); + required(IdAssignmentPolicyValue.SYSTEM_ID); + + AOM.Obj exists = aom.findServant(a_servant); + + if (exists != null) + { + if (exists.isDeactiveted()) + { + // If exists but deactivated, activate and return + // the existing key. + exists.setDeactivated(false); + incarnate(exists, exists.key, a_servant, false); + return exists.key; + } + else if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) + throw new ServantAlreadyActive(); + + // It multiple ids are allowed, exit block allowing repetetive + // activations. + } + + byte[] object_key = AOM.getFreeId(); + ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this, + object_key); + create_and_connect(object_key, + a_servant._all_interfaces(this, object_key)[0], delegate); + return object_key; + } + + /** + * Add the given servant to the Active Object Map as a servant for the object + * with the provided Object Id. If the servant activator is set, its incarnate + * method will be called. + * + * @param an_Object_Id an object id for the given object. + * @param a_servant a servant that will serve the object with the given Object + * Id. If null is passed, under apporoprate policies the servant activator is + * invoked. + * + * @throws ObjectAlreadyActive if the given object id is already in the Active + * Object Map. + * @throws ServantAlreadyActive if the UNIQUE_ID policy applies and this + * servant is already in use. + * @throws WrongPolicy if the required RETAIN policy does not apply to this + * POA. + * @throws BAD_PARAM if the passed object id is invalid due any reason. + */ + public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant) + throws ServantAlreadyActive, ObjectAlreadyActive, + WrongPolicy + { + activate_object_with_id(an_Object_Id, a_servant, false); + } + + /** + * Same as activate_object_with_id, but permits gnuForwardRequest forwarding + * exception. This is used when the activation is called from the remote + * invocation context and we have possibility to return the forwarding + * message. + */ + public void activate_object_with_id(byte[] an_Object_Id, Servant a_servant, + boolean use_forwarding) + throws ServantAlreadyActive, ObjectAlreadyActive, WrongPolicy + { + checkDiscarding(); + required(ServantRetentionPolicyValue.RETAIN); + + // If the UNIQUE_ID applies, the servant being passed must not be + // already active. + if (applies(IdUniquenessPolicyValue.UNIQUE_ID)) + { + AOM.Obj sx = aom.findServant(a_servant, false); + if (sx != null) + throw new ServantAlreadyActive(); + } + + AOM.Obj exists = aom.get(an_Object_Id); + if (exists != null) + { + if (exists.servant == null) + { + locateServant(an_Object_Id, a_servant, exists, use_forwarding); + exists.setDeactivated(false); + } + else if (exists.isDeactiveted()) + { + exists.setDeactivated(false); + incarnate(exists, an_Object_Id, a_servant, use_forwarding); + } + else + throw new ObjectAlreadyActive(); + } + else + { + ServantDelegateImpl delegate = new ServantDelegateImpl(a_servant, this, + an_Object_Id); + create_and_connect(an_Object_Id, a_servant._all_interfaces(this, + an_Object_Id)[0], delegate); + } + } + + /** + * Locate the servant for this object Id and connect it to ORB. + * + * @param an_Object_Id the object id. + * @param a_servant the servant (may be null). + * @param exists an existing active object map entry. + * @param use_forwarding allow to throw the gnuForwardRequest if the activator + * throws ForwardRequest. + * + * @throws OBJ_ADAPTER minor 4 if the servant cannot be located (the required + * servant manager may be missing). + */ + private void locateServant(byte[] an_Object_Id, Servant a_servant, + AOM.Obj exists, boolean use_forwarding + ) + throws InternalError + { + // An object was created with create_reference. + gnuServantObject object = (gnuServantObject) exists.object; + if (servant_activator != null) + { + exists.setServant(incarnate(exists, an_Object_Id, a_servant, + use_forwarding + ) + ); + } + else if (default_servant != null) + { + exists.setServant(default_servant); + } + if (exists.servant == null) + { + exists.setServant(a_servant); + } + if (exists.servant == null) + { + throw new OBJ_ADAPTER("no servant", 4, CompletionStatus.COMPLETED_NO); + } + + ServantDelegateImpl delegate = + new ServantDelegateImpl(exists.servant, this, an_Object_Id); + exists.servant._set_delegate(delegate); + object.setServant(exists.servant); + connect_to_orb(an_Object_Id, delegate.object); + } + + /** + * Deactivate object with the given id. + * + * The deactivated object will continue to process requests that arrived + * before decativation. If this POA has the associated + * servant manager, a {@link ServantActivatorOperations#etherealize} is + * immediately invoked on the passed id. + * + * @throws WrongPolicy if the required RETAIN policy does not apply to + * this POA. + */ + public void deactivate_object(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + AOM.Obj exists = aom.get(the_Object_Id); + + if (exists == null || exists.isDeactiveted()) + throw new ObjectNotActive(); + + exists.setDeactivated(true); + + // Check if this servant is serving something else. + aom.remove(the_Object_Id); + + AOM.Obj other = aom.findServant(exists.servant, false); + + boolean remaining = other != null; + + aom.put(exists); + + if (servant_activator != null) + servant_activator.etherealize(the_Object_Id, this, exists.servant, false, + remaining + ); + } + + /** + * Create the object reference, encapsulating the given repository Id and + * the Object Id, generated by this POA. The returned object will not be + * activated by default and may be activated on the first invocation by + * the servant manager (if it is set and if policies are applicable). + * + * @param a_repository_id the repository id for the given object, can + * be null if to be requested from the servant later. + * + * @throws WrongPolicy if the required SYSTEM_ID policy does not apply to + * this POA. + */ + public org.omg.CORBA.Object create_reference(String a_repository_id) + throws WrongPolicy + { + required(IdAssignmentPolicyValue.SYSTEM_ID); + return create_reference_with_id(AOM.getFreeId(), a_repository_id); + } + + /** + * <p> + * Create the object reference, encapsulating the given repository Id and + * the given Object Id. The returned object will <i>not</i> be + * activated by default and may be activated on the first invocation by + * the servant manager (if the IMPLICIT_ACTIVATION policy applies). + * + * @param an_object_id the object id for the object being created. If this + * POA uses the SYSTEM_ID policy, the portable application should only + * pass the ids, generated by this POA. + * + * @param a_repository_id the repository id for the object being created, + * can be null if this information should be later requested from the + * servant. + */ + public org.omg.CORBA.Object create_reference_with_id(byte[] an_object_id, + String a_repository_id + ) + { + String[] ids; + if (a_repository_id == null) + ids = null; + else + ids = new String[] { a_repository_id }; + + // Check maybe such object is already activated. + AOM.Obj e = aom.get(an_object_id); + + Servant servant; + if (e == null) + { + servant = null; + } + else + { + servant = e.servant; + e.setDeactivated(false); + } + + gnuServantObject object = + new gnuServantObject(ids, an_object_id, this, m_orb); + object._set_delegate(new LocalDelegate(object, this, an_object_id)); + aom.add(object.Id, object, servant, this); + connect_to_orb(an_object_id, object); + + return object; + } + + /** + * Creates a new POA as a child of the target POA. + * + * @param child_name the name of the child POA being created. + * @param manager the manager that will control the new POA. If this parameter + * is null, a new POA manager is created and associated with the new POA. + * + * @param policies the policies, applicable for the parent POA. Policies + * are <i>not</i> inherited from the parent POA. + * + * @return an newly created POA. The POA will be intially in the holding + * state and must be activated to start processing requests. + * + * @throws AdapterAlreadyExists if the child with the given child_name + * already exists for the current POA. + * @throws InvalidPolicy if the policies conflict with each other or are + * otherwise inappropriate. + * + * @see #the_children() + */ + public POA create_POA(String child_name, POAManager manager, Policy[] policies) + throws AdapterAlreadyExists, InvalidPolicy + { + POA child; + for (int i = 0; i < children.size(); i++) + { + child = (POA) children.get(i); + if (child.the_name().equals(child_name)) + throw new AdapterAlreadyExists(name + "/" + child_name); + } + + POA poa = createPoaInstance(child_name, manager, policies, m_orb); + children.add(poa); + return poa; + } + + /** + * Returns a default servant for this POA. + * + * @return a servant that will be used for requests for + * which no servant is found in the Active Object Map. + * + * @throws NoServant if there is no default servant associated with this POA. + * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. + */ + public Servant get_servant() + throws NoServant, WrongPolicy + { + required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); + if (default_servant == null) + throw new NoServant(); + return default_servant; + } + + /** + * Sets the default servant for this POA. + * + * @param a_servant a servant that will be used for requests for + * which no servant is found in the Active Object Map. + * + * @throws WrongPolicy if the USE_DEFAULT_SERVANT policy is not active. + */ + public void set_servant(Servant a_servant) + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT); + default_servant = a_servant; + } + + /** + * Set a servant manager for this POA. + * + * @param a servant manager being set. If the RETAIN policy applies, the + * manager must implement a {@link ServantActivator}. If the NON_RETAIN + * policy applies, the manager must implement a {@link ServantLocator}. + * + * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not + * apply to this POA. + * + * @throws OBJ_ADAPTER minor code 4 if the passed manager does not + * implement the required interface ({@link ServantActivator}, + * {@link ServantLocator}). The POA, that has the RETAIN policy uses + * servant managers that are ServantActivators. When the POA has the + * NON_RETAIN policy it uses servant managers that are ServantLoacators. + * + * @throws BAD_INV_ORDER minor code 6 if the method is called more than once + * on the same POA. The manager can be set only once. + */ + public void set_servant_manager(ServantManager a_manager) + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); + if (servant_activator != null || servant_locator != null) + throw new BAD_INV_ORDER("Setting manager twice for " + name, 6, + CompletionStatus.COMPLETED_NO + ); + + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + if (a_manager instanceof ServantActivator) + servant_activator = (ServantActivator) a_manager; + else + throw new OBJ_ADAPTER("RETAIN requires ServantActivator", 4, + CompletionStatus.COMPLETED_NO + ); + } + else if (applies(ServantRetentionPolicyValue.NON_RETAIN)) + { + if (a_manager instanceof ServantLocator) + servant_locator = (ServantLocator) a_manager; + else + throw new OBJ_ADAPTER("NON_RETAIN requires ServantLocator", 4, + CompletionStatus.COMPLETED_NO + ); + } + else + throw new WrongPolicy("No servant retention policy is specified."); + } + + /** + * Get the servant manager, associated with this POA. + * + * @return the associated servant manager or null if it has + * been previously set. + * + * @throws WrongPolicy if the required USE_SERVANT_MANAGER policy does not + * apply to this POA. + */ + public ServantManager get_servant_manager() + throws WrongPolicy + { + required(RequestProcessingPolicyValue.USE_SERVANT_MANAGER); + + if (servant_activator != null) + return servant_activator; + else + return servant_locator; + } + + /** + * Get the unique Id of the POA in the process in which it is created. + * This Id is needed by portable interceptors. The id is unique + * for the life span of the POA in the process. For persistent + * POAs, if a POA is created in the same path with the same name as + * another POA, these POAs are identical have the same id. All transient + * POAs are assumed unique. + */ + public byte[] id() + { + if (m_poa_id != null) + return m_poa_id; + else + { + BufferedCdrOutput buffer = new BufferedCdrOutput(); + POA p = this; + while (p != null) + { + buffer.write_string(p.the_name()); + p = p.the_parent(); + } + m_poa_id = buffer.buffer.toByteArray(); + return m_poa_id; + } + } + + /** + * Returns the reference to the active object with the given Id. + * + * @param the_Object_Id the object id. + * + * @throws ObjectNotActive if there is no active object with such Id + * in the scope of this POA. + * @throws WrongPolicy if the required RETAIN policy does not apply to + * this POA. + */ + public org.omg.CORBA.Object id_to_reference(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + AOM.Obj ref = aom.get(the_Object_Id); + if (ref == null) + throw new ObjectNotActive(); + else + return ref.object; + } + + /** + * Returns the servant that serves the active object with the given Id. + * + * @param the_Object_Id the object id. + * + * @throws ObjectNotActive if there is no active object with such Id or + * it is not currently active. + * @throws WrongPolicy. This method requires either RETAIN or + * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them + * apply to this POA. + */ + public Servant id_to_servant(byte[] the_Object_Id) + throws ObjectNotActive, WrongPolicy + { + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + AOM.Obj ref = aom.get(the_Object_Id); + if (ref == null || ref.isDeactiveted()) + { + if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else if (ref.servant != null) + return ref.servant; + else if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else if (default_servant != null) + { + return default_servant; + } + else + throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); + } + + /** + * Returns the Object Id, encapsulated in the given object reference. + * + * @param the_Object the object that has been previously created with this + * POA. It need not be active. + * + * @throws WrongAdapter if the passed object is not known for this POA. + * @throws WrongPolicy never (declared for the future extensions only). + */ + public byte[] reference_to_id(org.omg.CORBA.Object the_Object) + throws WrongAdapter, WrongPolicy + { + AOM.Obj ref = aom.findObject(the_Object); + if (ref == null) + throw new WrongAdapter(); + return ref.key; + } + + /** + * Returns the servant that is serving this object. + * + * @return if the RETAIN policy applies and the object is in the Active Object + * Map, the method returns the servant, associated with this object. + * Otherwise, if the USE_DEFAULT_SERVANT policy applies, the method returns + * the default servant (if one was set). + * + * @throws ObjectNotActive if none of the conditions above are satisfied. + * @throws WrongAdapter if the object reference was not created with this POA. + * @throws WrongPolicy. This method requires either RETAIN or + * USE_DEFAULT_SERVANT policies and reaises the WrongPolicy if none of them + * apply to this POA. + */ + public Servant reference_to_servant(org.omg.CORBA.Object the_Object) + throws ObjectNotActive, WrongPolicy, WrongAdapter + { + if (applies(ServantRetentionPolicyValue.RETAIN)) + { + AOM.Obj ref = aom.findObject(the_Object); + if (ref == null) + { + String object; + if (the_Object == null) + object = "null passed"; + else if (the_Object instanceof gnuServantObject) + { + gnuServantObject gs = (gnuServantObject) the_Object; + object = "Wrong owner POA " + gs.poa.the_name(); + } + else + object = "Unknown " + the_Object.getClass().getName(); + + throw new WrongAdapter(object + " for '" + the_name() + "'"); + } + else if (ref.isDeactiveted() || ref.servant == null) + { + if (default_servant != null) + return default_servant; + else + throw new ObjectNotActive(); + } + else + return ref.servant; + } + else if (default_servant != null) + { + return default_servant; + } + else + throw new WrongPolicy("Either RETAIN or USE_DEFAULT_SERVANT required."); + } + + /** + * Returns the id of the object, served by the given servant (assuming that + * the servant serves only one object). The id is found in one of the + * following ways. + * <ul> + * <li>If the POA has both the RETAIN and the UNIQUE_ID policy and the + * specified servant is active, the method return the Object Id associated + * with that servant. </li> + * <li> If the POA has both the RETAIN and the IMPLICIT_ACTIVATION policy and + * either the POA has the MULTIPLE_ID policy or the specified servant is + * inactive, the method activates the servant using a POA-generated Object Id + * and the Interface Id associated with the servant, and returns that Object + * Id. </li> + * <li>If the POA has the USE_DEFAULT_SERVANT policy, the servant specified + * is the default servant, and the method is being invoked in the context of + * executing a request on the default servant, the method returns the ObjectId + * associated with the current invocation. </li> + * </ul> + * + * @throws ServantNotActive in all cases, not listed in the list above. + * @throws WrongPolicy The method requres USE_DEFAULT_SERVANT policy or a + * combination of the RETAIN policy and either the UNIQUE_ID or + * IMPLICIT_ACTIVATION policies and throws the WrongPolicy if these conditions + * are not satisfied. + */ + public byte[] servant_to_id(Servant the_Servant) + throws ServantNotActive, WrongPolicy + { + if (applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) || + applies(ServantRetentionPolicyValue.RETAIN) && + ( + applies(IdUniquenessPolicyValue.UNIQUE_ID) || + applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + ) + ) + { + AOM.Obj ref = null; + if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) + ref = aom.findServant(the_Servant); + if (ref == null && + applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) + ) + { + // Try to activate. + try + { + return activate_object(the_Servant); + } + catch (ServantAlreadyActive ex) + { + // Either it shuld not be or the policy allows multiple ids. + throw new InternalError(); + } + } + if (ref == null) + throw new ServantNotActive(); + else + return ref.key; + } + else + throw new WrongPolicy("(RETAIN and UNIQUE ID) " + + "or USE_DEFAULT_SERVANT required." + ); + } + + /** + * <p> + * Converts the given servant to the object reference. The servant will serve + * all methods, invoked on the returned object. The returned object reference + * can be passed to the remote client, enabling remote invocations. + * </p> + * <p> + * If the specified servant is active, it is returned. Otherwise, if the POA + * has the IMPLICIT_ACTIVATION policy the method activates the servant. In + * this case, if the servant activator is set, the + * {@link ServantActivatorOperations#incarnate} method will be called. + * </p> + * + * @throws ServantNotActive if the servant is inactive and no + * IMPLICIT_ACTIVATION policy applies. + * @throws WrongPolicy This method needs the RETAIN policy and either the + * UNIQUE_ID or IMPLICIT_ACTIVATION policies. + * + * @return the object, exposing the given servant in the context of this POA. + */ + public org.omg.CORBA.Object servant_to_reference(Servant the_Servant) + throws ServantNotActive, WrongPolicy + { + required(ServantRetentionPolicyValue.RETAIN); + + AOM.Obj exists = null; + + if (!applies(IdUniquenessPolicyValue.MULTIPLE_ID)) + exists = aom.findServant(the_Servant); + + if (exists != null) + { + if (exists.isDeactiveted()) + { + if (applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)) + { + checkDiscarding(); + exists.setDeactivated(false); + incarnate(exists, exists.key, the_Servant, false); + } + else + throw new ServantNotActive(); + } + else + return exists.object; + } + if (exists == null + && applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION)) + { + checkDiscarding(); + + byte[] object_key = AOM.getFreeId(); + + ServantDelegateImpl delegate = new ServantDelegateImpl(the_Servant, + this, object_key); + create_and_connect(object_key, the_Servant._all_interfaces(this, + object_key)[0], delegate); + + return delegate.object; + } + else + throw new ServantNotActive(); + } + + /** + * Incarnate in cases when request forwarding is not expected because the + * servant must be provided by the servant activator. + * + * @param x the aom entry, where the object is replaced by value, returned by + * servant activator (if not null). + * + * @param object_key the object key. + * + * @param a_servant the servant that was passed as a parameter in the + * activation method. + * + * @param use_forwarding if true, the gnuForwardRequest is throw under the + * forwarding exception (for remote client). Otherwise, the request is + * internally redirected (for local invocation). + */ + private Servant incarnate(AOM.Obj x, byte[] object_key, + Servant a_servant, boolean use_forwarding + ) + { + if (servant_activator != null) + { + Servant servant; + try + { + servant = servant_activator.incarnate(object_key, this); + } + catch (ForwardRequest ex) + { + if (use_forwarding) + throw new gnuForwardRequest(ex.forward_reference); + else + servant = + ForwardedServant.create((ObjectImpl) ex.forward_reference); + } + if (servant != null && x != null) + x.setServant(servant); + if (servant == null && x != null) + servant = x.servant; + return servant; + } + else if (a_servant != null) + { + x.setServant(a_servant); + return a_servant; + } + else if (x.servant != null) + { + return x.servant; + } + else if (default_servant != null) + { + x.setServant(default_servant); + return x.servant; + } + else + throw new BAD_INV_ORDER("No servant given and the servant activator not set"); + } + + /** + * Return the POA manager, associated with this POA. + * + * @return the associated POA manager (always available). + */ + public POAManager the_POAManager() + { + return m_manager; + } + + /** + * Returns the adapter activator, associated with this POA. + * The newly created POA has no activator (null would be + * returned). The ORB root POA also initially has no activator. + * + * @return tha adapter activator or null if this POA has no + * associated adapter activator. + */ + public AdapterActivator the_activator() + { + return m_activator; + } + + /** + * Set the adapter activator for this POA. + * + * @param an_activator the activator being set. + */ + public void the_activator(AdapterActivator an_activator) + { + m_activator = an_activator; + } + + /** + * The children of this POA. + * + * @return the array of all childs for this POA. + */ + public POA[] the_children() + { + POA[] poas = new POA[ children.size() ]; + for (int i = 0; i < poas.length; i++) + { + poas [ i ] = (POA) children.get(i); + } + return poas; + } + + /** + * Return the name of this POA. + * + * @return the name of POA, relative to its parent. + */ + public String the_name() + { + return name; + } + + /** + * Return the parent of this POA. + * + * @return the parent POA or <code>null</code> if this is a root POA. + */ + public POA the_parent() + { + return parent; + } + + /** {@inheritDoc} */ + public IdAssignmentPolicy create_id_assignment_policy(IdAssignmentPolicyValue a_value) + { + return new gnuIdAssignmentPolicy(a_value); + } + + /** {@inheritDoc} */ + public IdUniquenessPolicy create_id_uniqueness_policy(IdUniquenessPolicyValue a_value) + { + return new gnuIdUniquenessPolicy(a_value); + } + + /** {@inheritDoc} */ + public ImplicitActivationPolicy create_implicit_activation_policy(ImplicitActivationPolicyValue a_value) + { + return new gnuImplicitActivationPolicy(a_value); + } + + /** {@inheritDoc} */ + public LifespanPolicy create_lifespan_policy(LifespanPolicyValue a_value) + { + return new gnuLifespanPolicy(a_value); + } + + /** {@inheritDoc} */ + public RequestProcessingPolicy create_request_processing_policy(RequestProcessingPolicyValue a_value) + { + return new gnuRequestProcessingPolicy(a_value); + } + + /** {@inheritDoc} */ + public ServantRetentionPolicy create_servant_retention_policy(ServantRetentionPolicyValue a_value) + { + return new gnuServantRetentionPolicy(a_value); + } + + /** {@inheritDoc} */ + public ThreadPolicy create_thread_policy(ThreadPolicyValue a_value) + { + return new gnuThreadPolicy(a_value); + } + + /** + * <p> + * Destroy this POA and all descendant POAs. The destroyed POAs can be later + * re-created via {@link AdapterActivator} or by invoking {@link #create_POA}. + * This differs from {@link PoaManagerOperations#deactivate} that does not + * allow recreation of the deactivated POAs. After deactivation, recreation is + * only possible if the POAs were later destroyed. + * </p> + * <p> + * The remote invocation on the target, belonging to the POA that is currently + * destroyed return the remote exception ({@link TRANSIENT}, minor code 4). + * </p> + * + * @param etherealize_objects if true, and POA has RETAIN policy, and the + * servant manager is available, the servant manager method + * {@link ServantActivatorOperations#etherealize} is called for each <i>active</i> + * object in the Active Object Map. This method should not try to access POA + * being destroyed. If <code>destroy</code> is called multiple times before + * the destruction completes, the etherialization should be invoked only once. + * + * @param wait_for_completion if true, the method waits till the POA being + * destroyed completes all current requests and etherialization. If false, the + * method returns immediately. + */ + public void destroy(boolean etherealize_objects, boolean wait_for_completion) + { + // Notify the IOR interceptors about that the POA is destroyed. + if (m_orb.iIor != null) + m_orb.iIor.adapter_state_changed( + new ObjectReferenceTemplate[] { getReferenceTemplate() }, + NON_EXISTENT.value); + + if (wait_for_completion) + waitWhileRunning(); + + // Nofify the IOR interceptors that the POA is destroyed. + if (m_manager instanceof gnuPOAManager) + { + ((gnuPOAManager) m_manager).poaDestroyed(this); + } + + // Put the brake instead of manager, preventing the subsequent + // requests. + gnuPOAManager g = new gnuPOAManager(); + g.state = State.INACTIVE; + m_manager = g; + + // Disconnect from parent. + if (parent instanceof gnuPOA) + { + ((gnuPOA) parent).children.remove(this); + } + + unregisterFromManager(); + + // Disconnect from the ORB all objects, registered with this POA. + ArrayList keys = new ArrayList(); + keys.addAll(aom.keySet()); + + byte[] key; + AOM.Obj obj; + for (int i = 0; i < keys.size(); i++) + { + key = (byte[]) keys.get(i); + obj = aom.get(key); + if (obj.poa == this) + m_orb.disconnect(obj.object); + } + + m_orb.identityDestroyed(this); + + if (etherealize_objects && servant_activator != null && !m_inDestruction) + { + etherealizeAll(); + } + m_inDestruction = true; + + POA[] ch = the_children(); + for (int i = 0; i < ch.length; i++) + { + ch[i].destroy(etherealize_objects, wait_for_completion); + } + } + + /** + * Destroy this POA if it has not been destroyed, destroys it. + */ + protected void finalize() + throws java.lang.Throwable + { + if (!m_inDestruction) + destroy(false, false); + } + + /** + * Remove self from the manager list. + */ + private void unregisterFromManager() + { + if (m_manager instanceof gnuPOAManager) + { + gnuPOAManager p = (gnuPOAManager) m_manager; + p.removePOA(this); + } + } + + /** + * Get the policy of the given type, associated with this POA. + * + * @param a_policy_type a type of the requested policy. + * @return a policy of the given type, applyting to this POA. + * + * @throws org.omg.CORBA.BAD_PARAM if the policy of this type has not + * been specified for this POA. + */ + public Policy _get_policy(int a_policy_type) + throws org.omg.CORBA.BAD_PARAM + { + for (int i = 0; i < s_policies.length; i++) + { + if (s_policies [ i ].policy_type() == a_policy_type) + return s_policies [ i ].copy(); + } + throw new BAD_PARAM("No policy type " + a_policy_type); + } + + /** + * Get the copy of the policy array. + */ + public Policy[] getPolicyArray() + { + Policy[] r = new Policy[ s_policies.length ]; + for (int i = 0; i < s_policies.length; i++) + { + r [ i ] = s_policies [ i ].copy(); + } + return r; + } + + /** + * The POAs cannot be created by this method. + * + * @specnote this is also not possible in Suns jdk at least till 1.4. + * + * @throws NO_IMPLEMENT always. + */ + public org.omg.CORBA.Object _set_policy_override(Policy[] policies, + SetOverrideType how + ) + { + throw new NO_IMPLEMENT("Use createPOA instead."); + } + + /** + * Get the ORB, where this POA is connected. + */ + public ORB orb() + { + return m_orb; + } + + /** + * Connect the given delegate under the given key, also calling incarnate. + */ + private void create_and_connect(byte[] object_key, String repository_id, + ServantDelegateImpl delegate) + { + aom.add(delegate); + connect_to_orb(object_key, getReferenceFactory().make_object(repository_id, + object_key)); + if (servant_activator != null) + incarnate(null, object_key, delegate.servant, false); + } + + /** + * Check if the POA is not in a discarding mode. The activation + * operations are forbidded in discarding mode. + * + * @throws TRANSIENT if the POA is in discarding mode. + */ + void checkDiscarding() + throws TRANSIENT + { + if (m_manager.get_state() == State.DISCARDING) + throw new TRANSIENT("Discarding mode", 1, CompletionStatus.COMPLETED_MAYBE); + } + + /** + * Connect the given delegate object to orb. + */ + protected void connect_to_orb(byte[] an_Object_Id, org.omg.CORBA.Object object) + { + if (applies(ThreadPolicyValue.SINGLE_THREAD_MODEL)) + m_orb.connect_1_thread(object, toIORKey(an_Object_Id), this); + else + m_orb.connect(object, toIORKey(an_Object_Id)); + } + + /** + * Returns the representation of this POA tree. + */ + public String toString() + { + CPStringBuilder b = new CPStringBuilder(name); + + if (children.size() != 0) + { + b.append(" ("); + + for (int i = 0; i < children.size(); i++) + { + b.append(children.get(i)); + if (i < children.size() - 2) + b.append(", "); + } + b.append(")"); + } + return b.toString(); + } + + /** + * Check if the policy set is valid. + */ + protected boolean validatePolicies(Policy[] a) + throws InvalidPolicy + { + if (applies(ServantRetentionPolicyValue.NON_RETAIN)) + { + if (!applies(RequestProcessingPolicyValue.USE_DEFAULT_SERVANT) && + !applies(RequestProcessingPolicyValue.USE_SERVANT_MANAGER) + ) + { + short p = 0; + for (short i = 0; i < a.length; i++) + { + if (a [ i ].policy_type() == SERVANT_RETENTION_POLICY_ID.value) + p = i; + } + throw new InvalidPolicy("NON_RETAIN requires either " + + "USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER", + p + ); + } + } + return true; + } + + /** + * Recursively searches for the given object in the POA tree. + */ + public AOM.Obj findObject(org.omg.CORBA.Object object) + { + AOM.Obj h = aom.findObject(object); + if (h != null) + return h; + else + { + for (int i = 0; i < children.size(); i++) + { + h = ((gnuPOA) children.get(i)).findObject(object); + if (h != null) + return h; + } + } + return h; + } + + /** + * Recursively searches for the given key in the POA tree. + * @param ior_key the key, ecapsulating both object + * and poa ids. + * @return + */ + public AOM.Obj findKey(byte[] object_id, byte[] poa_id) + { + AOM.Obj h = null; + if (Arrays.equals(poa_id, id())) + h = aom.get(object_id); + if (h != null) + return h; + else + { + for (int i = 0; i < children.size(); i++) + { + h = ((gnuPOA) children.get(i)).findKey(object_id, poa_id); + if (h != null) + return h; + } + } + return h; + } + + /** + * Parses the given key, extracts poa and object id and searches + * for such reference. + */ + public AOM.Obj findIorKey(byte[] ior_key) + { + BufferredCdrInput in = new BufferredCdrInput(ior_key); + int signature = in.read_long(); + if (signature != SIGNATURE) + return null; + + byte[] id = in.read_sequence(); + byte[] poa = in.read_sequence(); + return findKey(id, poa); + } + + /** + * Converts the object Id into the IOR key. IOR key must be + * unique in the scope of the ORB, and Ids only in the scope of POA. + * Hence the IOR key includes the POA identifiers. + */ + public byte[] toIORKey(byte[] object_id) + { + BufferedCdrOutput buffer = new BufferedCdrOutput(); + buffer.write_long(SIGNATURE); + buffer.write_sequence(object_id); + buffer.write_sequence(id()); + return buffer.buffer.toByteArray(); + } + + /** + * Extracts the object id from the ior key. + * + * @param ior_key + * + * @return the encapsulated object ior key or null if + * this ior key either refers a different POA or encoding signature + * mismatch. + */ + public byte[] idFormIor(byte[] ior_key) + { + BufferredCdrInput in = new BufferredCdrInput(ior_key); + int signature = in.read_long(); + if (signature != SIGNATURE) + return null; + + byte[] object_id = in.read_sequence(); + byte[] poa_id = in.read_sequence(); + if (Arrays.equals(poa_id, id())) + return object_id; + else + return null; + } + + /** + * Recursively searches for the given servant in the POA tree. + */ + public AOM.Obj findServant(Servant servant) + { + AOM.Obj h = aom.findServant(servant); + if (h != null) + return h; + else + { + for (int i = 0; i < children.size(); i++) + { + h = ((gnuPOA) children.get(i)).findServant(servant); + if (h != null) + return h; + } + } + return h; + } + + /** + * Get the object reference template of this POA. + * Instantiate a singleton instance, if required. + */ + public ObjectReferenceTemplate getReferenceTemplate() + { + if (refTemplate == null) + refTemplate = new RefTemplate(); + + return refTemplate; + } + + public ObjectReferenceFactory getReferenceFactory() + { + return m_object_factory; + } + + public void setReferenceFactory(ObjectReferenceFactory factory) + { + m_object_factory = factory; + } + + /** + * Create the object (needed by the factory interface). + */ + public Object make_object(String a_repository_id, byte[] an_object_id) + { + AOM.Obj existing = aom.get(an_object_id); + // The object may already exist. In this case, it is just returned. + if (existing != null && existing.object != null) + return existing.object; + else + { + return new gnuServantObject(new String[] { a_repository_id }, + an_object_id, this, m_orb); + } + } + + /** + * Required by object reference factory ops. + */ + public String[] _truncatable_ids() + { + return ref_template_ids; + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java new file mode 100644 index 000000000..db43751a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPOAManager.java @@ -0,0 +1,272 @@ +/* gnuPOAManager.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.BAD_INV_ORDER; +import org.omg.CORBA.LocalObject; +import org.omg.PortableInterceptor.NON_EXISTENT; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.AdapterInactive; +import org.omg.PortableServer.POAManagerPackage.State; + +import java.util.HashSet; +import java.util.Iterator; + +/** + * The implementation of the POA manager. The manager is a controlled + * switch that can change its states in response to the method calls + * and throw exceptions if the requested change is invalid. It is possible + * to check the state this switch. It does not do anything else. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPOAManager + extends LocalObject + implements POAManager +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The POAs, controlled by this manager. + */ + private HashSet POAs = new HashSet(); + + /** + * The state of the manager. The newly created manager is always + * in the holding state. + */ + State state = State.HOLDING; + + /** + * Get the state of the POA manager. + */ + public State get_state() + { + return state; + } + + /** + * Turns the associated POAs into active state, allowing them to receive + * and process requests. + * + * @throws AdapterInactive if the POAs are in the inactive state. + * If once inactivated, the POA cannot be activated again. This + * method can only be called to leave the holding or discarding state. + */ + public void activate() + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.ACTIVE; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + } + + /** + * Turns the associated POAs into holding state. In this state, the POAs + * queue incoming requests but do not process them. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void hold_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.HOLDING; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + } + + /** + * + * Turns the asociated POAs into inactive state. The POAs in the incative + * state will reject new requests. If the POA is once inactivated, it + * cannot be activated again. The operation is used when + * the associated POAs are to be shut down. + * + * @param etherealize_objects if true, the servant managers of the + * associated POAs, having RETAIN and USE_SERVANT_MANAGER policies, + * will receive a call of {@link ServantActivatorOperations#etherealize}. + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + * + * @throws AdapterInactive if the POAs are already in the inactive state. + * + * @see POAOperations#destroy + */ + public void deactivate(boolean etherealize_objects, + boolean wait_for_completion + ) + throws AdapterInactive + { + if (state == State.INACTIVE) + throw new AdapterInactive("Repetetive inactivation"); + state = State.INACTIVE; + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + + Iterator iter = POAs.iterator(); + while (iter.hasNext()) + { + gnuPOA poa = (gnuPOA) iter.next(); + + // If the servant activator is non null, this means it has been + // set - hence the policies are appropriate. + if (poa.servant_activator != null) + poa.etherealizeAll(); + } + } + + /** + * Turns the associated POAs into discaring state. In this state, the POAs + * discard the incoming requests. This mode is used in situations when + * the server is flooded with requests. The client receives remote exception + * ({@link org.omg.CORBA.TRANSIENT}, minor code 1). + * + * @param wait_for_completion if true, the method call suspends the current + * thread till POAs complete the requests they are currently processing. If + * false, the method returns immediately. + + * @throws AdapterInactive if the POAs are in the inactive state. + */ + public void discard_requests(boolean wait_for_completion) + throws AdapterInactive + { + if (state != State.INACTIVE) + state = State.DISCARDING; + else + throw new AdapterInactive(); + + notifyInterceptors(state.value()); + + if (wait_for_completion) + waitForIdle(); + } + + /** + * Suspend the current thread while at least one of the associated POA is + * actively processing some requests. The method assumes that the POAs + * are not accepting the <i>new</i> requests due manager state. + * + * @throws BAD_INV_ORDER if the POAs are in the active state. + */ + public void waitForIdle() + { + if (state == State.ACTIVE) + throw new BAD_INV_ORDER("The state is active"); + + gnuPOA poa; + Iterator iter = POAs.iterator(); + + while (iter.hasNext()) + { + poa = (gnuPOA) iter.next(); + poa.waitWhileRunning(); + } + } + + /** + * Add the POA that will be controlled by this manager. + * + * @param poa the POA. + */ + public void addPoa(gnuPOA poa) + { + POAs.add(poa); + } + + /** + * Remove the POA, releasing it from the control of this manager. + * Called in POA finaliser. + * + * @param poa the POA to remove. + */ + public void removePOA(gnuPOA poa) + { + POAs.remove(poa); + } + + /** + * This method is called when POA is destryed. The interceptors are + * notified. + */ + public void poaDestroyed(gnuPOA poa) + { + notifyInterceptors(NON_EXISTENT.value); + } + + /** + * Notify CORBA 3.0 interceptors about the status change. + */ + public synchronized void notifyInterceptors(int new_state) + { + gnuPOA poa; + Iterator iter = POAs.iterator(); + + // The System.identityHashCode is also called in gnuIorInfo. + while (iter.hasNext()) + { + poa = (gnuPOA) iter.next(); + if (poa.m_orb.iIor != null) + { + poa.m_orb.iIor.adapter_manager_state_changed( + System.identityHashCode(this), (short) new_state); + } + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java new file mode 100644 index 000000000..d489d0e83 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuPoaCurrent.java @@ -0,0 +1,179 @@ +/* gnuPoaCurrent.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import org.omg.CORBA.CurrentHelper; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.PortableServer.Current; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.CurrentPackage.NoContext; +import org.omg.PortableServer.POA; + +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; + +/** + * Supports the "Poa current" concept, providing the id and poa of + * the object currently being served. There is only one instance + * of this class per ORB. It maintains a thread to information map. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuPoaCurrent + extends ObjectImpl + implements Current +{ + /** + * The table, mapping threads to records. + */ + private TreeMap threads = new TreeMap(); + + /** + * Get the array of POA current repository ids. + * + * @return a single member array, containing value, returned + * by the {@link CurrentHelper#id}, normally + * "IDL:omg.org/PortableServer/Current:2.3". + */ + public String[] _ids() + { + return new String[] { CurrentHelper.id() }; + } + + /** + * Get the object id, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public byte[] get_object_id() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_object_id(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Get the object POA, associated with the thread currently being served. + * + * @throws NoContext if the current thread is not associated with any + * object. + */ + public POA get_POA() + throws NoContext + { + CurrentOperations r; + synchronized (threads) + { + r = (CurrentOperations) threads.get(Thread.currentThread().getName()); + } + if (r != null) + return r.get_POA(); + else + throw new NoContext(Thread.currentThread().getName()); + } + + /** + * Add the entry to the map. + */ + public void put(Thread t, CurrentOperations record) + { + synchronized (threads) + { + threads.put(t.getName(), record); + } + } + + /** + * Check if this Poa has some running threads. + */ + public boolean has(POA poa) + { + synchronized (threads) + { + Iterator iter = threads.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry item = (Map.Entry) iter.next(); + try + { + if (((CurrentOperations) item.getValue()).get_POA() == poa) + { + return true; + } + } + catch (NoContext ex) + { + throw new InternalError(); + } + } + } + return false; + } + + /** + * Check if this thread is registered. + */ + public boolean has(Thread t) + { + synchronized (threads) + { + return threads.containsKey(t.getName()); + } + } + + /** + * Remove the entry from the map. + */ + public void remove(Thread t) + { + synchronized (threads) + { + threads.remove(t.getName()); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java new file mode 100644 index 000000000..4e322e5e2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuRequestProcessingPolicy.java @@ -0,0 +1,80 @@ +/* gnuRequestProcessingPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.REQUEST_PROCESSING_POLICY_ID; +import org.omg.PortableServer.RequestProcessingPolicy; +import org.omg.PortableServer.RequestProcessingPolicyValue; + +/** + * The implementation of the request processing policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuRequestProcessingPolicy + extends _PolicyImplBase + implements RequestProcessingPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuRequestProcessingPolicy(RequestProcessingPolicyValue v) + { + super(REQUEST_PROCESSING_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/RequestProcessingPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public RequestProcessingPolicyValue value() + { + return (RequestProcessingPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java new file mode 100644 index 000000000..17ef452a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantObject.java @@ -0,0 +1,825 @@ +/* gnuServantObject.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.IorObject; +import gnu.CORBA.Interceptor.gnuServerRequestInfo; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.Minor; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.Unexpected; +import gnu.CORBA.ResponseHandlerImpl; +import gnu.CORBA.StreamHolder; + +import gnu.java.lang.CPStringBuilder; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BAD_PARAM; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.OBJECT_NOT_EXIST; +import org.omg.CORBA.OBJ_ADAPTER; +import org.omg.CORBA.ORB; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TRANSIENT; +import org.omg.CORBA.UserException; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.PortableInterceptor.ForwardRequest; +import org.omg.PortableInterceptor.ServerRequestInterceptorOperations; +import org.omg.PortableServer.CurrentOperations; +import org.omg.PortableServer.DynamicImplementation; +import org.omg.PortableServer.ImplicitActivationPolicyValue; +import org.omg.PortableServer.POA; +import org.omg.PortableServer.POAManager; +import org.omg.PortableServer.POAManagerPackage.State; +import org.omg.PortableServer.Servant; +import org.omg.PortableServer.ServantLocatorPackage.CookieHolder; +import org.omg.PortableServer.ServantRetentionPolicyValue; +import org.omg.PortableServer.portable.Delegate; + +import java.io.IOException; + +import java.util.Arrays; + +/** + * Represents a CORBA object, being locally served by the associated servant. + * The calls to the object are forwarded to the calls to the servant. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantObject extends ObjectImpl + implements org.omg.CORBA.Object, + InvokeHandler, + CurrentOperations, + IorProvider +{ + /** + * The associated servant that must also implement the {@link InvokeHandler} + * interface. This value can be temporary null if the object was created using + * POA.create_reference or POA.create_reference_with_id, private to force + * always to use {@link setServant}. + */ + private Servant servant; + + /** + * The Id of this object. + */ + public final byte[] Id; + + /** + * The poa that takes care about this object. + */ + public final gnuPOA poa; + + /** + * The POA manager, used to control the work of this object. + */ + public final POAManager manager; + + /** + * The orb. + */ + public final ORB_1_4 orb; + + /** + * The object repository ids, if they were specified separately. Normally, the + * ids are requested from the servant. + */ + public final String[] repository_ids; + + /** + * True indicates that the NO_RETAIN policy applies for the servant. + * The servant must be discarded after the each call. + */ + boolean noRetain; + + /** + * Create an object with no connected servant. The servant must be set later. + * + * @param a_repository_ids an array of repository ids, can be null (then ids + * will be requested from the servant). + * @param an_id the object id. + * @param a_poa the POA. + */ + public gnuServantObject(String[] a_repository_ids, byte[] an_id, + gnuPOA a_poa, ORB_1_4 an_orb + ) + { + repository_ids = a_repository_ids; + Id = an_id; + manager = a_poa.the_POAManager(); + poa = a_poa; + orb = an_orb; + + noRetain = poa.applies(ServantRetentionPolicyValue.NON_RETAIN); + } + + /** + * Get the IOR as it would be for this object. + */ + public IOR getIor() + { + return orb.getLocalIor(this); + } + + /** + * Create a servant object, associated with the passed servant. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler}. + */ + public gnuServantObject(Servant a_servant, byte[] an_id, ORB_1_4 an_orb, + gnuPOA a_poa + ) + { + Id = an_id; + setServant(a_servant); + poa = a_poa; + if (poa != null) + { + manager = poa.the_POAManager(); + } + else + { + manager = null; + } + repository_ids = null; + orb = an_orb; + + noRetain = poa != null && poa.applies(ServantRetentionPolicyValue.NON_RETAIN); + } + + /** + * Set a servant, if it has not been previously set. + * + * @param a_servant a servant to set, can be null to indicate the necessity + * for the subsequent activation. + * + * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler} or + * {@link DynamicImplementation} and also not null. + */ + public void setServant(Servant a_servant) + { + if (a_servant != null && + !(a_servant instanceof InvokeHandler) && + !(a_servant instanceof DynamicImplementation) + ) + { + throw new BAD_PARAM("Must be either InvokeHandler or " + + "DynamicImplementation, but is " + a_servant + ); + } + servant = a_servant; + } + + /** + * Returns the associated servant. + */ + public Servant getServant() + { + return servant; + } + + /** + * Return the associated invocation handler. + */ + public InvokeHandler getHandler(String operation, CookieHolder cookie, + boolean forwarding_allowed + ) throws gnuForwardRequest + { + if (servant != null && !noRetain) + { + return servantToHandler(servant); + } + else + { + // Use servant locator to locate the servant. + if (poa.servant_locator != null) + { + try + { + servant = + poa.servant_locator.preinvoke(Id, poa, operation, cookie); + return servantToHandler(servant); + } + catch (org.omg.PortableServer.ForwardRequest forw_ex) + { + if (forwarding_allowed) + { + throw new gnuForwardRequest(forw_ex.forward_reference); + } + else + { + servant = + ForwardedServant.create(forw_ex.forward_reference); + return servantToHandler(servant); + } + } + } + else + // Use servant activator to locate the servant. + if (poa.applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) && + poa.applies(ServantRetentionPolicyValue.RETAIN) + ) + { + try + { + poa.activate_object_with_id(Id, servant, forwarding_allowed); + servant = poa.id_to_servant(Id); + return servantToHandler(servant); + } + catch (gnuForwardRequest forwarded) + { + throw forwarded; + } + catch (Exception ex) + { + BAD_OPERATION bad = + new BAD_OPERATION("Unable to activate", Minor.Activation, + CompletionStatus.COMPLETED_NO + ); + bad.initCause(ex); + throw bad; + } + } + else if (poa.default_servant != null) + { + servant = poa.default_servant; + return servantToHandler(servant); + } + + // No servant and no servant manager - throw exception. + else + { + throw new BAD_OPERATION("Unable to activate", Minor.Activation, + CompletionStatus.COMPLETED_NO + ); + } + } + } + + /** + * Convert the servant to invocation handler. + */ + public InvokeHandler servantToHandler(Servant a_servant) + { + if (a_servant instanceof InvokeHandler) + { + return (InvokeHandler) a_servant; + } + else if (a_servant instanceof DynamicImplementation) + { + return new DynamicImpHandler((DynamicImplementation) a_servant); + } + else + { + throw new BAD_OPERATION(a_servant + + " must be either InvokeHandler or " + "POA DynamicImplementation" + ); + } + } + + /** + * Create a servant object, associated with the passed servant. Requests the + * object id from the servant. Depending on the policies of the servants POA, + * the calls are eithe not synchronized or synchronized on POA or ORB. + * + * @param a_servant a servant, serving this object. + * @param an_id an Object Id for this object. + */ + public gnuServantObject(Servant a_servant, gnuPOA a_poa) + { + this(a_servant, a_servant._object_id(), (ORB_1_4) a_servant._orb(), a_poa); + } + + /** + * Delegates call to servant, passing the poa and Id. + */ + public String[] _ids() + { + if (repository_ids == null) + { + return getServant()._all_interfaces(poa, Id); + } + else + { + return repository_ids; + } + } + + /** + * Gets a string representation. + */ + public String toString() + { + CPStringBuilder b = new CPStringBuilder("Servant object ("); + for (int i = 0; i < Id.length; i++) + { + b.append(Integer.toHexString(Id [ i ] & 0xFF)); + b.append(' '); + } + b.append(')'); + return b.toString(); + } + + /** + * Always returns true. + */ + public boolean _is_local() + { + return true; + } + + /** + * Check if this object could be named by the given repository id. + * + * @param idl_id the repository id to check. + * + * @return true if it is one of the possible repository ids of this object. + */ + public boolean _is_a(String idl_id) + { + String[] maybe = _ids(); + for (int i = 0; i < maybe.length; i++) + { + if (maybe [ i ].equals(idl_id)) + { + return true; + } + } + return false; + } + + /** + * Get an ORB, associated with the servant of this object. + * + * @return + */ + public ORB _orb() + { + return getServant()._orb(); + } + + /** + * Handle the invocation (delegates to servant). + * + * @throws TRANSIENT minor 0x535503e9 if the POA is in discarding mode. + * @throws OBJ_ADAPTER minor 0x535503ea if the POA is inactivated. + * @throws OBJECT_NOT_EXISTS minor 0x535503ec if this object is inactivated. + * + * @specnote see {@link POAManagerOperations} for specnotes about the minor + * codes. + */ + public OutputStream _invoke(String method, InputStream input, + ResponseHandler r_handler + ) throws SystemException + { + boolean intercept = false; + ServerRequestInterceptorOperations interceptor = null; + gnuServerRequestInfo info = null; + ResponseHandlerImpl i_handler = null; + + try + { + if (orb.iServer != null && + r_handler instanceof ResponseHandlerImpl + ) + { + interceptor = orb.iServer; + + i_handler = (ResponseHandlerImpl) r_handler; + + info = + new gnuServerRequestInfo(this, i_handler.request_header, + i_handler.reply_header + ); + intercept = true; + + interceptor.receive_request_service_contexts(info); + } + + try + { + CookieHolder cookie = null; + AOM.Obj self = poa.aom.get(Id); + + if (poa.servant_locator != null) + { + // If the servant locator is in use, it is always responsible + // for providing the servant. + self.servant = servant = null; + cookie = new CookieHolder(); + } + else if (self != null && self.isDeactiveted()) + { + if (poa.applies( + ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION + ) && + poa.servant_activator != null + ) + { + // Reset the servant, forcing the subsequent activation. + servant = null; + } + else + { + throw new OBJECT_NOT_EXIST("Object deactivated", + 0x535503ec, CompletionStatus.COMPLETED_NO + ); + } + } + + InvokeHandler handler = getHandler(method, cookie, true); + + Delegate d = null; + + try + { + d = servant._get_delegate(); + orb.currents.put(Thread.currentThread(), this); + } + catch (Exception ex) + { + // In some cases exception is thrown if the delegate is not set. + } + if (d instanceof ServantDelegateImpl) + { + // If the delegate is already set, check maybe we can + // reuse the existing instance. + if (((ServantDelegateImpl) d).object != this) + { + servant._set_delegate(new ServantDelegateImpl(servant, poa, Id)); + } + } + else + { + servant._set_delegate(new ServantDelegateImpl(servant, poa, Id)); + } + + try + { + switch (manager.get_state().value()) + { + case State._ACTIVE : + + OutputStream rt; + try + { + if (intercept) + { + interceptor.receive_request(info); + } + + rt = handler._invoke(method, input, r_handler); + + if (intercept) + { + // Handler is casted into i_handler. + if (i_handler.isExceptionReply()) + { + info.m_reply_header.reply_status = + ReplyHeader.USER_EXCEPTION; + + // Make Any, holding the user exception. + Any a = orb.create_any(); + OutputStream buf = i_handler.getBuffer(); + InputStream in = buf.create_input_stream(); + String uex_idl = "unknown"; + try + { + in.mark(Integer.MAX_VALUE); + uex_idl = in.read_string(); + in.reset(); + } + catch (IOException e) + { + throw new Unexpected(e); + } + + try + { + UserException exception = + ObjectCreator.readUserException(uex_idl, + in + ); + + ObjectCreator.insertWithHelper(a, + exception + ); + } + catch (Exception e) + { + // Failed due any reason, insert without + // helper. + a.insert_Streamable(new StreamHolder( + buf.create_input_stream() + ) + ); + + RecordTypeCode r = + new RecordTypeCode(TCKind.tk_except); + r.setId(uex_idl); + r.setName(ObjectCreator.getDefaultName( + uex_idl + ) + ); + } + + info.m_usr_exception = a; + interceptor.send_exception(info); + } + else + { + info.m_reply_header.reply_status = + ReplyHeader.NO_EXCEPTION; + interceptor.send_reply(info); + } + } + } + catch (SystemException sys_ex) + { + if (intercept) + { + info.m_reply_header.reply_status = + ReplyHeader.SYSTEM_EXCEPTION; + info.m_sys_exception = sys_ex; + interceptor.send_exception(info); + } + throw sys_ex; + } + + return rt; + + case State._HOLDING : + + // The holding mode is implemented + // relying on the holding capabilites of the network + // support (if any). + // TODO FIXME in more recent CORBA applications, the + // client + // ORB can free the connection and wait for a server side + // notification about the completed request. Implement + // this + // as soon as JDK specification would allow bidirectional + // policy. + int sleep = 5; + int max = 500; + + // Wait till the state will be switched into some other + // mode. + while (manager.get_state().value() == State._HOLDING) + { + try + { + Thread.sleep(sleep); + if (sleep < max) + { + sleep = max; + } + } + catch (InterruptedException ex) + { + } + } + + // Handle another mode. + return _invoke(method, input, r_handler); + + case State._DISCARDING : + throw new TRANSIENT("Discarding mode", 0x535503e9, + CompletionStatus.COMPLETED_NO + ); + + case State._INACTIVE : + throw new OBJ_ADAPTER("POA deactivated", 0x535503ea, + CompletionStatus.COMPLETED_NO + ); + + default : + throw new InternalError(); // No more states. + } + } + finally + { + if (poa.servant_locator != null) + { + poa.servant_locator.postinvoke(Id, poa, method, + cookie.value, servant + ); + } + } + } + finally + { + orb.currents.remove(Thread.currentThread()); + if (noRetain) + servant = null; + } + } + catch (ForwardRequest fex) + { + // May be thrown by interceptor. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward = info.m_forward_reference; + } + } + } + throw new gnuForwardRequest(fex.forward); + } + catch (gnuForwardRequest fex) + { + // May be thrown during activation. + if (intercept) + { + Forwarding: + while (true) + { + info.m_reply_header.reply_status = + ReplyHeader.LOCATION_FORWARD; + info.m_forward_reference = fex.forward_reference; + try + { + interceptor.send_other(info); + break Forwarding; + } + catch (ForwardRequest fex2) + { + info.m_forward_reference = fex2.forward; + fex.forward_reference = (ObjectImpl) fex2.forward; + } + } + } + throw fex; + } + } + + /** + * Compare with another object for equality, comparing the object keys. + */ + public boolean equals(java.lang.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject o = (gnuServantObject) other; + + return Arrays.equals(o.Id, Id); + } + else + { + return false; + } + } + + /** + * Get the hash code, based on the object key. + */ + public int hashCode() + { + long s = 0; + int v = 1; + for (int i = 0; i < Id.length; i++) + { + s += Id [ i ] * v; + if (s > Integer.MAX_VALUE) + { + s = s % Integer.MAX_VALUE; + v = 1; + } + v = v * 8; + } + return (int) (s % Integer.MAX_VALUE); + } + + /** + * Get the object id. + */ + public byte[] get_object_id() + { + return Id; + } + + /** + * Get POA. + */ + public POA get_POA() + { + return poa; + } + + /** + * Returns without action. + */ + public void _release() + { + } + + /** + * Returns without action. + */ + public void _releaseReply(InputStream stream) + { + } + + /** + * Checks if this object is equivalent to another instance. These objects are + * assumed equal if they are connected to the same orb and poa under the same + * Id, regardless of they delegates. + * + * @param other instance to check. + * @return + */ + public boolean _is_equivalent(org.omg.CORBA.Object other) + { + if (other instanceof gnuServantObject) + { + gnuServantObject g = (gnuServantObject) other; + return orb == g.orb && poa == g.poa && Arrays.equals(Id, g.Id); + } + else if (other instanceof IorObject) + { + IorObject ir = ((IorObject) other); + try + { + IorDelegate ird = (IorDelegate) ir._get_delegate(); + byte[] ior_id = poa.idFormIor(ird.getIor().key); + if (ior_id != null && Arrays.equals(ior_id, Id)) + { + return true; + } + else + { + return false; + } + } + catch (Exception ex) + { + // Non - typical delegate or very specific subclass of + // IOR_constructed_object. + return super._is_equivalent(other); + } + } + return super._is_equivalent(other); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java new file mode 100644 index 000000000..95958d299 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuServantRetentionPolicy.java @@ -0,0 +1,80 @@ +/* gnuServantRetentionPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.SERVANT_RETENTION_POLICY_ID; +import org.omg.PortableServer.ServantRetentionPolicy; +import org.omg.PortableServer.ServantRetentionPolicyValue; + +/** + * The implementation of the servant retention policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuServantRetentionPolicy + extends _PolicyImplBase + implements ServantRetentionPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuServantRetentionPolicy(ServantRetentionPolicyValue v) + { + super(SERVANT_RETENTION_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ServantRetentionPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ServantRetentionPolicyValue value() + { + return (ServantRetentionPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java new file mode 100644 index 000000000..e7dac0f6a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Poa/gnuThreadPolicy.java @@ -0,0 +1,80 @@ +/* gnuThreadPolicy.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.Poa; + +import gnu.CORBA._PolicyImplBase; + +import org.omg.PortableServer.THREAD_POLICY_ID; +import org.omg.PortableServer.ThreadPolicy; +import org.omg.PortableServer.ThreadPolicyValue; + +/** + * The implementation of the thread policy. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuThreadPolicy + extends _PolicyImplBase + implements ThreadPolicy, AccessiblePolicy +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1L; + + /** + * Create the policy. + * + * @param v a value for the policy. + */ + public gnuThreadPolicy(ThreadPolicyValue v) + { + super(THREAD_POLICY_ID.value, v, v.value(), + "IDL:org.omg/PortableServer/ThreadPolicy:1.0" + ); + } + + /** + * Get the value for the policy that was passed in a constructor. + */ + public ThreadPolicyValue value() + { + return (ThreadPolicyValue) getValue(); + } +} diff --git a/libjava/classpath/gnu/CORBA/RawReply.java b/libjava/classpath/gnu/CORBA/RawReply.java new file mode 100644 index 000000000..a36f4b4b2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/RawReply.java @@ -0,0 +1,95 @@ +/* RawReply.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.GIOP.MessageHeader; + +import org.omg.CORBA.ORB; + +/** + * The remote object reply in the binary form, holding + * the message header and the following binary data. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +class RawReply +{ + /** + * The message header. + */ + final MessageHeader header; + + /** + * The associated orb. + */ + final ORB orb; + + /** + * The message data. + */ + final byte[] data; + + /** + * Create the binary reply. + * + * @param an_header the message header + * @param a_data the message data. + */ + RawReply(ORB an_orb, MessageHeader an_header, byte[] a_data) + { + orb = an_orb; + header = an_header; + data = a_data; + } + + /** + * Get the CDR input stream with the correctly set alignment. + * + * @return the CDR stream to read the message data. + */ + BufferredCdrInput getStream() + { + BufferredCdrInput in = new BufferredCdrInput(data); + in.setOffset(header.getHeaderSize()); + in.setVersion(header.version); + in.setOrb(orb); + in.setBigEndian(header.isBigEndian()); + return in; + } +} diff --git a/libjava/classpath/gnu/CORBA/ResponseHandlerImpl.java b/libjava/classpath/gnu/CORBA/ResponseHandlerImpl.java new file mode 100644 index 000000000..4d509cc52 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ResponseHandlerImpl.java @@ -0,0 +1,189 @@ +/* ResponseHandlerImpl.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.GIOP.MessageHeader; +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.GIOP.RequestHeader; +import gnu.CORBA.GIOP.CodeSetServiceContext; + +import org.omg.CORBA.ORB; +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. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ResponseHandlerImpl + implements ResponseHandler +{ + /** + * The message header. This field is used to compute the size and alignments. + * It is, however, never directly written to the buffer stream. + */ + public final MessageHeader message_header; + + /** + * The associated orb. + */ + public final ORB orb; + + /** + * The reply header. + */ + public final ReplyHeader reply_header; + + /** + * The request header. + */ + public final RequestHeader request_header; + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise. + */ + private boolean exceptionReply; + + /** + * The buffer to write into. + */ + private BufferedCdrOutput 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. + * + * @param m_header a message header. + * @param r_header a reply header. + */ + ResponseHandlerImpl(ORB an_orb, MessageHeader m_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. + * + * @return the stream to write exception details into. + */ + public OutputStream createExceptionReply() + { + exceptionReply = true; + prepareStream(); + return buffer; + } + + /** + * Get an output stream for writing a regular reply (not an exception). + * + * Before returning the stream, the handler automatically writes the regular + * reply header, but not the message header. + * + * @return the output stream for writing a regular reply. + */ + public OutputStream createReply() + { + exceptionReply = false; + prepareStream(); + reply_header.reply_status = ReplyHeader.NO_EXCEPTION; + return buffer; + } + + /** + * Get the buffer, normally containing the written reply. The reply includes + * the reply header (or the exception header) but does not include the message + * header. + * + * The stream buffer can also be empty if no data have been written into + * streams, returned by {@link #createReply()} or + * {@link #createExceptionReply()}. + * + * @return the CDR output stream, containing the written output. + */ + public BufferedCdrOutput getBuffer() + { + return buffer; + } + + /** + * True if the stream was obtained by invoking {@link #createExceptionReply()}, + * false otherwise (usually no-exception reply). + */ + public boolean isExceptionReply() + { + return exceptionReply; + } + + /** + * Compute the header offset, set the correct version number and codeset. + */ + private void prepareStream() + { + buffer = new BufferedCdrOutput(); + buffer.setOrb(orb); + buffer.setVersion(message_header.version); + buffer.setCodeSet(CodeSetServiceContext.find(reply_header.service_context)); + + // 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()); + + // Get the position after the reply header would be written. + reply_header.write(buffer); + + int new_offset = message_header.getHeaderSize() + buffer.buffer.size(); + + buffer.buffer.reset(); + buffer.setOffset(new_offset); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/SafeForDirectCalls.java b/libjava/classpath/gnu/CORBA/SafeForDirectCalls.java new file mode 100644 index 000000000..f3efb6677 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/SafeForDirectCalls.java @@ -0,0 +1,50 @@ +/* SafeForDirectCalls.java -- FIXME: briefly describe file purpose + Copyright (C) 2006 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; + +/** + * This interface marks that the object does not modify the passed read only + * parameters and hence, if it is local, it is safe to call the methods + * directly, without cloning such parameters. Otherwise such parameters should + * be cloned. + */ +public interface SafeForDirectCalls +{ + +} diff --git a/libjava/classpath/gnu/CORBA/ServiceDetailHolder.java b/libjava/classpath/gnu/CORBA/ServiceDetailHolder.java new file mode 100644 index 000000000..e8786374a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ServiceDetailHolder.java @@ -0,0 +1,91 @@ +/* ServiceDetailHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.ServiceDetail; +import org.omg.CORBA.ServiceDetailHelper; + + +/** + * The service detail holder. This class is not included in the original + * API specification, so we place it outside the org.omg namespace. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ServiceDetailHolder + implements org.omg.CORBA.portable.Streamable +{ + /** + * The stored value. + */ + public ServiceDetail value; + + /** + * Create the initialised instance. + * @param initialValue + */ + public ServiceDetailHolder(ServiceDetail initialValue) + { + value = initialValue; + } + + /** + * Read from the CDR stream. + */ + public void _read(org.omg.CORBA.portable.InputStream in) + { + value = ServiceDetailHelper.read(in); + } + + /** + * Get the typecode. + */ + public org.omg.CORBA.TypeCode _type() + { + return ServiceDetailHelper.type(); + } + + /** + * Write into the CDR stream. + */ + public void _write(org.omg.CORBA.portable.OutputStream out) + { + ServiceDetailHelper.write(out, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java new file mode 100644 index 000000000..0c21f6f45 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/ServiceRequestAdapter.java @@ -0,0 +1,167 @@ +/* ServiceRequestConverter.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferedCdrOutput; + +import org.omg.CORBA.ARG_IN; +import org.omg.CORBA.ARG_OUT; +import org.omg.CORBA.Any; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ServerRequest; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; +import org.omg.CORBA.portable.Streamable; + +/** + * 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) + */ +public class ServiceRequestAdapter + implements ResponseHandler +{ + /** + * A buffer for writing the response. + */ + BufferedCdrOutput reply = new BufferedCdrOutput(); + + /** + * If set to true, an exception has been thrown during the invocation. + */ + boolean isException; + + public OutputStream createExceptionReply() + { + isException = true; + return reply; + } + + public OutputStream createReply() + { + isException = false; + return reply; + } + + /** + * 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. + * 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 + ) + { + try + { + int IN = ARG_IN.value; + int OUT = ARG_OUT.value; + + // Write all arguments to the buffer output stream. + BufferedCdrOutput buffer = new BufferedCdrOutput(); + gnuNVList args = new gnuNVList(); + request.arguments(args); + + for (int i = 0; i < args.count(); i++) + { + if ((args.item(i).flags() & IN) != 0) + { + args.item(i).value().write_value(buffer); + } + } + + ServiceRequestAdapter h = new ServiceRequestAdapter(); + + target._invoke(request.operation(), buffer.create_input_stream(), h); + + InputStream in = h.reply.create_input_stream(); + + if (h.isException) + { + // Write the exception information + gnuAny exc = new gnuAny(); + GeneralHolder uku = new GeneralHolder(h.reply); + exc.insert_Streamable(uku); + request.set_exception(exc); + } + else + { + if (result != null) + { + // 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 StreamHolder(in)); + } + + // Unpack the arguments + for (int i = 0; i < args.count(); i++) + { + if ((args.item(i).flags() & OUT) != 0) + { + Any a = args.item(i).value(); + a.read_value(in, a.type()); + } + } + } + } + catch (Bounds ex) + { + throw new InternalError(); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/SetOverrideTypeHolder.java b/libjava/classpath/gnu/CORBA/SetOverrideTypeHolder.java new file mode 100644 index 000000000..478ec3f70 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/SetOverrideTypeHolder.java @@ -0,0 +1,90 @@ +/* SetOverrideTypeHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.SetOverrideType; +import org.omg.CORBA.SetOverrideTypeHelper; + +/** + * The holder for SetOverrideType. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class SetOverrideTypeHolder + implements org.omg.CORBA.portable.Streamable +{ + /** + * The stored SetOverrideType value. + */ + public SetOverrideType value; + + /** + * Create the initialised instance. + * + * @param initialValue the initial value. + */ + public SetOverrideTypeHolder(SetOverrideType initialValue) + { + value = initialValue; + } + + /** + * Fill in the {@link value} by data from the CDR stream. + */ + public void _read(org.omg.CORBA.portable.InputStream in) + { + value = SetOverrideTypeHelper.read(in); + } + + /** + * Get the typecode of the SetOverrideType. + */ + public org.omg.CORBA.TypeCode _type() + { + return SetOverrideTypeHelper.type(); + } + + /** + * Write the stored value into the CDR stream. + */ + public void _write(org.omg.CORBA.portable.OutputStream out) + { + SetOverrideTypeHelper.write(out, value); + } +} diff --git a/libjava/classpath/gnu/CORBA/SimpleDelegate.java b/libjava/classpath/gnu/CORBA/SimpleDelegate.java new file mode 100644 index 000000000..d1c6ab407 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/SimpleDelegate.java @@ -0,0 +1,318 @@ +/* Local_delegate.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; +import org.omg.CORBA.ORB; +import org.omg.CORBA.Request; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * The delegate, implementing the basic functionality only. This delegate + * is set in {@link ORG.connect(org.omg.CORBA.Object)} if ORB + * determines that the object is an instance of the + * {@link org.omg.CORBA.portable.ObjectImpl} and no other delegate is set. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class SimpleDelegate + extends Delegate + implements IorProvider +{ + /** + * The orb. + */ + protected final ORB orb; + + /** + * The ior. + */ + protected IOR ior; + + public SimpleDelegate(ORB an_orb, IOR an_ior) + { + orb = an_orb; + ior = an_ior; + } + + /** + * Set the IOR of this object. The IOR must be newly set if + * the server reports that the object has permanently moved to a new + * location. + * + * @param an_ior the new IOR. + */ + public void setIor(IOR an_ior) + { + this.ior = an_ior; + } + + /** + * Get the IOR of this object. + */ + public IOR getIor() + { + return ior; + } + + /** + * Create the request for the local call + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String operation, NVList parameters, + NamedValue returns + ) + { + if (orb instanceof OrbFunctional) + { + ((OrbFunctional) orb).ensureRunning(); + } + gnuRequest g = new gnuRequest(); + g.setORB(orb); + g.setOperation(operation); + g.setIor(ior); + g.m_target = target; + g.ctx(context); + g.set_args(parameters); + if (returns != null) + g.set_result(returns); + return g; + } + + /** + * Create the request for the local call. + */ + public Request create_request(org.omg.CORBA.Object target, Context context, + String operation, NVList parameters, + NamedValue returns, ExceptionList exceptions, + ContextList ctx_list + ) + { + if (orb instanceof OrbFunctional) + { + ((OrbFunctional) orb).ensureRunning(); + } + gnuRequest g = new gnuRequest(); + g.setORB(orb); + g.setOperation(operation); + g.setIor(ior); + g.m_target = target; + g.ctx(context); + g.set_args(parameters); + g.set_exceptions(exceptions); + g.set_context_list(ctx_list); + if (returns != null) + g.set_result(returns); + return g; + } + + /** + * Not implemented. + * + * @throws NO_IMPLEMENT, always. + */ + public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object target) + { + throw new NO_IMPLEMENT(); + } + + /** + * Performs direct comparison ('=='). + */ + public boolean equals(org.omg.CORBA.Object self, org.omg.CORBA.Object other) + { + return self == other; + } + + /** + * Not implemented. + * + * @throws NO_IMPLEMENT, always. + */ + public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object target) + { + throw new NO_IMPLEMENT(); + } + + /** + * Return the hashcode (0 <= hashcode < maximum). + */ + public int hash(org.omg.CORBA.Object target, int maximum) + { + return target == null ? 0 : target.hashCode() % maximum; + } + + /** + * Delegates functionality to java.lang.Object.hashCode(); + */ + public int hashCode(org.omg.CORBA.Object target) + { + return target == null ? 0 : target.hashCode(); + } + + /** + * Check if this object can be referenced by the given repository id. + * + * @param target the CORBA object, must be an instance of + * {@link org.omg.CORBA.portable.ObjectImpl}. + * + * @param repositoryIdentifer the repository id. + * + * @return true if the passed parameter is a repository id of this + * CORBA object. + */ + public boolean is_a(org.omg.CORBA.Object target, String repositoryIdentifer) + { + if (!(target instanceof ObjectImpl)) + throw new NO_IMPLEMENT("Supported only for org.omg.CORBA.portable.ObjectImpl"); + + ObjectImpl imp = (ObjectImpl) target; + String[] ids = imp._ids(); + + for (int i = 0; i < ids.length; i++) + { + if (ids [ i ].equals(repositoryIdentifer)) + return true; + } + return false; + } + + /** + * Returns true if the objects are the same or 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) + { + 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; + } + else + { + // We compere the IOR's in this case. + if (a instanceof IorProvider && b instanceof IorProvider) + { + IOR ia = ((IorProvider) a).getIor(); + IOR ib = ((IorProvider) b).getIor(); + + if (ia != null && ib != null) + return (ia.equals(ib)); + else + return ia == ib; + } + } + if (a != null && b != null) + { + return a.equals(b); + } + } + catch (Exception ex) + { + // Unable to get one of the delegates. + return false; + } + } + return false; + } + + /** + * Returns true by default. + */ + public boolean is_local(org.omg.CORBA.Object self) + { + return true; + } + + /** + * Returns true if the target is null. + */ + public boolean non_existent(org.omg.CORBA.Object target) + { + return target == null; + } + + /** + * Returns the ORB, passed in constructor, + * regardless of the argument. This class requires a single instance + * per each object. + */ + public ORB orb(org.omg.CORBA.Object target) + { + return orb; + } + + /** + * Returns without action. + */ + public void release(org.omg.CORBA.Object target) + { + } + + /** + * This method assumes that the target is local and connected to the ORB. + */ + public Request request(org.omg.CORBA.Object target, String operation) + { + if (orb instanceof OrbFunctional) + { + ((OrbFunctional) orb).ensureRunning(); + } + gnuRequest g = new gnuRequest(); + g.setORB(orb); + g.setOperation(operation); + g.setIor(ior); + g.m_target = target; + return g; + } +} diff --git a/libjava/classpath/gnu/CORBA/SocketRepository.java b/libjava/classpath/gnu/CORBA/SocketRepository.java new file mode 100644 index 000000000..71e073adb --- /dev/null +++ b/libjava/classpath/gnu/CORBA/SocketRepository.java @@ -0,0 +1,148 @@ +/* SocketRepository.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.net.Socket; +import java.net.SocketException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +/** + * This class caches the opened sockets that are reused during the + * frequent calls. Otherwise, some CORBA applications may spend + * up to 90 % of the working time just for closing and opening the sockets. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class SocketRepository +{ + /** + * The socket map. + */ + private static HashMap sockets = new HashMap(); + + /** + * Put a socket. This method also discards all not reusable sockets from + * the map. + * + * @param key as socket key. + * + * @param s a socket. + */ + public static void put_socket(Object key, Socket s) + { + synchronized (sockets) + { + sockets.put(key, s); + gc(); + } + } + + /** + * Removes all non reusable sockets. As it is private, + * we know we call from the synchronized code already. + */ + private static void gc() + { + Iterator iter = sockets.entrySet().iterator(); + + Map.Entry e; + Socket sx; + + while (iter.hasNext()) + { + e = (Map.Entry) iter.next(); + sx = (Socket) e.getValue(); + + if (not_reusable(sx)) + iter.remove(); + } + } + + /** + * Return true if the socket is no longer reusable. + */ + static boolean not_reusable(Socket s) + { + return (s.isClosed() || !s.isBound() || !s.isConnected() || + s.isInputShutdown() || s.isOutputShutdown()); + } + + /** + * Get a socket. + * + * @param key a socket key. + * + * @return an opened socket for reuse, null if no such available or it is + * closed, its input or output has been shutown or otherwise the socket is not + * reuseable. + */ + public static Socket get_socket(Object key) + { + synchronized (sockets) + { + Socket s = (Socket) sockets.get(key); + if (s == null) + return null; + + // Ensure that the socket is fully reusable. + else if (not_reusable(s)) + { + sockets.remove(key); + return null; + } + else + { + try + { + // Set one minute time out that will be changed later. + s.setSoTimeout(60 * 1000); + } + catch (SocketException e) + { + s = null; + } + + sockets.remove(key); + return s; + } + } + } +} diff --git a/libjava/classpath/gnu/CORBA/StreamBasedRequest.java b/libjava/classpath/gnu/CORBA/StreamBasedRequest.java new file mode 100644 index 000000000..66796d653 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/StreamBasedRequest.java @@ -0,0 +1,60 @@ +/* gnuStreamRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferedCdrOutput; + +/** + * A stream, additionally holding the gnu request. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class StreamBasedRequest + extends BufferedCdrOutput +{ + /** + * The enclosed request. + */ + public gnuRequest request; + + /** + * True if the response is expected. + */ + public boolean response_expected = true; +} diff --git a/libjava/classpath/gnu/CORBA/StreamHolder.java b/libjava/classpath/gnu/CORBA/StreamHolder.java new file mode 100644 index 000000000..992b4af21 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/StreamHolder.java @@ -0,0 +1,123 @@ +/* StreamHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +package gnu.CORBA; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +import java.io.IOException; + +/** + * A holder that stores the input stream, from that the holder data + * can be read. There is no way to write the data into this holder. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class StreamHolder + implements Streamable +{ + /** + * The stream, holding the data for this holder. + */ + protected final InputStream stream; + + /** + * Create a holder that will read from the given stream. + * + * @param a_stream a stream. + */ + public StreamHolder(InputStream a_stream) + { + stream = a_stream; + } + + /** + * This method is not in use, should never be called. + */ + public TypeCode _type() + { + throw new NO_IMPLEMENT(); + } + + /** + * Writes the data from the stored stream into the provided + * output stream till the end of the input stream is reached. + * + * @throws MARSHAL if the IOException is thrown during operation. + */ + public void _write(OutputStream output) + { + try + { + int d = stream.read(); + + while (d >= 0) + { + output.write(d); + d = stream.read(); + } + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL(); + m.initCause(ex); + m.minor = Minor.CDR; + throw m; + } + } + + /** + * This method is not in use, should never be called. + */ + public void _read(InputStream input) + { + throw new NO_IMPLEMENT(); + } + + /** + * Get the input stream that has been passed in constructor. + */ + InputStream getInputStream() + { + return stream; + } +} diff --git a/libjava/classpath/gnu/CORBA/StubLocator.java b/libjava/classpath/gnu/CORBA/StubLocator.java new file mode 100644 index 000000000..d9e5ee471 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/StubLocator.java @@ -0,0 +1,110 @@ +/* StubLocator.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.ORB; +import org.omg.CORBA.portable.ObjectImpl; + +/** + * Finds a stub class like "_HelloStub" that can be instantiated + * from IOR reference. The returned object can be casted to the + * used type like "Hello" without using the helper .narrow method, + * and the object is not unnsecessarily re - instantiated if + * the .narrow method is used anyway. If no stub, matching the naming + * conventions, is available, the returned stub replacement can still be used + * to get the valid request, add parameter and invoke the method by name. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class StubLocator +{ + /** + * Search for the possibly available default stub. + * + * @param orb the current ORB. It is not required to find the binding + * classes, but is needed to instantiate the default implementation + * if no binding classes are found. + * + * @param ior the IOR, possibly containing the information about the + * correct implementation class. + */ + public static ObjectImpl search(ORB orb, IOR ior) + { + try + { + int a = ior.Id.indexOf(':'); + int b = ior.Id.lastIndexOf(':'); + + String s = ior.Id.substring(a + 1, b).replace('/', '.'); + + String path; + + b = s.lastIndexOf('.'); + if (b > 0) + path = s.substring(0, b + 1); + else + path = ""; + + String stub = "_" + s.substring(b + 1) + "Stub"; + + Class stubClass = ObjectCreator.forName(path + stub); + + return (ObjectImpl) stubClass.newInstance(); + } + catch (Exception failed) + { + // Various exceptions can be thrown if the Id cannot be parsed, + // the class is missing, cannot be instantiated or is not an + // instance of the ObjectImpl. + return createDefaultStub(orb, ior); + } + } + + /** + * Return the default stub for the case when the client binding classes + * are not locally available. The returned stub can still be used + * to get the valid request, add parameter and invoke the method by name. + * + * @return the default implementation. + */ + protected static ObjectImpl createDefaultStub(ORB orb, IOR ior) + { + return new IorObject(orb, ior); + } +} diff --git a/libjava/classpath/gnu/CORBA/TypeCodeHelper.java b/libjava/classpath/gnu/CORBA/TypeCodeHelper.java new file mode 100644 index 000000000..46831e8d2 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/TypeCodeHelper.java @@ -0,0 +1,304 @@ +/* TypeCodeHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.typecodes.FixedTypeCode; +import gnu.CORBA.typecodes.GeneralTypeCode; +import gnu.CORBA.typecodes.ArrayTypeCode; +import gnu.CORBA.typecodes.PrimitiveTypeCode; +import gnu.CORBA.typecodes.RecordTypeCode; +import gnu.CORBA.typecodes.StringTypeCode; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; + +/** + * Reads and writes the TypeCodes usind common data representation. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class TypeCodeHelper +{ + /** + * Read the CORBA {@link TypeCode}. First, the TypeCode kind + * is read as four byte long. Then, if needed, the additional + * parameters are loaded following CORBA specification. + * + * @param in a stream to read from. + */ + public static TypeCode read(org.omg.CORBA.portable.InputStream in) + throws BadKind, Bounds + { + TCKind kind = TCKind.from_int(in.read_long()); + TypeCode rt; + GeneralTypeCode g; + RecordTypeCode r; + RecordTypeCode.Field f; + StringTypeCode s; + int n; + + switch (kind.value()) + { + case TCKind._tk_sequence : + case TCKind._tk_array : + + ArrayTypeCode p = new ArrayTypeCode(kind); + p.setLength(in.read_long()); + rt = p; + break; + + case TCKind._tk_string : + case TCKind._tk_wstring : + s = new StringTypeCode(kind); + s.setLength(in.read_long()); + rt = s; + break; + + case TCKind._tk_fixed : + + FixedTypeCode fx = new FixedTypeCode(); + fx.setDigits(in.read_short()); + fx.setScale(in.read_short()); + rt = fx; + break; + + case TCKind._tk_objref : + case TCKind._tk_native : + case TCKind._tk_abstract_interface : + g = new GeneralTypeCode(kind); + g.setId(in.read_string()); + g.setName(in.read_string()); + rt = g; + break; + + case TCKind._tk_alias : + case TCKind._tk_value_box : + g = new GeneralTypeCode(kind); + g.setId(in.read_string()); + g.setName(in.read_string()); + g.setContentType(in.read_TypeCode()); + rt = g; + break; + + case TCKind._tk_struct : + case TCKind._tk_except : + r = new RecordTypeCode(kind); + r.setId(in.read_string()); + r.setName(in.read_string()); + + n = in.read_long(); + + for (int i = 0; i < n; i++) + { + f = r.field(); + f.name = in.read_string(); + f.type = in.read_TypeCode(); + } + rt = r; + break; + + case TCKind._tk_enum : + r = new RecordTypeCode(kind); + r.setId(in.read_string()); + r.setName(in.read_string()); + + n = in.read_long(); + + for (int i = 0; i < n; i++) + { + f = r.field(); + f.name = in.read_string(); + } + rt = r; + break; + + case TCKind._tk_union : + r = new RecordTypeCode(kind); + r.setId(in.read_string()); + r.setName(in.read_string()); + r.setDiscriminator_type(in.read_TypeCode()); + r.setDefaultIndex(in.read_long()); + + n = in.read_long(); + + for (int i = 0; i < n; i++) + { + f = r.field(); + f.label = in.read_any(); + f.name = in.read_string(); + f.type = in.read_TypeCode(); + } + rt = r; + + break; + + case TCKind._tk_value : + r = new RecordTypeCode(kind); + r.setId(in.read_string()); + r.setName(in.read_string()); + r.setTypeModifier(in.read_short()); + r.setConcreteBase_type(in.read_TypeCode()); + + n = in.read_long(); + + for (int i = 0; i < n; i++) + { + f = r.field(); + f.name = in.read_string(); + f.type = in.read_TypeCode(); + f.visibility = in.read_short(); + } + rt = r; + break; + + default : + rt = new PrimitiveTypeCode(kind); + } + return rt; + } + + /** + * Write the CORBA {@link TypeCode}. First, the TypeCode kind + * is written as four byte long. Then, if needed, the additional + * parameters are stored following CORBA specification. + * + * @param out a stream to write into. + * @param x a {@link TypeCode} to write. + */ + public static void write(org.omg.CORBA.portable.OutputStream out, TypeCode x) + throws BadKind, Bounds + { + out.write_long(x.kind().value()); + + switch (x.kind().value()) + { + case TCKind._tk_string : + case TCKind._tk_wstring : + out.write_long(x.length()); + break; + + case TCKind._tk_sequence : + case TCKind._tk_array : + write(out, x.content_type()); + out.write_long(x.length()); + break; + + case TCKind._tk_fixed : + out.write_short(x.fixed_digits()); + out.write_short(x.fixed_scale()); + break; + + case TCKind._tk_objref : + case TCKind._tk_native : + case TCKind._tk_abstract_interface : + out.write_string(x.id()); + out.write_string(x.name()); + break; + + case TCKind._tk_alias : + case TCKind._tk_value_box : + out.write_string(x.id()); + out.write_string(x.name()); + write(out, x.content_type()); + break; + + case TCKind._tk_struct : + case TCKind._tk_except : + out.write_string(x.id()); + out.write_string(x.name()); + + out.write_long(x.member_count()); + + for (int i = 0; i < x.member_count(); i++) + { + out.write_string(x.member_name(i)); + write(out, x.member_type(i)); + } + break; + + case TCKind._tk_enum : + out.write_string(x.id()); + out.write_string(x.name()); + + out.write_long(x.member_count()); + + for (int i = 0; i < x.member_count(); i++) + { + out.write_string(x.member_name(i)); + } + break; + + case TCKind._tk_union : + out.write_string(x.id()); + out.write_string(x.name()); + + write(out, x.discriminator_type()); + out.write_long(x.default_index()); + + out.write_long(x.member_count()); + + for (int i = 0; i < x.member_count(); i++) + { + out.write_any(x.member_label(i)); + out.write_string(x.member_name(i)); + write(out, x.member_type(i)); + } + break; + + case TCKind._tk_value : + out.write_string(x.id()); + out.write_string(x.name()); + out.write_short(x.type_modifier()); + write(out, x.concrete_base_type()); + + out.write_long(x.member_count()); + + for (int i = 0; i < x.member_count(); i++) + { + out.write_string(x.member_name(i)); + write(out, x.member_type(i)); + out.write_short(x.member_visibility(i)); + } + break; + + default :} + } +} diff --git a/libjava/classpath/gnu/CORBA/TypeKindNamer.java b/libjava/classpath/gnu/CORBA/TypeKindNamer.java new file mode 100644 index 000000000..464fd98a1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/TypeKindNamer.java @@ -0,0 +1,183 @@ +/* primitiveTypes.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.typecodes.PrimitiveTypeCode; +import gnu.CORBA.typecodes.RecordTypeCode; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * A conveniency method for naming the built-in types. + * This is used in error reporting that is part of the user interface. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class TypeKindNamer +{ + /** + * Names of the primitve types. + */ + protected static final String[] tk = + new String[] + { + "null", "void", "short", "long", "ushort", "ulong", "float", "double", + "boolean", "char", "octet", "any", "TypeCode", "Principal", "objref", + "struct", "union", "enum", "string", "sequence", "array", "alias", + "exception", "longlong", "ulonglong", "longdouble", "wchar", "wstring", + "fixed", "value", "value_box", "native", "abstract_interface" + }; + + /** + * Primitve TypeCodes. + */ + protected static final TypeCode[] primitveCodes = + new TypeCode[] + { + new PrimitiveTypeCode(TCKind.tk_null), + new PrimitiveTypeCode(TCKind.tk_void), + new PrimitiveTypeCode(TCKind.tk_short), + new PrimitiveTypeCode(TCKind.tk_long), + new PrimitiveTypeCode(TCKind.tk_ushort), + new PrimitiveTypeCode(TCKind.tk_ulong), + new PrimitiveTypeCode(TCKind.tk_float), + new PrimitiveTypeCode(TCKind.tk_double), + new PrimitiveTypeCode(TCKind.tk_boolean), + new PrimitiveTypeCode(TCKind.tk_char), + new PrimitiveTypeCode(TCKind.tk_octet), + new PrimitiveTypeCode(TCKind.tk_any), + new PrimitiveTypeCode(TCKind.tk_TypeCode), + new PrimitiveTypeCode(TCKind.tk_Principal), + new RecordTypeCode(TCKind.tk_objref), + new PrimitiveTypeCode(TCKind.tk_struct), + new PrimitiveTypeCode(TCKind.tk_union), + new PrimitiveTypeCode(TCKind.tk_enum), + new PrimitiveTypeCode(TCKind.tk_string), + new PrimitiveTypeCode(TCKind.tk_sequence), + new PrimitiveTypeCode(TCKind.tk_array), + new PrimitiveTypeCode(TCKind.tk_alias), + new PrimitiveTypeCode(TCKind.tk_except), + new PrimitiveTypeCode(TCKind.tk_longlong), + new PrimitiveTypeCode(TCKind.tk_ulonglong), + new PrimitiveTypeCode(TCKind.tk_longdouble), + new PrimitiveTypeCode(TCKind.tk_wchar), + new PrimitiveTypeCode(TCKind.tk_wstring), + new PrimitiveTypeCode(TCKind.tk_fixed), + new PrimitiveTypeCode(TCKind.tk_value), + new PrimitiveTypeCode(TCKind.tk_value_box), + new PrimitiveTypeCode(TCKind.tk_native), + 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. + * + * @return the primitve type code, corresponding the passed value. + * + * @throws BadKind if this is not a primitive type code. + */ + public static TypeCode getPrimitveTC(TCKind tc) + throws BadKind + { + try + { + return primitveCodes [ tc.value() ]; + } + catch (ArrayIndexOutOfBoundsException ex) + { + throw new BadKind(tc.value() + " is not a primitve type."); + } + } + + /** + * Get the string name of the passed primitive type. + * + * @param kind the kind of the primitive type the must be defined + * in {@link omg.org.CORBA.TCKind}. + * + * @return the short string name, used in error reporting, etc. + */ + public static String nameIt(int kind) + { + try + { + return tk [ kind ]; + } + catch (ArrayIndexOutOfBoundsException ex) + { + return "type of kind '" + kind + "'"; + } + } + + /** + * Get the string name of the passed primitive type. + * + * @param kind the kind of the primitive type the must be defined + * in {@link omg.org.CORBA.TCKind}. + * + * @return the short string name, used in error reporting, etc. + */ + public static String nameIt(TypeCode type) + { + try + { + if (type.kind().value() == TCKind._tk_array) + return "array of " + nameIt(type.content_type()); + else if (type.kind().value() == TCKind._tk_sequence) + return "sequence of " + nameIt(type.content_type()); + else + return nameIt(type.kind().value()); + } + catch (Exception ex) + { + return "type of kind '" + type.kind().value() + "'"; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/Unexpected.java b/libjava/classpath/gnu/CORBA/Unexpected.java new file mode 100644 index 000000000..89fb7e7b9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Unexpected.java @@ -0,0 +1,128 @@ +/* DNW.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + + +/** + * Contains the static method to throw an error in the case + * when the execution should never get into the current point. + * + * The error message contains the text, suggesting to check + * the user code first and then report a bug. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class Unexpected + extends InternalError +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The default message for the CORBA assertion error. + */ + public static final String SHARED_MESSAGE = + "CORBA assertion error. Please check your code. " + + "If you think it is Classpath problem, please report " + + "this bug providing as much information as possible."; + + /** + * Create an instance with explaining message and enclosing + * exception. + */ + public Unexpected(String msg, Exception why) + { + super(msg + ". " + SHARED_MESSAGE); + if (why != null) + initCause(why); + } + + /** + * Create an instance with enclosing exception. + */ + public Unexpected(Exception why) + { + super(SHARED_MESSAGE); + if (why != null) + initCause(why); + } + + /** + * Create an instance. + */ + public Unexpected() + { + super(SHARED_MESSAGE); + } + + /** + * Throws an error with the custom explaining message and + * the appended share message. + * + * @param msg the error message + * @param why the enclosing exception. + */ + public static void error(String msg, Exception why) + { + throw new Unexpected(msg, why); + } + + /** + * Throws an error with the shared explaining message. + * + * @param why the enclosing exception. + * @throws Error, always. + */ + public static void error(Exception why) + { + throw new Unexpected(why); + } + + /** + * Throws an error with the shared explaining message. + * + * @throws Error, always. + */ + public static void error() + { + throw new Unexpected(); + } +} diff --git a/libjava/classpath/gnu/CORBA/Version.java b/libjava/classpath/gnu/CORBA/Version.java new file mode 100644 index 000000000..20449a389 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/Version.java @@ -0,0 +1,222 @@ +/* Version.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.io.IOException; +import java.io.Serializable; + +import org.omg.CORBA.MARSHAL; + +/** + * A version number, represented by the major version number + * and the minor version number. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class Version + implements Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Major number (0..256, so the byte cannot be used). + */ + public final int major; + + /** + * Minor number. + */ + public final int minor; + + /** + * Create the version with the given version numbers. + * + * @param _major major number (0..255) + * @param _minor minor number (0..255) + */ + public Version(int _major, int _minor) + { + major = (byte) _major; + minor = (byte) _minor; + } + + /** + * Returns true if the versions are equal. + * @param other the other version to compare. + * + * @return true if the versions are equal + */ + public boolean equals(java.lang.Object other) + { + if (other == this) + { + return true; + } + if (!(other instanceof Version)) + { + return false; + } + + Version that = (Version) other; + return same(that); + } + + /** + * Get the hashcode, higher 8 bits being the major version and lower 8 bits + * the minor version. + */ + public int hashCode() + { + return major << 8 | minor; + } + + /** + * Read from the input stream, major number first. + * @param in a stream to read from. + */ + public static Version read_version(java.io.InputStream in) + { + try + { + int major = in.read() & 0xFF; + int minor = in.read() & 0xFF; + return new Version(major, minor); + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL("IOException while reading message header"); + m.initCause(ex); + m.minor = Minor.Header; + throw m; + } + } + + /** + * Returns true if the versions are the same. + * + * @param that the other version to compare. + * + * @return true if the versions are the same. + */ + public boolean same(Version that) + { + return major == that.major && minor == that.minor; + } + + /** + * Returns true if the given version is higher than + * or equals to the version, supplied as parameter + * in the form of two integers. + * + * @param a_major major number of the version to compare. + * @param a_minor minor number of the version to compare. + * + * @return true if this version is higher than or equals to + * the version v. + */ + public boolean since_inclusive(int a_major, int a_minor) + { + if (major > a_major) + return true; + else if (major < a_major) + return false; + else + + // Major numbers are equal. + return minor >= a_minor; + } + + /** + * Return the string representation, in the form + * major.minor. + */ + public String toString() + { + return major + "." + minor; + } + + /** + * Returs true if the given version is lower or equal to the + * version, specified by the provided minor and major version + * number. This means, the version, specified by these two numbers, + * should be supported by the current version. + * + * @param a_major a major version number. + * @param a_minor a minor version number. + * + * @return true if the current version should be supported by the + * version, specified by the two passed numbers. + */ + public boolean until_inclusive(int a_major, int a_minor) + { + if (major < a_major) + return true; + else if (major > a_major) + return false; + else + + // Major numbers are equal. + return minor <= a_minor; + } + + /** + * Write into the output stream, major number first. + * + * @param out a stream to write into. + */ + public void write(java.io.OutputStream out) + { + try + { + out.write(major & 0xFF); + out.write(minor & 0xFF); + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL("IOException while writing message header"); + m.minor = Minor.Header; + m.initCause(ex); + throw m; + } + } + +} diff --git a/libjava/classpath/gnu/CORBA/WCharHolder.java b/libjava/classpath/gnu/CORBA/WCharHolder.java new file mode 100644 index 000000000..3c6a87fbe --- /dev/null +++ b/libjava/classpath/gnu/CORBA/WCharHolder.java @@ -0,0 +1,128 @@ +/* WCharHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.typecodes.PrimitiveTypeCode; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +/** + * A holder for CORBA <code>char</code> that is mapped into + * java <code>char</code>. + * + * The holders have several application areas. The end user usually + * sees them implementing CORBA methods where the primitive type + * is passed by reference. While CORBA (or, for example, C) supports + * this, the java does not and a wrapper class is required. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public final class WCharHolder + implements Streamable +{ + /** + * The default type code for this holder. + */ + private static final TypeCode t_char = new PrimitiveTypeCode(TCKind.tk_wchar); + + /** + * The <code>char</code> (CORBA <code>wchar</code>) value, + * held by this WCharHolder. + */ + public char value; + + /** + * Constructs an instance of WCharHolder, + * initializing {@link #value} to <code>0 </code>. + */ + public WCharHolder() + { + } + + /** + * Constructs an instance of WCharHolder, + * initializing {@link #value} to the given <code>char</code>. + * + * @param initial_value a value that will be assigned to the + * {@link #value} field. + */ + public WCharHolder(char initial_value) + { + value = initial_value; + } + + /** + * Fill in the {@link value } field by reading the required data + * from the given stream. For <code>char</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.InputStream#read_wchar}. + * + * @param input the input stream to read from. + */ + public void _read(InputStream input) + { + value = input.read_wchar(); + } + + /** + * Returns the TypeCode, corresponding the CORBA type that is stored + * using this holder. + */ + public TypeCode _type() + { + return t_char; + } + + /** + * Write the {@link value } field to the given stream. + * For <code>char</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.OutputStream#write_wchar(char) }. + * + * @param output the output stream to write into. + */ + public void _write(OutputStream output) + { + output.write_wchar(value); + } +} diff --git a/libjava/classpath/gnu/CORBA/WStringHolder.java b/libjava/classpath/gnu/CORBA/WStringHolder.java new file mode 100644 index 000000000..7f18791df --- /dev/null +++ b/libjava/classpath/gnu/CORBA/WStringHolder.java @@ -0,0 +1,131 @@ +/* WStringHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.typecodes.StringTypeCode; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +/** + * A holder for CORBA <code>wstring</code> that is mapped into + * java <code>String</code>. This holder writes and reads differently + * from the StringHolder. + * + * The holders have several application areas. The end user usually + * sees them implementing CORBA methods where the primitive type + * is passed by reference. While CORBA (or, for example, C) supports + * this, the java does not and a wrapper class is required. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class WStringHolder + implements Streamable +{ + /** + * The default type code for this holder. + */ + private static final StringTypeCode t_string = + new StringTypeCode(TCKind.tk_wstring); + + /** + * The <code>String</code> (CORBA <code>string</code>) value, + * held by this WStringHolder. + */ + public String value; + + /** + * Constructs an instance of WStringHolder, + * initializing {@link #value} to <code>null</code>. + */ + public WStringHolder() + { + } + + /** + * Constructs an instance of WStringHolder, + * initializing {@link #value} to the given <code>String</code>. + * + * @param initial_value a value that will be assigned to the + * {@link #value} field. + */ + public WStringHolder(String initial_value) + { + value = initial_value; + } + + /** + * Fill in the {@link #value } field by reading the required data + * from the given stream. For <code>string</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.InputStream#read_wstring}. + * + * @param input the input stream to read from. + */ + public void _read(InputStream input) + { + value = input.read_wstring(); + } + + /** + * Returns the TypeCode, corresponding the CORBA type that is stored + * using this holder. The {@link TypeCode#length()} method of the + * returned typecode always returns 0. + */ + public TypeCode _type() + { + return t_string; + } + + /** + * Write the {@link #value } field to the given stream. + * For <code>string</code>, the functionality + * is delegated to + * {@link org.omg.CORBA.portable.OutputStream#write_wstring(String) }. + * + * @param output the output stream to write into. + */ + public void _write(OutputStream output) + { + output.write_wstring(value); + } +} diff --git a/libjava/classpath/gnu/CORBA/_PolicyImplBase.java b/libjava/classpath/gnu/CORBA/_PolicyImplBase.java new file mode 100644 index 000000000..a235080c1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/_PolicyImplBase.java @@ -0,0 +1,232 @@ +/* _PolicyImplBase.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.CompletionStatus; +import org.omg.CORBA.Policy; +import org.omg.CORBA.PolicyHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.InvokeHandler; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.ResponseHandler; + +/** + * The server side implementation base for the {@link Policy}. + * + * @specnote The java 1.4 API does not define the server side policy + * implementation base, but it defines the policy client side stub. + * As these two classes always work together, and even no separate testing is + * possible, the required implementation base is provided in gnu.CORBA + * namespace. Sun will probably include they base in the future java APIs. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public abstract class _PolicyImplBase + extends ObjectImpl + implements Policy, InvokeHandler +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The policy repository ids. + */ + private final String[] ids; + + /** + * The type of this policy. + */ + private final int type; + + /** + * The value of this policy. The value object is never the same + * for different policies. + */ + private final java.lang.Object value; + + /** + * The policy integer code, written in request to write + * the policy value. + */ + private final int policyCode; + + /** + * Create the new policy of the given type, having the given value. + * For security reasons, the method is kept package private. + * + * @param p_type the type of this policy. + * @param p_value the value of this policy. + * @param p_code the integer code of this policy. + * @param p_idl the policy IDL type string. The {@link #_ids()} + * will return array, first line being this string and another + * being PolicyHelper.id(). + */ + public _PolicyImplBase(int p_type, java.lang.Object p_value, int p_code, + String p_idl + ) + { + type = p_type; + value = p_value; + policyCode = p_code; + ids = new String[] { p_idl, PolicyHelper.id() }; + } + + /** + * Get the integer code of the type of this policy. + */ + public final int policy_type() + { + return type; + } + + /** + * Return the list of repository ids. + */ + public final String[] _ids() + { + return ids; + } + + /** + * Call the required method. + */ + public final OutputStream _invoke(String method, InputStream input, + ResponseHandler rh + ) + { + OutputStream output = null; + + if (method.equals("destroy")) + { + // The "destroy" has been invoked. + destroy(); + output = rh.createReply(); + } + else if (method.equals("copy")) + { + // The "copy" has been invoked. + org.omg.CORBA.Object returns = copy(); + output = rh.createReply(); + output.write_Object(this); + } + else if (method.equals("policy_type")) + { + // The "policy_type" has been invoked. + int returns = policy_type(); + output = rh.createReply(); + output.write_long(returns); + } + else if (method.equals("value")) + { + // The "value" can be invoked on the children types + // and must return an integer, representing the policy value + // (CORBA enumeration). + output = rh.createReply(); + output.write_long(policyCode); + } + else + throw new BAD_OPERATION(method, Minor.Method, + CompletionStatus.COMPLETED_MAYBE); + + return output; + } + + /** + * Get the value of this policy + */ + public final java.lang.Object getValue() + { + return value; + } + + /** + * Get the integer code of this policy value. + */ + public final int getCode() + { + return policyCode; + } + + /** + * Returns without action. It is a work of garbage collector + * to remove the unused objects. + */ + public final void destroy() + { + } + + /** + * Returns the string representation of the given policy. + */ + public final String toString() + { + return value.toString(); + } + + /** + * Create a copy of this policy. The object is not mutable, so + * <code>this</code> can be returned. + * + * @return <code>this</code> + */ + public Policy copy() + { + return this; + } + + /** + * Use the value to get a hash code. + */ + public int hashCode() + { + return getValue().hashCode(); + } + + /** + * Check the values for equality. + */ + public boolean equals(Object x) + { + return x == null ? false : getValue().equals(x); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuAny.java b/libjava/classpath/gnu/CORBA/gnuAny.java new file mode 100644 index 000000000..6692d623e --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuAny.java @@ -0,0 +1,907 @@ +/* gnuAny.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.Vio; +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.typecodes.PrimitiveTypeCode; +import gnu.CORBA.typecodes.StringTypeCode; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnyHolder; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BooleanHolder; +import org.omg.CORBA.CharHolder; +import org.omg.CORBA.DoubleHolder; +import org.omg.CORBA.FixedHolder; +import org.omg.CORBA.FloatHolder; +import org.omg.CORBA.IntHolder; +import org.omg.CORBA.LongHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.ObjectHolder; +import org.omg.CORBA.Principal; +import org.omg.CORBA.PrincipalHolder; +import org.omg.CORBA.ShortHolder; +import org.omg.CORBA.StringHolder; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodeHolder; +import org.omg.CORBA.ValueBaseHolder; +import org.omg.CORBA.portable.Streamable; + +import java.io.Serializable; +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.zip.Adler32; + +/** + * The implementation of {@link Any}. + * + * For performance reasonse, the inserted values are not cloned. + * If the value object allows modifications (like {@link Streamable}), + * these subsequent alterations are reflected by the instance of + * this gnuAny, and the gnuAny alterations are reflected by the + * returned value. If it is required to have the uncoupled value, + * it must be requested from the copy of the current instance. + * The {@link gnuAny} can be simply cloned by the provided + * {@link Clone()} method. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuAny + extends Any +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The value, returned by {@link #type()} if the value has been + * not intialized. + */ + protected static final TypeCode nullType = + new PrimitiveTypeCode(TCKind.tk_null); + + /** + * The Streamable, representing the value, held by this gnuAny. + */ + protected Streamable has; + + /** + * The complete typecode of the Streamable, if explicitly set. + */ + protected TypeCode typecode; + + /** + * The typecode kind of the Streamable, if explicitly set. + */ + protected int xKind = -1; + + /** + * The associated ORB. + */ + private ORB orb; + + /** + * Set the associated orb. + */ + public void setOrb(ORB an_orb) + { + orb = an_orb; + } + + /** + * Creates a deep copy of this gnuAny, writing to and subsequently + * reading from from the byte buffer. + * + * @return the uncoupled gnuAny with all fields set to identical + * values. + */ + public gnuAny Clone() + { + BufferedCdrOutput out = new BufferedCdrOutput(); + out.setOrb(orb); + out.write_any(this); + + BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray()); + in.setOrb(orb); + return (gnuAny) in.read_any(); + } + + /** + * Create the buffered CDR input stream, containing the + * value, stored inside of this {@link Any}. + */ + public org.omg.CORBA.portable.InputStream create_input_stream() + { + if (has instanceof GeneralHolder) + { + GeneralHolder u = (GeneralHolder) has; + return u.getInputStream(); + } + else + { + BufferedCdrOutput out = new BufferedCdrOutput(); + out.setOrb(orb); + write_value(out); + + BufferredCdrInput in = new BufferredCdrInput(out.buffer.toByteArray()); + in.setOrb(orb); + return in; + } + } + + /** + * Create the buffered CDR output stream (empty). + */ + public org.omg.CORBA.portable.OutputStream create_output_stream() + { + BufferedCdrOutput stream = new BufferedCdrOutput(); + stream.setOrb(orb); + return stream; + } + + /** + * Compare two Any's for equality. + * @param other the other Any to compare. + */ + public boolean equal(Any other) + { + if (other == this) + return true; + if (type().kind() != other.type().kind()) + return false; + + if (has != null && other instanceof gnuAny) + if (has.equals(((gnuAny) other).has)) + return true; + + BufferedCdrOutput a = new BufferedCdrOutput(); + a.setOrb(orb); + write_value(a); + + BufferedCdrOutput b = new BufferedCdrOutput(); + b.setOrb(orb); + other.write_value(b); + + byte[] ba = a.buffer.toByteArray(); + byte[] bb = b.buffer.toByteArray(); + + return Arrays.equals(ba, bb); + } + + /** + * Get the content - dependent hashcode. + */ + public int hashCode() + { + if (has == null) + return type().kind().value(); + else + { + Adler32 adler = new Adler32(); + + BufferedCdrOutput a = new BufferedCdrOutput(); + a.setOrb(orb); + write_value(a); + + adler.update(a.buffer.toByteArray()); + adler.update(type().kind().value()); + + return (int) adler.getValue() & Integer.MAX_VALUE; + } + } + + /** + * Delegates functionality to {@link #equal(Any)}. + */ + public boolean equals(java.lang.Object other) + { + if (other == this) + return true; + if (!(other instanceof Any)) + return false; + + return equal((Any) other); + } + + /** + * Extract the previously stored object. + */ + public org.omg.CORBA.Object extract_Object() + { + try + { + return ((ObjectHolder) has).value; + } + catch (ClassCastException ex) + { + BAD_OPERATION bad = new BAD_OPERATION(); + bad.initCause(ex); + bad.minor = Minor.Any; + throw bad; + } + } + + /** + * Extract the previously inserted CORBA <code>Principal</code>/ + * @return the previously inserted value. + * + * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something + * else than Principal. + * + * @deprecated by CORBA 2.2. + */ + public Principal extract_Principal() + { + check(TCKind._tk_Principal); + return ((PrincipalHolder) has).value; + } + + /** + * Return the value, encapsulated in a suitable holder. + * This implementation returns the direct reference, + * so the alterations on the returned streamable are + * directly reflected to the content of this {@link Any}. + */ + public Streamable extract_Streamable() + { + return has; + } + + public TypeCode extract_TypeCode() + throws BAD_OPERATION + { + check(TCKind._tk_TypeCode); + return ((TypeCodeHolder) has).value; + } + + /** + * Extract the stored value type. + * + * @return the previously stored value type. + * + * @throws BAD_OPERATION if the Any contains something different. + * + * @see org.omg.CORBA.portable.ValueBase + */ + public Serializable extract_Value() + throws BAD_OPERATION + { + try + { + if (has instanceof ValueBaseHolder) + return ((ValueBaseHolder) has).value; + else + { + // Normally, ValueBase holder must be an instance of the + // ValueBaseHolder. However some IDL compilers probably + // have a bug, do not deriving this way. The the only + // way to access the wrapped value is via reflection. + Field f = has.getClass().getField("value"); + return (Serializable) f.get(has); + } + } + catch (Exception ex) + { + BAD_OPERATION bad = new BAD_OPERATION("Value type expected"); + bad.minor = Minor.Any; + bad.initCause(ex); + throw bad; + } + } + + /** {@inheritDoc} */ + public Any extract_any() + throws BAD_OPERATION + { + check(TCKind._tk_any); + return ((AnyHolder) has).value; + } + + /** {@inheritDoc} */ + public boolean extract_boolean() + throws BAD_OPERATION + { + check(TCKind._tk_boolean); + return ((BooleanHolder) has).value; + } + + /** {@inheritDoc} */ + public char extract_char() + throws BAD_OPERATION + { + check(TCKind._tk_char); + return ((CharHolder) has).value; + } + + /** {@inheritDoc} */ + public double extract_double() + throws BAD_OPERATION + { + check(TCKind._tk_double); + return ((DoubleHolder) has).value; + } + + /** + * Extract the previously inserted CORBA <code>fixed</code>/ + * @return the previously inserted value. + * + * @throws org.omg.CORBA.BAD_OPERATION if the holder contains something + * else than BigDecimal. + */ + public BigDecimal extract_fixed() + throws org.omg.CORBA.BAD_OPERATION + { + check(TCKind._tk_fixed); + return ((FixedHolder) has).value; + } + + /** {@inheritDoc} */ + public float extract_float() + throws BAD_OPERATION + { + check(TCKind._tk_float); + return ((FloatHolder) has).value; + } + + /** {@inheritDoc} */ + public int extract_long() + throws BAD_OPERATION + { + // CORBA long = java int. + check(TCKind._tk_long); + return ((IntHolder) has).value; + } + + /** {@inheritDoc} */ + public long extract_longlong() + throws BAD_OPERATION + { + check(TCKind._tk_longlong); + return ((LongHolder) has).value; + } + + /** {@inheritDoc} */ + public byte extract_octet() + throws BAD_OPERATION + { + // ShortHolder holds also octets. + check(TCKind._tk_octet); + return (byte) ((OctetHolder) has).value; + } + + /** {@inheritDoc} */ + public short extract_short() + throws BAD_OPERATION + { + check(TCKind._tk_short); + return ((ShortHolder) has).value; + } + + /** {@inheritDoc} */ + public String extract_string() + throws BAD_OPERATION + { + check(TCKind._tk_string); + return ((StringHolder) has).value; + } + + /** {@inheritDoc} */ + public int extract_ulong() + throws BAD_OPERATION + { + // IntHolder also holds ulongs. + check(TCKind._tk_ulong); + return ((IntHolder) has).value; + } + + /** {@inheritDoc} */ + public long extract_ulonglong() + throws BAD_OPERATION + { + // LongHolder also holds ulonglong + check(TCKind._tk_ulonglong); + return ((LongHolder) has).value; + } + + /** {@inheritDoc} */ + public short extract_ushort() + throws BAD_OPERATION + { + // ShortHolder also holds ushorts. + check(TCKind._tk_ushort); + return ((ShortHolder) has).value; + } + + /** {@inheritDoc} */ + public char extract_wchar() + throws BAD_OPERATION + { + check(TCKind._tk_wchar); + return ((WCharHolder) has).value; + } + + /** {@inheritDoc} */ + public String extract_wstring() + throws BAD_OPERATION + { + // StringHolder also holds wstrings. + check(TCKind._tk_wstring); + return ((WStringHolder) has).value; + } + + /** + * Inserts the CORBA object and sets the typecode to the given type. + */ + public void insert_Object(org.omg.CORBA.Object x, TypeCode typecode) + { + has = new ObjectHolder(x); + type(typecode); + } + + /** + * Inserts the CORBA object. + */ + public void insert_Object(org.omg.CORBA.Object x) + { + has = new ObjectHolder(x); + } + + /** + * Insert the CORBA Principal. + * This implementation uses direct assignment, so the later + * alterations of that BigDecimal are reflected on the + * content of this {@link Any}. + * + * @deprecated by CORBA 2.2. + */ + public void insert_Principal(Principal x) + { + resetTypes(); + if (has instanceof PrincipalHolder) + ((PrincipalHolder) has).value = x; + else + has = new PrincipalHolder(x); + } + + /** + * Sets the value to the value, encapsulated in this holder. + * This implementation uses direct assignment, so the later + * alterations of that streamable are reflected on the + * content of this {@link Any}. + */ + public void insert_Streamable(Streamable x) + { + resetTypes(); + has = x; + } + + /** + * Insert the typecode into this Any + * @param typecode the typecode to insert. + */ + public void insert_TypeCode(TypeCode typecode) + { + resetTypes(); + if (has instanceof TypeCodeHolder) + ((TypeCodeHolder) has).value = typecode; + else + has = new TypeCodeHolder(typecode); + } + + /** {@inheritDoc} */ + public void insert_Value(Serializable x, TypeCode c_typecode) + { + 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) + { + if (typecode != null && typecode.kind() == TCKind.tk_value_box) + { + has = new gnuValueHolder(x, typecode); + } + else + { + if (has instanceof ValueBaseHolder) + ((ValueBaseHolder) has).value = x; + else + has = new ValueBaseHolder(x); + } + } + + /** + * Insert another {@link Any} into this {@link Any}. + * This implementation uses direct assignment, so the later + * alterations of that {@link Any} are reflected on the + * content of this {@link Any}. + */ + public void insert_any(Any an_any) + { + resetTypes(); + if (has instanceof AnyHolder) + ((AnyHolder) has).value = an_any; + else + has = new AnyHolder(an_any); + } + + /** {@inheritDoc} */ + public void insert_boolean(boolean x) + { + resetTypes(); + if (has instanceof BooleanHolder) + ((BooleanHolder) has).value = x; + else + has = new BooleanHolder(x); + } + + /** {@inheritDoc} */ + public void insert_char(char x) + { + resetTypes(); + if (has instanceof CharHolder) + ((CharHolder) has).value = x; + else + has = new CharHolder(x); + } + + /** {@inheritDoc} */ + public void insert_double(double x) + { + resetTypes(); + if (has instanceof DoubleHolder) + ((DoubleHolder) has).value = x; + else + has = new DoubleHolder(x); + } + + /** + * Inserts the CORBA <code>fixed</code>, setting the typecode + * explicitly. + * This implementation uses direct assignment, so the later + * alterations of that BigDecimal are reflected on the + * content of this {@link Any}. + */ + public void insert_fixed(BigDecimal x, TypeCode x_typecode) + { + resetTypes(); + insert_fixed(x); + typecode = x_typecode; + } + + /** + * Inserts the CORBA <code>fixed</code>, setting the typecode + * by example of the currently passed value. + * This implementation uses direct assignment, so the later + * alterations of that BigDecimal are reflected on the + * content of this {@link Any}, including the typecode. + */ + public void insert_fixed(BigDecimal x) + { + resetTypes(); + if (has instanceof FixedHolder) + ((FixedHolder) has).value = x; + else + has = new FixedHolder(x); + } + + /** {@inheritDoc} */ + public void insert_float(float x) + { + resetTypes(); + if (has instanceof FloatHolder) + ((FloatHolder) has).value = x; + else + has = new FloatHolder(x); + } + + /** {@inheritDoc} */ + public void insert_long(int x) + { + resetTypes(); + if (has instanceof IntHolder) + ((IntHolder) has).value = x; + else + has = new IntHolder(x); + } + + /** {@inheritDoc} */ + public void insert_longlong(long x) + { + resetTypes(); + if (has instanceof LongHolder) + ((LongHolder) has).value = x; + else + has = new LongHolder(x); + } + + /** {@inheritDoc} */ + public void insert_octet(byte x) + { + resetTypes(); + if (has instanceof OctetHolder) + ((OctetHolder) has).value = x; + else + has = new OctetHolder(x); + } + + /** {@inheritDoc} */ + public void insert_short(short x) + { + resetTypes(); + if (has instanceof ShortHolder) + ((ShortHolder) has).value = x; + else + has = new ShortHolder(x); + } + + /** {@inheritDoc} */ + public void insert_string(String x) + { + resetTypes(); + if (has instanceof StringHolder) + ((StringHolder) has).value = x; + else + has = new StringHolder(x); + + typecode = new StringTypeCode(TCKind.tk_string); + } + + /** {@inheritDoc} */ + public void insert_ulong(int x) + { + resetTypes(); + if (has instanceof IntHolder) + ((IntHolder) has).value = x; + else + has = new IntHolder(x); + xKind = TCKind._tk_ulong; + } + + /** {@inheritDoc} */ + public void insert_ulonglong(long x) + { + resetTypes(); + if (has instanceof LongHolder) + ((LongHolder) has).value = x; + else + has = new LongHolder(x); + xKind = TCKind._tk_ulonglong; + } + + /** {@inheritDoc} */ + public void insert_ushort(short x) + { + resetTypes(); + if (has instanceof ShortHolder) + ((ShortHolder) has).value = x; + else + has = new ShortHolder(x); + xKind = TCKind._tk_ushort; + } + + /** {@inheritDoc} */ + public void insert_wchar(char x) + { + resetTypes(); + if (has instanceof WCharHolder) + ((WCharHolder) has).value = x; + else + has = new WCharHolder(x); + } + + /** {@inheritDoc} */ + public void insert_wstring(String x) + { + resetTypes(); + if (has instanceof WStringHolder) + ((WStringHolder) has).value = x; + else + has = new WStringHolder(x); + } + + /** + * Return the associated orb. + */ + public ORB orb() + { + return orb; + } + + /** + * Read the value of the given type from the given stream. + * + * @param input a stream to read from. + * @param a_type a typecode of the value to read. + */ + public void read_value(org.omg.CORBA.portable.InputStream input, + TypeCode a_type + ) + throws MARSHAL + { + try + { + int kind = a_type.kind().value(); + + // Fixed needs special handling. + if (kind == TCKind._tk_fixed) + { + BigDecimal dec = BigDecimalHelper.read(input, a_type.fixed_scale()); + has = new FixedHolder(dec); + } + else + { + has = HolderLocator.createHolder(a_type); + if (has == null) + { + // Use the Universal Holder that reads till the end of stream. + // This works with the extract/insert pair of the typical + // Helper. + BufferedCdrOutput buffer = new BufferedCdrOutput(); + buffer.setOrb(orb); + has = new GeneralHolder(buffer); + } + } + type(a_type); + + if (!(has instanceof GeneralHolder) && + (kind == TCKind._tk_value_box)) + { + // The streamable only contains operations for + // reading the value, not the value header. + Field vField = has.getClass().getField("value"); + + Object content = Vio.read(input, a_type.id()); + vField.set(has, content); + } + else + has._read(input); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(); + m.minor = Minor.Any; + m.initCause(ex); + throw m; + } + } + + /** {@inheritDoc} */ + public TypeCode type() + { + if (typecode != null) + return typecode; + else if (xKind >= 0) + { + typecode = new PrimitiveTypeCode(TCKind.from_int(xKind)); + return typecode; + } + else + return has != null ? has._type() : nullType; + } + + /** + * Explicitly set the typecode of the value to the given type. + * + * @param valueTypeCode the typecode of the value. + */ + public void type(TypeCode valueTypeCode) + { + xKind = valueTypeCode.kind().value(); + typecode = valueTypeCode; + } + + /** {@inheritDoc} */ + public void write_value(org.omg.CORBA.portable.OutputStream output) + { + 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); + } + + /** + * Check if the current value if the value of the given kind. + * + * @param kind a kind to check. + * @throws BAD_OPERATION if the value is not set of is different kind. + */ + protected void check(int kind) + throws BAD_OPERATION + { + if (has == null) + { + BAD_OPERATION bad = new BAD_OPERATION("value not set"); + bad.minor = Minor.Any; + throw bad; + } + + if (xKind >= 0) + { + if (xKind != kind) + if (!(xKind == TCKind._tk_alias && has._type().kind().value() == kind)) + { + BAD_OPERATION bad = new BAD_OPERATION("Extracting " + + TypeKindNamer.nameIt(kind) + " when stored " + + TypeKindNamer.nameIt(xKind)); + bad.minor = Minor.Any; + throw bad; + } + } + else + { + if (type().kind().value() != kind) + if (!(type().kind().value() == TCKind._tk_alias && has._type().kind().value() == kind)) + { + BAD_OPERATION bad = new BAD_OPERATION("Extracting " + + TypeKindNamer.nameIt(kind) + " stored " + + TypeKindNamer.nameIt(type())); + bad.minor = Minor.Any; + throw bad; + } + } + } + + /** + * Clear the additional type information before reusing this instance. + */ + private final void resetTypes() + { + typecode = null; + xKind = -1; + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuCodecFactory.java b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java new file mode 100644 index 000000000..5dfd56df1 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuCodecFactory.java @@ -0,0 +1,90 @@ +/* gnuCodecFactory.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.LocalObject; +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; + +/** + * A simple implementation of the Codec factory, able to return the + * standard Codec's. Only ENCODING_CDR_ENCAPS encoding is supported. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuCodecFactory extends LocalObject implements CodecFactory +{ + /** + * The associated ORB. + */ + private final ORB orb; + + /** + * Create a new instance of the this factory, associated with the given ORB. + */ + public gnuCodecFactory(ORB an_orb) + { + orb = an_orb; + } + + /** + * Creates the Codec for the given encoding. + * + * @param for_encoding the encoding for that the Codec must be created. + * + * @return the suitable Codec. + * + * @throws UnknownEncoding if the encoding is not a ENCODING_CDR_ENCAPS. + */ + 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." + ); + + return new CdrEncapsCodecImpl(orb, + new Version(for_encoding.major_version, for_encoding.minor_version) + ); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuContext.java b/libjava/classpath/gnu/CORBA/gnuContext.java new file mode 100644 index 000000000..baa9fc804 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuContext.java @@ -0,0 +1,202 @@ +/* gnuContext.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.omg.CORBA.Any; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.CTX_RESTRICT_SCOPE; +import org.omg.CORBA.Context; +import org.omg.CORBA.NVList; + +/** + * The working implementation of the {@link org.omg.CORBA.Context}. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuContext + extends Context +{ + /** + * The parent context. + */ + Context parent; + + /** + * The collection to store the context properties. + */ + Map properties = new Hashtable(); + + /** + * The name of this context. + */ + String name; + + /** + * Creates the new context with the given name and parent. + * + * @param a_name a name of the new context. + * @param a_parent a parent, used to resolve the missing references. + */ + public gnuContext(String a_name, Context a_parent) + { + name = a_name; + parent = a_parent; + } + + /** {@inheritDoc} */ + public String context_name() + { + return name; + } + + /** {@inheritDoc} */ + public Context create_child(String child) + { + return new gnuContext(child, this); + } + + /** {@inheritDoc} */ + public void delete_values(String property) + { + boolean starts = false; + if (property.endsWith("*")) + { + starts = true; + property = property.substring(0, property.length() - 1); + } + + Set keys = properties.keySet(); + + Iterator iter = keys.iterator(); + while (iter.hasNext()) + { + String key = (String) iter.next(); + if ((starts && key.startsWith(property)) || + (!starts && key.equals(property)) + ) + iter.remove(); + } + } + + /** {@inheritDoc} */ + public NVList get_values(String start_scope, int flags, String pattern) + { + if (start_scope != null) + { + Context c = this; + while (c != null && !c.context_name().equals(start_scope)) + c = c.parent(); + if (c == null) + return new gnuNVList(); + } + + try + { + gnuNVList rt = new gnuNVList(); + + boolean starts = false; + if (pattern.endsWith("*")) + { + starts = true; + pattern = pattern.substring(0, pattern.length() - 1); + } + + Set keys = properties.keySet(); + + Iterator iter = keys.iterator(); + while (iter.hasNext()) + { + String key = (String) iter.next(); + if ((starts && key.startsWith(pattern)) || + (!starts && key.equals(pattern)) + ) + { + rt.add_value(key, (Any) properties.get(key), 0); + } + } + + if ((flags & CTX_RESTRICT_SCOPE.value) == 0 && parent != null) + { + NVList par = parent.get_values(start_scope, flags, pattern); + for (int i = 0; i < par.count(); i++) + { + rt.list.add(par.item(i)); + } + } + + return rt; + } + catch (Bounds ex) + { + throw new Error("Report this bug."); + } + } + + /** {@inheritDoc} */ + public Context parent() + { + return parent; + } + + /** {@inheritDoc} */ + public void set_one_value(String name, Any value) + { + properties.put(name, value); + } + + /** {@inheritDoc} */ + public void set_values(NVList values) + { + try + { + for (int i = 0; i < values.count(); i++) + { + properties.put(values.item(i).name(), values.item(i).value()); + } + } + catch (Bounds ex) + { + throw new Error("Please report this bug."); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuContextList.java b/libjava/classpath/gnu/CORBA/gnuContextList.java new file mode 100644 index 000000000..592eb2c2c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuContextList.java @@ -0,0 +1,81 @@ +/* gnuContextList.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ContextList; + +/** + * The working implementation of the {@link org.omg.CORBA.ContextList}. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuContextList + extends ContextList +{ + /** + * The collection, holding the actual list of strings. + */ + CorbaList strings = new CorbaList(); + + /** {@inheritDoc} */ + public void add(String name) + { + strings.add(name); + } + + /** {@inheritDoc} */ + public int count() + { + return strings.size(); + } + + /** {@inheritDoc} */ + public String item(int at) + throws Bounds + { + return (String) strings.item(at); + } + + /** {@inheritDoc} */ + public void remove(int at) + throws Bounds + { + strings.drop(at); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuEnvironment.java b/libjava/classpath/gnu/CORBA/gnuEnvironment.java new file mode 100644 index 000000000..beb805e6f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuEnvironment.java @@ -0,0 +1,72 @@ +/* gnuEnvironment.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Environment; + +/** + * The implementation of the exception container ("Environment"). + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuEnvironment + extends Environment +{ + /** + * The stored exception. + */ + protected Exception exception; + + /** {@inheritDoc} */ + public void clear() + { + exception = null; + } + + /** {@inheritDoc} */ + public void exception(Exception except) + { + exception = except; + } + + /** {@inheritDoc} */ + public Exception exception() + { + return exception; + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuExceptionList.java b/libjava/classpath/gnu/CORBA/gnuExceptionList.java new file mode 100644 index 000000000..06ddf8d71 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuExceptionList.java @@ -0,0 +1,82 @@ +/* gnuExceptionList.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Bounds; +import org.omg.CORBA.ExceptionList; +import org.omg.CORBA.TypeCode; + +/** + * The implementation of the list of type codes for exceptions. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org). + */ +public class gnuExceptionList + extends ExceptionList +{ + /** + * A list to store the objects. + */ + protected CorbaList list = new CorbaList(); + + /** {@inheritDoc} */ + public void add(TypeCode an_exception) + { + list.add(an_exception); + } + + /** {@inheritDoc} */ + public int count() + { + return list.size(); + } + + /** {@inheritDoc} */ + public TypeCode item(int at) + throws Bounds + { + return (TypeCode) list.item(at); + } + + /** {@inheritDoc} */ + public void remove(int at) + throws Bounds + { + list.drop(at); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuNVList.java b/libjava/classpath/gnu/CORBA/gnuNVList.java new file mode 100644 index 000000000..3645a3e8d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuNVList.java @@ -0,0 +1,127 @@ +/* gnuNVList.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Any; +import org.omg.CORBA.Bounds; +import org.omg.CORBA.NVList; +import org.omg.CORBA.NamedValue; + +/** + * The implementation of {@link NVList}. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuNVList + extends NVList +{ + /** + * The list of the named values. + */ + protected CorbaList list; + + /** + * Creates the list with the default initial size. + */ + public gnuNVList() + { + list = new CorbaList(); + } + + /** + * Creates the list with the given initial size. + */ + public gnuNVList(int initial_size) + { + list = new CorbaList(initial_size); + } + + /** {@inheritDoc} */ + public NamedValue add(int a_flags) + { + return add_value(null, new gnuAny(), a_flags); + } + + /** {@inheritDoc} */ + public NamedValue add_item(String a_name, int a_flags) + { + return add_value(a_name, new gnuAny(), a_flags); + } + + /** {@inheritDoc} */ + public NamedValue add_value(String a_name, Any a_value, int a_flags) + { + gnuNamedValue n = new gnuNamedValue(); + n.setName(a_name); + n.setValue(a_value); + n.setFlags(a_flags); + list.add(n); + return n; + } + + /** + * Add the given named value to the list directly. + * + * @param value the named vaue to add. + */ + public void add(NamedValue value) + { + list.add(value); + } + + + /** {@inheritDoc} */ + public int count() + { + return list.size(); + } + + /** {@inheritDoc} */ + public NamedValue item(int at) + throws Bounds + { + return (NamedValue) list.item(at); + } + + /** {@inheritDoc} */ + public void remove(int at) + throws Bounds + { + list.drop(at); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuNamedValue.java b/libjava/classpath/gnu/CORBA/gnuNamedValue.java new file mode 100644 index 000000000..6e3c271c9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuNamedValue.java @@ -0,0 +1,112 @@ +/* gnuNamedValue.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import org.omg.CORBA.Any; +import org.omg.CORBA.NamedValue; + +/** + * The implementation of the named value. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class gnuNamedValue + extends NamedValue +{ + /** + * The named value value. + */ + private Any m_value = new gnuAny(); + + /** + * The named value name. + */ + private String m_name; + + /** + * The named value flags. + */ + private int m_flags; + + /** + * Set the flags, the normally expected values are + * {@link org.omg.CORBA.ARG_IN#value}, + * {@link org.omg.CORBA.ARG_OUT#value} and + * {@link org.omg.CORBA.ARG_INOUT#value}. + */ + public void setFlags(int flags) + { + m_flags = flags; + } + + /** + * Set the name of the value. + * @param name the name of this value + */ + public void setName(String name) + { + m_name = name; + } + + /** + * Set the value of the value. + * @param value the value of this object. + */ + public void setValue(Any value) + { + m_value = value; + } + + /** {@inheritDoc} */ + public int flags() + { + return m_flags; + } + + /** {@inheritDoc} */ + public String name() + { + return m_name; + } + + /** {@inheritDoc} */ + public Any value() + { + return m_value; + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuRequest.java b/libjava/classpath/gnu/CORBA/gnuRequest.java new file mode 100644 index 000000000..56c9dbb1f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuRequest.java @@ -0,0 +1,1423 @@ +/* gnuRequest.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.BufferredCdrInput; +import gnu.CORBA.CDR.BufferedCdrOutput; +import gnu.CORBA.GIOP.MessageHeader; +import gnu.CORBA.GIOP.ReplyHeader; +import gnu.CORBA.GIOP.RequestHeader; +import gnu.CORBA.GIOP.CodeSetServiceContext; +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.COMM_FAILURE; +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.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; +import java.io.OutputStream; + +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 +{ + /** + * The maximal supported GIOP version. + */ + public static Version MAX_SUPPORTED = new Version(1, 2); + + /** + * 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. + */ + 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. + */ + 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 RawReply EMPTY = + new RawReply(null, new MessageHeader(), new byte[ 0 ]); + + /** + * The context holder for methods ctx(Context) and ctx(). + */ + protected Context m_context; + + /** + * The context list for method contexts(). + */ + protected ContextList m_context_list; + + /** + * 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. + */ + protected ExceptionList m_exceptions = new gnuExceptionList(); + + /** + * The result, returned by the invoked method (function). + */ + 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; + + /** + * The name of the method being invoked. + */ + protected String m_operation; + + /** + * 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()}). + */ + protected boolean oneWay; + + /** + * The flag, indicating that the request has been sent and no result is yet + * received. + */ + protected boolean running; + + /** + * The request arguments. + */ + protected gnuNVList m_args = new gnuNVList(); + + /** + * The request arguments in the case when they are directly written into the + * parameter buffer. + */ + protected StreamBasedRequest 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; + + /** + * The ORB of the target. + */ + private ORB orb; + + /** + * 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. + */ + private boolean Big_endian = true; + + /** + * Set the IOR data, sufficient to find the invocation target. This also sets + * default endian encoding for invocations. + * + * @see IOR.parse(String) + */ + public void setIor(IOR an_ior) + { + ior = an_ior; + setBigEndian(ior.Big_Endian); + } + + /** + * Used when redirecting request to another target. + */ + gnuRequest redirected; + + /** + * Get the IOR data, sufficient to find the invocation target. + * + * @return the IOR data. + */ + public IOR getIor() + { + return ior; + } + + /** + * Set the ORB, related to the invocation target. + */ + public void setORB(ORB an_orb) + { + orb = an_orb; + + // Take the interceptor from the ORB. + if (orb instanceof OrbRestricted) + m_interceptor = ((OrbRestricted) 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. + * + * @param use_big_endian true to use the Big Endian, false to use the Little + * Endian encoding. + */ + public void setBigEndian(boolean use_big_endian) + { + Big_endian = use_big_endian; + } + + /** + * The the method name to invoke. + * + * @param operation the method name. + */ + public void setOperation(String operation) + { + m_operation = operation; + } + + /** + * Get the parameter stream, where the invocation arguments should be written + * if they are written into the stream directly. + */ + public StreamBasedRequest getParameterStream() + { + m_parameter_buffer = new StreamBasedRequest(); + m_parameter_buffer.request = this; + m_parameter_buffer.setVersion(ior.Internet.version); + m_parameter_buffer.setCodeSet(CodeSetServiceContext.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)) + { + BufferedCdrOutput measure = new BufferedCdrOutput(); + 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; + } + + /** + * Creates a shallow copy of this request. + */ + public gnuRequest Clone() + { + try + { + return (gnuRequest) clone(); + } + catch (CloneNotSupportedException ex) + { + throw new Unexpected(ex); + } + } + + /** {@inheritDoc} */ + public Any add_in_arg() + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_IN.value); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public Any add_inout_arg() + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_INOUT.value); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public Any add_named_in_arg(String name) + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_IN.value); + v.setName(name); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public Any add_named_inout_arg(String name) + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_INOUT.value); + v.setName(name); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public Any add_named_out_arg(String name) + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_OUT.value); + v.setName(name); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public Any add_out_arg() + { + gnuNamedValue v = new gnuNamedValue(); + v.setFlags(ARG_OUT.value); + m_args.add(v); + return v.value(); + } + + /** {@inheritDoc} */ + public NVList arguments() + { + return m_args; + } + + /** {@inheritDoc} */ + public ContextList contexts() + { + return m_context_list; + } + + /** {@inheritDoc} */ + public Context ctx() + { + return m_context; + } + + /** {@inheritDoc} */ + public void ctx(Context a_context) + { + m_context = a_context; + } + + /** {@inheritDoc} */ + public Environment env() + { + return m_environment; + } + + /** {@inheritDoc} */ + public ExceptionList exceptions() + { + return m_exceptions; + } + + /** {@inheritDoc} */ + 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. + */ + } + + /** + * 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. + * + * @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. + */ + public synchronized void invoke() throws BAD_INV_ORDER + { + waitWhileBusy(); + complete = false; + running = true; + + if (ior == null) + throw new BAD_INV_ORDER("Set IOR property first"); + + try + { + Forwardings: + while (true) + { + try + { + p_invoke(); + break Forwardings; + } + catch (ForwardRequest e) + { + try + { + ObjectImpl impl = (ObjectImpl) e.forward; + SimpleDelegate delegate = + (SimpleDelegate) impl._get_delegate(); + ior = delegate.getIor(); + } + catch (Exception ex) + { + BAD_PARAM bad = + new BAD_PARAM("Unsupported forwarding target"); + bad.initCause(ex); + throw bad; + } + } + } + } + finally + { + running = false; + complete = true; + } + } + + /** {@inheritDoc} */ + public String operation() + { + return m_operation; + } + + /** + * Get the orb, related to the invocation target. + */ + public ORB orb() + { + return orb; + } + + /** {@inheritDoc} */ + public boolean poll_response() + { + return complete && !running; + } + + /** {@inheritDoc} */ + public NamedValue result() + { + return m_result; + } + + /** + * {@inheritDoc} + * + */ + public Any return_value() + { + return m_result.value(); + } + + /** {@inheritDoc} */ + public synchronized void send_deferred() + { + waitWhileBusy(); + new Thread() + { + public void run() + { + invoke(); + } + }.start(); + } + + /** + * 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? + */ + public void send_oneway() + { + final gnuRequest cloned = Clone(); + cloned.oneWay = true; + + new Thread() + { + public void run() + { + cloned.invoke(); + } + }.start(); + } + + /** + * 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. + */ + public void set_args(NVList a_args) + { + if (a_args instanceof gnuNVList) + m_args = (gnuNVList) a_args; + else + { + try + { + // In case if this is another implementation of the NVList. + m_args.list.clear(); + for (int i = 0; i < a_args.count(); i++) + { + m_args.add(a_args.item(i)); + } + } + catch (Bounds ex) + { + Unexpected.error(ex); + } + } + } + + /** + * Set the context list that is later returned by the method + * {@link #contexts()}. + * + * @param a_context_list a new context list. + */ + public void set_context_list(ContextList a_context_list) + { + m_context_list = a_context_list; + } + + /** + * 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. + */ + public void set_environment(Environment a_environment) + { + m_environment = a_environment; + } + + /** + * 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. + */ + public void set_exceptions(ExceptionList a_exceptions) + { + m_exceptions = a_exceptions; + } + + /** + * Set the operation name. + * + * @param a_operation the operation name. + */ + public void set_operation(String a_operation) + { + m_operation = a_operation; + } + + /** + * 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. + */ + public void set_result(NamedValue a_result) + { + m_result = a_result; + } + + /** + * 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) + { + if (m_result == null || !returns.equal(m_result.value().type())) + { + m_result = new gnuNamedValue(); + m_result.value().type(returns); + } + } + + /** + * Set the invocation target. + * + * @param a_target the CORBA object for that the method will be invoked. + */ + public void set_target(org.omg.CORBA.Object a_target) + { + m_target = a_target; + } + + /** + * 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. + * @return the server response in binary form. + */ +public synchronized RawReply submit() + throws ForwardRequest + { + gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader(); + + header.setBigEndian(Big_endian); + + // The byte order will be Big Endian by default. + header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST; + header.version = useVersion(ior.Internet.version); + + RequestHeader rh = header.create_request_header(); + 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. + BufferedCdrOutput request_part = new BufferedCdrOutput(); + + request_part.setOffset(header.getHeaderSize()); + request_part.setVersion(header.version); + request_part.setCodeSet(CodeSetServiceContext.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."); + } + + if (m_parameter_buffer != null) + { + write_parameter_buffer(header, request_part); + } + + // Now the message size is available. + header.message_size = request_part.buffer.size(); + + Socket socket = null; + + java.lang.Object key = ior.Internet.host + ":" + ior.Internet.port; + + synchronized (SocketRepository.class) + { + socket = SocketRepository.get_socket(key); + } + + try + { + long pause = PAUSE_INITIAL; + + if (socket == null) + { + // The IOException may be thrown under very heavy parallel + // load. For some time, just wait, exceptiong the socket to free. + Open: for (int i = 0; i < PAUSE_STEPS; i++) + { + try + { + if (orb instanceof OrbFunctional) + socket = ((OrbFunctional) orb).socketFactory. + createClientSocket( + ior.Internet.host, ior.Internet.port); + else + socket = new Socket(ior.Internet.host, ior.Internet.port); + break Open; + } + catch (IOException ex) + { + try + { + // Expecting to free a socket via finaliser. + System.gc(); + Thread.sleep(pause); + pause = pause * 2; + if (pause > PAUSE_MAX) + pause = PAUSE_MAX; + } + catch (InterruptedException iex) + { + } + } + } + } + + if (socket == null) + throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port + + " in use"); + socket.setKeepAlive(true); + + OutputStream socketOutput = socket.getOutputStream(); + + // Write the message header. + header.write(socketOutput); + + // Write the request header and parameters (if present). + request_part.buffer.writeTo(socketOutput); + + socketOutput.flush(); + if (!socket.isClosed() && !oneWay) + { + MessageHeader response_header = new MessageHeader(); + InputStream socketInput = socket.getInputStream(); + response_header.read(socketInput); + + byte[] r; + if (orb instanceof OrbFunctional) + { + OrbFunctional fo = (OrbFunctional) orb; + r = response_header.readMessage(socketInput, socket, + fo.TOUT_WHILE_READING, fo.TOUT_AFTER_RECEIVING); + } + else + r = response_header.readMessage(socketInput, null, 0, 0); + + return new RawReply(orb, response_header, r); + } + else + return EMPTY; + } + catch (IOException io_ex) + { + COMM_FAILURE m = new COMM_FAILURE("Unable to open a socket at " + + ior.Internet.host + ":" + ior.Internet.port, 0xC9, + CompletionStatus.COMPLETED_NO); + m.initCause(io_ex); + throw m; + } + finally + { + try + { + if (socket != null && !socket.isClosed()) + { + socket.setSoTimeout(OrbFunctional.TANDEM_REQUESTS); + SocketRepository.put_socket(key, socket); + } + } + catch (IOException scx) + { + InternalError ierr = new InternalError(); + ierr.initCause(scx); + throw ierr; + } + } + } + + /** {@inheritDoc} */ + public org.omg.CORBA.Object target() + { + return m_target; + } + + /** + * 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) + { + if (desired.until_inclusive(MAX_SUPPORTED.major, MAX_SUPPORTED.minor)) + return desired; + else + return MAX_SUPPORTED; + } + + /** + * Wait while the response to request, submitted using + * {@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. + */ + public synchronized void waitWhileBusy() + { + // Waiting constants. + long wait = 10; + long increment = 2; + long max = 5000; + + while (running) + { + try + { + Thread.sleep(wait); + if (wait < max) + wait = wait * increment; + } + catch (InterruptedException ex) + { + } + } + } + + /** + * Do actual invocation. This method recursively calls itself if the + * redirection is detected. + */ + private void p_invoke() + throws SystemException, ForwardRequest + { + RawReply response = submit(); + + // If this is a one way message, do not care about the response. + if (oneWay && response == EMPTY) + return; + + if (m_rph == null) + m_rph = response.header.create_reply_header(); + + BufferredCdrInput input = response.getStream(); + input.setOrb(orb); + + m_rph.read(input); + + // The stream must be aligned sinve v1.2, but only once. + boolean align = response.header.version.since_inclusive(1, 2); + + switch (m_rph.reply_status) + { + case ReplyHeader.NO_EXCEPTION: + + NamedValue arg; + + // Read return value, if set. + if (m_result != null) + { + if (align) + { + input.align(8); + align = false; + } + m_result.value().read_value(input, m_result.value().type()); + } + + // Read returned parameters, if set. + if (m_args != null) + for (int i = 0; i < m_args.count(); i++) + { + try + { + arg = m_args.item(i); + + // Both ARG_INOUT and ARG_OUT have this binary flag set. + if ((arg.flags() & ARG_OUT.value) != 0) + { + if (align) + { + input.align(8); + align = false; + } + + arg.value().read_value(input, arg.value().type()); + } + } + catch (Bounds ex) + { + Unexpected.error(ex); + } + } + + if (m_interceptor != null) + m_interceptor.receive_reply(m_info); + + break; + + case ReplyHeader.SYSTEM_EXCEPTION: + if (align) + { + input.align(8); + align = false; + } + readExceptionId(input); + + m_sys_ex = ObjectCreator.readSystemException(input, + m_rph.service_context); + m_environment.exception(m_sys_ex); + + if (m_interceptor != null) + m_interceptor.receive_exception(m_info); + + throw m_sys_ex; + + case ReplyHeader.USER_EXCEPTION: + if (align) + { + 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 StreamHolder(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: + 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) + { + 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", 8100 + m_rph.reply_status, + CompletionStatus.COMPLETED_NO); + } + } + + /** + * Read exception id without changing the stream pointer position. + */ + void readExceptionId(BufferredCdrInput input) + { + input.mark(2048); + m_exception_id = input.read_string(); + input.reset(); + } + + /** + * Write the operation parameters. + * + * @param header the message header + * @param request_part the stream to write parameters into + * + * @throws MARSHAL if the attempt to write the parameters has failde. + */ + protected void write_parameter_buffer(MessageHeader header, + BufferedCdrOutput request_part + ) throws MARSHAL + { + try + { + if (header.version.since_inclusive(1, 2)) + { + request_part.align(8); + } + m_parameter_buffer.buffer.writeTo(request_part); + } + catch (IOException ex) + { + MARSHAL m = new MARSHAL("Unable to write method arguments to CDR output."); + m.minor = Minor.CDR; + throw m; + } + } + + /** + * Write the operation parameters. + * + * @param header the message header + * @param request_part the stream to write parameters into + * + * @throws MARSHAL if the attempt to write the parameters has failde. + */ + protected void write_parameters(MessageHeader header, + BufferedCdrOutput request_part + ) throws MARSHAL + { + // Align after 1.2, but only once. + boolean align = header.version.since_inclusive(1, 2); + NamedValue para; + + try + { + // Write parameters now. + for (int i = 0; i < m_args.count(); i++) + { + para = m_args.item(i); + + // This bit is set both for ARG_IN and ARG_INOUT + if ((para.flags() & ARG_IN.value) != 0) + { + if (align) + { + request_part.align(8); + align = false; + } + para.value().write_value(request_part); + } + } + } + catch (Bounds ex) + { + 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() + { + BufferedCdrOutput buf = new BufferedCdrOutput(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 IorObject(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. + BufferedCdrOutput buf = new BufferedCdrOutput(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 IorObject(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 + ); + } +} diff --git a/libjava/classpath/gnu/CORBA/gnuValueHolder.java b/libjava/classpath/gnu/CORBA/gnuValueHolder.java new file mode 100644 index 000000000..d3f2b6b58 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/gnuValueHolder.java @@ -0,0 +1,135 @@ +/* gnuValueHolder.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA; + +import gnu.CORBA.CDR.Vio; + +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.ValueBaseHolder; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; + +/** + * Boxed value holder that also remembers the value type and the value helper. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuValueHolder + extends ValueBaseHolder +{ + /** + * The type code of the stored value. + */ + TypeCode type; + + /** + * The helper that could read and write fields of the boxed value. + */ + transient BoxedValueHelper helper; + + /** + * If true, the helper not available. + */ + transient boolean helper_NA; + + /** + * Create a new instance for the given value and given type. + */ + public gnuValueHolder(Serializable value, TypeCode a_type) + { + super(value); + type = a_type; + } + + /** + * Get the true type, as it was passed in the constructor. + */ + public TypeCode _type() + { + return type; + } + + /** + * Write content to the output stream. Tries to locate the + * corresponding helper class. + */ + public void _write(OutputStream output) + { + findHelper(); + if (helper == null) + super._write(output); + else + Vio.write(output, value, helper); + } + + /** + * Read, trying to locate helper, if possible. + */ + public void _read(InputStream input) + { + findHelper(); + if (helper == null) + super._read(input); + else + value = Vio.read(input, helper); + } + + /** + * Set the read and write methods. + */ + void findHelper() + { + if (helper != null || helper_NA) + return; + try + { + Class helperClass = + ObjectCreator.forName(ObjectCreator.toHelperName(type.id())); + + helper = (BoxedValueHelper) helperClass.newInstance(); + } + catch (Exception ex) + { + helper_NA = true; + } + } +} diff --git a/libjava/classpath/gnu/CORBA/interfaces/SocketFactory.java b/libjava/classpath/gnu/CORBA/interfaces/SocketFactory.java new file mode 100644 index 000000000..d1d7d418b --- /dev/null +++ b/libjava/classpath/gnu/CORBA/interfaces/SocketFactory.java @@ -0,0 +1,95 @@ +/* SocketFactory.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.interfaces; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; + +/** + * This class produces sockets for serving and submitting CORBA requests. The + * socket factory can be set using {@link gnuOrb.setSocketFactory()} for + * producting all sockets for that ORB. This is needed for using secure sockets, + * for implementing the desired timeout policies, for HTTP tunnels and in some + * other similar cases. While such functionality is provided by near all + * existing CORBA implementations, no standard mechanism is defined. + * + * The socket factory may need to put additional information to the IORs of the + * objects, released by the ORB. Because of this reason, this interface extends + * IORInterceptorOperations. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface SocketFactory +{ + /** + * The name of the ORB property that forces the ORB to use the socket + * factory class, the name of that (String) is the value of this property. + */ + final String PROPERTY = "gnu.CORBA.SocketFactory"; + + /** + * Create a server socket that should serve remote invocations on the given + * port. The ORB may use this socket to serve either one or more objects. + * + * @param port the port, on that the socket should be listening for requests. + * The port policy can be controlled by {@link gnuPortManager}. + * + * @throws IOException if the socket cannot be created on the given port due + * any reasons. The ORB may try to open the socket on another port, calling + * this method with the different parameter. + */ + ServerSocket createServerSocket(int port) + throws IOException; + + /** + * Create a client socket that should send a request to the remote side. When + * returned, the socket should be opened and ready to communicate. + * + * @param port the port, on that the socket should be openend. The port is + * usually part of the internet profile. + * + * @throws IOException if the socket cannot be created on the given port due + * any reasons. The ORB may try to open the socket on another port, calling + * this method with the different parameter. + */ + Socket createClientSocket(String host, int port) + throws IOException; + +} diff --git a/libjava/classpath/gnu/CORBA/interfaces/package.html b/libjava/classpath/gnu/CORBA/interfaces/package.html new file mode 100644 index 000000000..101475b2d --- /dev/null +++ b/libjava/classpath/gnu/CORBA/interfaces/package.html @@ -0,0 +1,49 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - + 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. --> + +<html> +<head><title>GNU Classpath - gnu.CORBA.interfaces</title></head> + +<body> +<p>This package contains Classpath specific interfaces that +the user program may be forced to use in cases when no +other, better solution of the problem is available. The +existing classes and methods in this package should not +be removed without the real need</p> +</body> +</html> diff --git a/libjava/classpath/gnu/CORBA/typecodes/AliasTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/AliasTypeCode.java new file mode 100644 index 000000000..41d0fbe8a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/AliasTypeCode.java @@ -0,0 +1,148 @@ +/* AliasTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * The type code that is an alias of another type code. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class AliasTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The typecode repository id. + */ + protected final String id; + + /** + * The typecode name. + */ + protected final String name; + + /** + * The type code for that this typecode is an alias. + */ + protected final TypeCode aliasFor; + + /** + * Create the typecode, specifying for that typecode it is an + * alias and the id and name of the newly created typecode. + * + * @param an_aliasFor the typecode, for that this typecode is an + * alias. + * + * @param an_id the repository id fo the newly created typecode. + * + * @param a_name the name of the newly created typecode. + */ + public AliasTypeCode(TypeCode an_aliasFor, String an_id, String a_name) + { + super(TCKind.tk_alias); + aliasFor = an_aliasFor; + id = an_id; + name = a_name; + } + + /** + * Get the typecode, for that this typecode is an alias. + */ + public TypeCode content_type() + { + return aliasFor; + } + + /** + * The objects are assumed to be equal if they repository + * ids are both equal or both unavailable and the + * kind values are equal. + * + * @param other the other typecode to compare. + */ + public boolean equal(TypeCode other) + { + if (super.equal(other)) + return true; + try + { + return id.equals(other.id()); + } + catch (BadKind ex) + { + return false; + } + } + + /** + * Return true if the given typecode is equal for + * either this typecode of the alias typecode. + * + * @param other the typecode to compare. + */ + public boolean equivalent(TypeCode other) + { + return other.equal(this) || other.equal(aliasFor); + } + + /** + * Get the repository id of this typecode. + */ + public String id() + { + return id; + } + + /** + * Get the name of this typecode. + */ + public String name() + { + return name; + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/ArrayTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/ArrayTypeCode.java new file mode 100644 index 000000000..394efb36a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/ArrayTypeCode.java @@ -0,0 +1,272 @@ +/* ArrayTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * A TypeCode for arrays. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class ArrayTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + + /** + * The array components. + */ + TypeCode of; + + /** + * The length of the array, must be updated when setting + * a new value. + */ + private int length; + + /** + * 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 ArrayTypeCode(TCKind array_of) + { + super(TCKind.tk_sequence); + of = new PrimitiveTypeCode(array_of); + } + + /** + * 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. + */ + public ArrayTypeCode(TCKind this_type, TypeCode array_of) + { + super(this_type); + of = array_of; + } + + /** + * Return the array component type. + * @return the array component type + * @throws org.omg.CORBA.TypeCodePackage.BadKind + */ + public TypeCode content_type() + throws org.omg.CORBA.TypeCodePackage.BadKind + { + return of; + } + + /** + * Return true if the other TypeCode defines the array, having elements + * of the same type. The sizes of arrays are not taken into + * consideration. + * + * @param other the other TypeCode + * @return true if <code>other</code> is an array with the same + * component type. + */ + public boolean equal(TypeCode other) + { + try + { + return kind() == other.kind() && + content_type() == other.content_type(); + } + catch (BadKind ex) + { + // Should not be thrown. + return false; + } + } + + /** + * Returns the agreed Id in the form of + * <code>IDL:omg.org/CORBA/ {type name} Seq:1.0</code>. + * + * @return the Id of this TypeCode. + * + * @throws org.omg.CORBA.TypeCodePackage.BadKind if the content type + * is not one of the constants, defined in {@link TCKind}. + * This package class should not be used as TypeCode for the arrays, + * holding the user defined components. + */ + public String id() + throws org.omg.CORBA.TypeCodePackage.BadKind + { + switch (content_type().kind().value()) + { + case TCKind._tk_null : + return "IDL:omg.org/CORBA/NullSeq:1.0"; + + case TCKind._tk_void : + return "IDL:omg.org/CORBA/VoidSeq:1.0"; + + case TCKind._tk_short : + return "IDL:omg.org/CORBA/ShortSeq:1.0"; + + case TCKind._tk_long : + return "IDL:omg.org/CORBA/LongSeq:1.0"; + + case TCKind._tk_ushort : + return "IDL:omg.org/CORBA/UShortSeq:1.0"; + + case TCKind._tk_ulong : + return "IDL:omg.org/CORBA/ULongSeq:1.0"; + + case TCKind._tk_float : + return "IDL:omg.org/CORBA/FloatSeq:1.0"; + + case TCKind._tk_double : + return "IDL:omg.org/CORBA/DoubleSeq:1.0"; + + case TCKind._tk_boolean : + return "IDL:omg.org/CORBA/BooleanSeq:1.0"; + + case TCKind._tk_char : + return "IDL:omg.org/CORBA/CharSeq:1.0"; + + case TCKind._tk_octet : + return "IDL:omg.org/CORBA/OctetSeq:1.0"; + + case TCKind._tk_any : + return "IDL:omg.org/CORBA/AnySeq:1.0"; + + case TCKind._tk_TypeCode : + return "IDL:omg.org/CORBA/TypeCodeSeq:1.0"; + + case TCKind._tk_Principal : + return "IDL:omg.org/CORBA/PrincipalSeq:1.0"; + + case TCKind._tk_objref : + return "IDL:omg.org/CORBA/ObjrefSeq:1.0"; + + case TCKind._tk_struct : + return "IDL:omg.org/CORBA/StructSeq:1.0"; + + case TCKind._tk_union : + return "IDL:omg.org/CORBA/UnionSeq:1.0"; + + case TCKind._tk_enum : + return "IDL:omg.org/CORBA/EnumSeq:1.0"; + + case TCKind._tk_string : + return "IDL:omg.org/CORBA/StringSeq:1.0"; + + case TCKind._tk_sequence : + return "IDL:omg.org/CORBA/SequenceSeq:1.0"; + + case TCKind._tk_array : + return "IDL:omg.org/CORBA/ArraySeq:1.0"; + + case TCKind._tk_alias : + return "IDL:omg.org/CORBA/AliasSeq:1.0"; + + case TCKind._tk_except : + return "IDL:omg.org/CORBA/ExceptSeq:1.0"; + + case TCKind._tk_longlong : + return "IDL:omg.org/CORBA/LongLongSeq:1.0"; + + case TCKind._tk_ulonglong : + return "IDL:omg.org/CORBA/ULongLongSeq:1.0"; + + case TCKind._tk_longdouble : + return "IDL:omg.org/CORBA/LongDoubleSeq:1.0"; + + case TCKind._tk_wchar : + return "IDL:omg.org/CORBA/WCharSeq:1.0"; + + case TCKind._tk_wstring : + return "IDL:omg.org/CORBA/WStringSeq:1.0"; + + case TCKind._tk_fixed : + return "IDL:omg.org/CORBA/FixedSeq:1.0"; + + case TCKind._tk_value : + return "IDL:omg.org/CORBA/ValueSeq:1.0"; + + case TCKind._tk_value_box : + return "IDL:omg.org/CORBA/Value_boxSeq:1.0"; + + case TCKind._tk_native : + return "IDL:omg.org/CORBA/NativeSeq:1.0"; + + case TCKind._tk_abstract_interface : + return "IDL:omg.org/CORBA/Abstract_interfaceSeq:1.0"; + + default : + throw new BadKind(); + } + } + + /** + * Return the array length. + * @return the length of the array. + * @throws org.omg.CORBA.TypeCodePackage.BadKind + */ + public int length() + throws org.omg.CORBA.TypeCodePackage.BadKind + { + return length; + } + + /** + * Sets the array length to the supplied value. + * + * @param l the new length. + */ + public void setLength(int l) + { + this.length = l; + } + +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/FixedTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/FixedTypeCode.java new file mode 100644 index 000000000..9e9f3eff6 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/FixedTypeCode.java @@ -0,0 +1,152 @@ +/* FixedTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + + +import java.math.BigDecimal; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * A typecode for CORBA <code>fixed</code> + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class FixedTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + + /** + * The number of the used digits. + */ + private short digits; + + /** + * The number of the digits after the decimal point. + */ + private short scale; + + /** + * Creates the instance of the fixed type code. + */ + public FixedTypeCode() + { + super(TCKind.tk_fixed); + } + + /** + * Creates the instance of the fixed type code, + * setting the digits and scale by example. + */ + public FixedTypeCode(BigDecimal example) + { + super(TCKind.tk_fixed); + if (example != null) + { + setScale(example.scale()); + setDigits(countDigits(example)); + } + } + + /** + * Set the number of digits. + */ + public void setDigits(int a_digits) + { + this.digits = (short) a_digits; + } + + /** + * Set the number of digits after the decimal point. + */ + public void setScale(int a_scale) + { + this.scale = (short) a_scale; + } + + /** + * Get the number of digits in thid BigDecimal + * + * @param number a BigDecimal to check. + */ + public static int countDigits(BigDecimal number) + { + return number.unscaledValue().abs().toString().length(); + } + + /** + * Compare with other type code for equality. + */ + public boolean equal(TypeCode other) + { + if (other == this) return true; + try + { + TypeCode that = (TypeCode) other; + return kind() == that.kind() && digits == that.fixed_digits() && + scale == that.fixed_scale(); + } + catch (BadKind ex) + { + return false; + } + } + + /** + * Get the number of digits. + */ + public short fixed_digits() + { + return digits; + } + + /** + * Get the number of digits after the decimal point. + */ + public short fixed_scale() + { + return scale; + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/GeneralTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/GeneralTypeCode.java new file mode 100644 index 000000000..a00f69823 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/GeneralTypeCode.java @@ -0,0 +1,249 @@ +/* GeneralTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + +import gnu.CORBA.CDR.BufferedCdrOutput; + +import java.util.Arrays; +import java.util.BitSet; + +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; + +/** + * A typecode for types, requiring to provide various additional + * properties but still not requiring to store the + * members of the structure. The property can be retrieved + * by the corresponding method if it has been previously assigned. + * Otherwise, a {@link BadKind} is thrown. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class GeneralTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + + /** + * Indicates that the field value has not been previously set. + */ + protected static int UNSET = Integer.MIN_VALUE; + + /** + * The kinds for that the length() must return 0 even if it + * has not been previously set. + */ + private static final BitSet lengthAllowed = new BitSet(); + + static + { + lengthAllowed.set(TCKind._tk_array); + lengthAllowed.set(TCKind._tk_sequence); + lengthAllowed.set(TCKind._tk_string); + lengthAllowed.set(TCKind._tk_wstring); + } + + private String id; + private String name; + private TypeCode concrete_base_type; + private TypeCode content_type; + private int len; + private int type_modifier = UNSET; + + /** + * Create a new instance, setting kind to the given kind. + * @param a_kind the kind of the typecode being created. + */ + public GeneralTypeCode(TCKind a_kind) + { + super(a_kind); + if (!lengthAllowed.get(a_kind.value())) + len = UNSET; + } + + /** + * Set this property. + */ + public void setConcreteBase_type(TypeCode a_concrete_base_type) + { + this.concrete_base_type = a_concrete_base_type; + } + + /** + * Set the component content type. + */ + public void setContentType(TypeCode a_content_type) + { + this.content_type = a_content_type; + } + + /** + * Set this property. + */ + public void setId(String an_id) + { + this.id = an_id; + } + + /** + * Set the length property. + * @param l + */ + public void setLength(int l) + { + len = l; + } + + /** + * Set this property. + */ + public void setName(String a_name) + { + this.name = a_name; + } + + /** + * Set the type modifier. + */ + public void setTypeModifier(int a_type_modifier) + { + this.type_modifier = a_type_modifier; + } + + /** {@inheritDoc} */ + public TypeCode concrete_base_type() + throws BadKind + { + if (concrete_base_type != null) + return concrete_base_type; + throw new BadKind("concrete_base_type"); + } + + /** + * Returns the content type that must be explicitly set + * for this class. + * + * @throws BadKind if the content type has not been set. + */ + public TypeCode content_type() + throws BadKind + { + if (content_type != null) + return content_type; + throw new BadKind("content_type"); + } + + /** + * Returns true if both typecodes, if written into CDR + * stream, would result the same stream content. + */ + public boolean equal(TypeCode other) + { + if (this == other) + return true; + if (kind() != other.kind()) + return false; + + BufferedCdrOutput a = new BufferedCdrOutput(16); + BufferedCdrOutput b = new BufferedCdrOutput(16); + + a.write_TypeCode(this); + b.write_TypeCode(other); + + return Arrays.equals(a.buffer.toByteArray(), b.buffer.toByteArray()); + } + + /** + * Delegates functionality to {@link #equal}. + */ + public boolean equivalent(TypeCode other) + { + return equal(other); + } + + /** {@inheritDoc} */ + public String id() + throws BadKind + { + if (id != null) + return id; + throw new BadKind("id"); + } + + /** + * Get the length. For sequences, arrays, strings and wstrings + * this method returns 0 rather than throwing a BadKind even + * if {@link setLength(int)} has not been previously called. + * + * @return the length of string, array or sequence. + * + * @throws BadKind if the method cannot be invoked for the + * given kind of typecode. + */ + public int length() + throws BadKind + { + if (len != UNSET) + return len; + throw new BadKind("length"); + } + + /** {@inheritDoc} */ + public String name() + throws BadKind + { + if (name != null) + return name; + throw new BadKind("name"); + } + + /** {@inheritDoc} */ + public short type_modifier() + throws BadKind + { + if (type_modifier != UNSET) + return (short) type_modifier; + throw new BadKind("type_modifier"); + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/PrimitiveTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/PrimitiveTypeCode.java new file mode 100644 index 000000000..8f8ce3ea3 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/PrimitiveTypeCode.java @@ -0,0 +1,201 @@ +/* PrimitiveTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + + 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.typecodes; + +import java.io.Serializable; + +import org.omg.CORBA.Any; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.portable.IDLEntity; + +/** + * An information about a primitive CORBA data type + * (boolean, char, wchar, octet and also signed or unsigned short, long, + * long long, float and double). + * This class only implements the methods {@link #kind() } + * and {@link equal() } that are valid for + * all TypeCode kinds. Other methods are implemented in derived + * subclasses. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class PrimitiveTypeCode + extends TypeCode + implements IDLEntity, Serializable +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The kind of this TypeCode. + */ + protected final TCKind kind; + + public PrimitiveTypeCode(TCKind a_kind) + { + kind = a_kind; + } + + public TypeCode concrete_base_type() + throws BadKind + { + throw new BadKind(); + } + + public TypeCode content_type() + throws BadKind + { + throw new BadKind(); + } + + public int default_index() + throws BadKind + { + throw new BadKind(); + } + + public TypeCode discriminator_type() + throws BadKind + { + throw new BadKind(); + } + + /** + * Test two types for equality. The default implementation + * returs true of the types of the same kind. + * @param other the other type to compere with + * @return true if the types are interchangeable. + */ + public boolean equal(TypeCode other) + { + return kind() == other.kind(); + } + + public boolean equivalent(TypeCode parm1) + { + throw new NO_IMPLEMENT(); + } + + public short fixed_digits() + throws BadKind + { + throw new BadKind("fixed_digits"); + } + + public short fixed_scale() + throws BadKind + { + throw new BadKind("fixed_scale"); + } + + public TypeCode get_compact_typecode() + { + throw new NO_IMPLEMENT(); + } + + public String id() + throws BadKind + { + throw new BadKind("id"); + } + + /** + * Return the kind of this type code object. + * @return one of the <code>TCKind.t_..</code> fields. + */ + public TCKind kind() + { + return kind; + } + + public int length() + throws BadKind + { + throw new BadKind("length"); + } + + public int member_count() + throws BadKind + { + throw new BadKind("member_count"); + } + + public Any member_label(int index) + throws BadKind, Bounds + { + throw new BadKind("member_label"); + } + + public String member_name(int index) + throws BadKind, Bounds + { + throw new BadKind("member_name"); + } + + public TypeCode member_type(int index) + throws BadKind, Bounds + { + throw new BadKind("member_type"); + } + + public short member_visibility(int index) + throws BadKind, Bounds + { + throw new BadKind("member_visibility"); + } + + public String name() + throws BadKind + { + throw new BadKind("name"); + } + + public short type_modifier() + throws BadKind + { + throw new BadKind("type_modifier"); + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/RecordTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/RecordTypeCode.java new file mode 100644 index 000000000..8f13de9a9 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/RecordTypeCode.java @@ -0,0 +1,252 @@ +/* RecordTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + +import gnu.CORBA.CorbaList; + +import org.omg.CORBA.Any; +import org.omg.CORBA.StructMember; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.UnionMember; +import org.omg.CORBA.ValueMember; + +/** + * The type code that also has the member property getters + * supported. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class RecordTypeCode + extends GeneralTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The individual field of the record. + */ + public static class Field + { + /** + * The record label. + */ + public Any label; + + /** + * The record name. + */ + public String name; + + /** + * The record type. + */ + public TypeCode type; + + /** + * The record visibility. + */ + public int visibility = UNSET; + } + + /** + * The members of this data structure. + */ + protected CorbaList members = new CorbaList(); + private TypeCode discriminator_type; + private int default_index = UNSET; + + /** + * Creates the type code of the given kind. + */ + public RecordTypeCode(TCKind a_kind) + { + super(a_kind); + } + + /** + * Set the default index. + */ + public void setDefaultIndex(int a_default_index) + { + this.default_index = a_default_index; + } + + /** + * Set the discriminator type. + */ + public void setDiscriminator_type(TypeCode a_discriminator_type) + { + this.discriminator_type = a_discriminator_type; + } + + public Field getField(int p) + { + return (Field) members.get(p); + } + + public void add(Field field) + { + members.add(field); + } + + /** + * Adds a new field, taking values from the passed + * {@link StructMember}. + */ + public void add(StructMember m) + { + Field f = field(); + f.name = m.name; + f.type = m.type; + } + + /** + * Adds a new field, taking values from the passed + * {@link ValueMember}. + */ + public void add(ValueMember m) + { + Field f = field(); + f.name = m.name; + f.type = m.type; + f.visibility = m.access; + + } + + /** + * Adds a new field, taking values from the passed + * {@link UnionMember}. + */ + public void add(UnionMember m) + { + Field f = field(); + f.name = m.name; + f.type = m.type; + f.label = m.label; + } + + public int default_index() + throws BadKind + { + if (default_index != UNSET) + return default_index; + throw new BadKind(); + } + + public TypeCode discriminator_type() + throws BadKind + { + if (discriminator_type != null) + return discriminator_type; + throw new BadKind(); + } + + /** + * Creates, adds and returns new field. + */ + public Field field() + { + Field f = new Field(); + members.add(f); + return f; + } + + /** {@inheritDoc} */ + public int member_count() + { + return members.size(); + } + + /** {@inheritDoc} */ + public Any member_label(int index) + throws BadKind, Bounds + { + Field f = getField(index); + if (f.label != null) + { + return f.label; + } + else + throw new BadKind(); + } + + /** {@inheritDoc} */ + public String member_name(int index) + throws BadKind + { + Field f = getField(index); + if (f.name != null) + { + return f.name; + } + else + throw new BadKind(); + } + + /** {@inheritDoc} */ + public TypeCode member_type(int index) + throws BadKind, Bounds + { + Field f = getField(index); + if (f.type != null) + { + return f.type; + } + else + throw new BadKind(); + } + + /** {@inheritDoc} */ + public short member_visibility(int index) + throws BadKind, Bounds + { + Field f = getField(index); + if (f.visibility != UNSET) + { + return (short) f.visibility; + } + else + throw new BadKind(); + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/RecursiveTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/RecursiveTypeCode.java new file mode 100644 index 000000000..727773674 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/RecursiveTypeCode.java @@ -0,0 +1,84 @@ +/* RecursiveTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + + +import org.omg.CORBA.TCKind; + +/** + * The typecode, serving as a placeholder in defining + * typecodes, containing recursion. + */ +public class RecursiveTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The id of the type for that this type serves as a + * placeholder. + */ + private final String the_id; + + /** + * Create a typecode that serves as a placeholder for + * the typecode with the given id. + * + * @param an_id the Id of the type for that this type serves as a + * placeholder. + */ + public RecursiveTypeCode(String an_id) + { + super(TCKind.tk_null); + the_id = an_id; + } + + /** + * Get the id of the type for that this type serves as a + * placeholder. + */ + public String id() + throws org.omg.CORBA.TypeCodePackage.BadKind + { + return the_id; + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/StringTypeCode.java b/libjava/classpath/gnu/CORBA/typecodes/StringTypeCode.java new file mode 100644 index 000000000..7f463d7b0 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/StringTypeCode.java @@ -0,0 +1,89 @@ +/* StringTypeCode.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.typecodes; + + +import org.omg.CORBA.TCKind; + +/** + * The typecode for string and wide string. + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class StringTypeCode + extends PrimitiveTypeCode +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + private int len = 0; + + /** + * Create a new instance of the string type code. + * + * @param a_kind a kind of this typecode, normally + * either tk_string or tk_wstring. + */ + public StringTypeCode(TCKind a_kind) + { + super(a_kind); + } + + /** + * Set the length property. + * + * @param a_length a length. + */ + public void setLength(int a_length) + { + len = a_length; + } + + /** + * Get the length of the string. This method returns 0 + * (unbounded) if the property has not been set. + * + * @return the length (bound) of the string. + */ + public int length() + { + return len; + } +} diff --git a/libjava/classpath/gnu/CORBA/typecodes/package.html b/libjava/classpath/gnu/CORBA/typecodes/package.html new file mode 100644 index 000000000..891b3b965 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/typecodes/package.html @@ -0,0 +1,48 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html + 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. --> + +<html> +<head><title>GNU Classpath - gnu.CORBA.typecodes</title></head> + +<body> + Contains GNU Classpath specific typecode definitions. + + @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) +</body> +</html> + |