123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825 |
- /* 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();
- }
- }
|