summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/CORBA/NamingService
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/CORBA/NamingService')
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/Binding_iterator_impl.java141
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/Ext.java232
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NameComponentComparator.java98
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NameParser.java527
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NameTransformer.java326
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NameValidator.java79
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NamingMap.java190
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/NamingServiceTransient.java146
-rw-r--r--libjava/classpath/gnu/CORBA/NamingService/TransientContext.java443
9 files changed, 2182 insertions, 0 deletions
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);
+ }
+}