summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/javax/naming/giop
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/javax/naming/giop')
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/ContextContinuation.java956
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/CorbalocParser.java441
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/GiopNamingEnumeration.java187
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceFactory.java179
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceURLContext.java840
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/ListBindingsEnumeration.java118
-rw-r--r--libjava/classpath/gnu/javax/naming/giop/ListEnumeration.java118
7 files changed, 2839 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/naming/giop/ContextContinuation.java b/libjava/classpath/gnu/javax/naming/giop/ContextContinuation.java
new file mode 100644
index 000000000..e952393cc
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/ContextContinuation.java
@@ -0,0 +1,956 @@
+/* ContextContinuation.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import gnu.CORBA.NamingService.Ext;
+import gnu.CORBA.NamingService.NameTransformer;
+
+import java.util.Hashtable;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.directory.InvalidAttributesException;
+
+import org.omg.CORBA.ORB;
+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.NamingContextExt;
+import org.omg.CosNaming.NamingContextExtHelper;
+import org.omg.CosNaming.NamingContextHelper;
+import org.omg.CosNaming._NamingContextExtStub;
+import org.omg.CosNaming._NamingContextStub;
+import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
+import org.omg.CosNaming.NamingContextPackage.CannotProceed;
+import org.omg.CosNaming.NamingContextPackage.InvalidName;
+import org.omg.CosNaming.NamingContextPackage.NotFound;
+
+/**
+ * The context to represent the corba naming service. Being the naming service,
+ * the returned context supports creating the subcontexts, forwarding this task
+ * to the existing naming service. When listing bindings, it uses the
+ * {@link Context#BATCHSIZE} property to determine, how many bindings should
+ * be returned at once (the process is transparend)
+ *
+ * @author Audrius Meskauskas (audriusa@Bioinformatics.org)
+ */
+public class ContextContinuation implements Context
+{
+ /**
+ * This number of bindings will be requested from the naming server at once,
+ * while the subsequent bindings will be requested via binding iterator one by
+ * one. Use {@link Context#BATCHSIZE} to override the value of this constant.
+ */
+ public int DEFAULT_BATCH_SIZE = 20;
+
+ /**
+ * The actual CORBA naming service.
+ */
+ NamingContextExt service;
+
+ /**
+ * The object request broker, used to access the naming service. This field
+ * is only initialised when the context is constructed from the URL.
+ */
+ ORB orb;
+
+ /**
+ * The properties.
+ */
+ Hashtable properties;
+
+ /**
+ * The parent factory.
+ */
+ GiopNamingServiceFactory factory;
+
+ /**
+ * The name transformer to obtain the name from its string representation. The
+ * to_name method of the naming service is avoided as it may be remote and
+ * hence expensive. The conversion rules are standard and cannot be service
+ * specific.
+ */
+ static NameTransformer transformer = new NameTransformer();
+
+ /**
+ * The batch size for list operations - how many to return at once.
+ */
+ public final int howMany;
+
+ /**
+ * Creates a new naming context that uses naming service, represented by the
+ * given CORBA object.
+ *
+ * @param nsObject
+ * the naming service object. It must be possible to narrow it into
+ * the NamingContextExt.
+ * @param props
+ * the environment table.
+ * @param anOrb
+ * the associated ORB. This reference is used during cleanup.
+ * @param aFactory
+ * parent factory. This reference is used during cleanup.
+ */
+ public ContextContinuation(org.omg.CORBA.Object nsObject,
+ Hashtable props, ORB anOrb,
+ GiopNamingServiceFactory aFactory)
+ {
+ factory = aFactory;
+ orb = anOrb;
+
+ Delegate delegate = ((ObjectImpl) nsObject)._get_delegate();
+
+ // If the IOR provides the IDL ID, we can check if our name
+ // service is old NamingContext or new NamingContextExt.
+ // Not all forms of the URL always provide the IDL id.
+ if (!nsObject._is_a(NamingContextExtHelper.id())
+ && nsObject._is_a(NamingContextHelper.id()))
+ {
+ // We are surely working with the old version.
+ _NamingContextStub stub = new _NamingContextStub();
+ stub._set_delegate(delegate);
+ // The Ext object will add the necessary extensions.
+ service = new Ext(stub);
+ }
+ else
+ {
+ // We expecte the service to be the NamingContextExt (this is true
+ // for both Sun's and our implementations). There is no easy way
+ // to check the version.
+ _NamingContextExtStub stub = new _NamingContextExtStub();
+ stub._set_delegate(delegate);
+ service = stub;
+ }
+ properties = props;
+ howMany = getBatchSize();
+ }
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object. The components of the name are
+ * mapped into the components of the CORBA name.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws NameAlreadyBoundException
+ * if this name is already used to name some object.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void bind(Name name, Object obj) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ service.bind(toGiop(name), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws NameAlreadyBoundException
+ * if this name is already used to name some object.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void bind(String name, Object obj) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ service.bind(transformer.toName(name), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Releases all resources, associated with this context. The close() method
+ * can be called several times, but after it has been once invoked, it is not
+ * allowed to call any other method of this context. This method destroys
+ * the ORB, if we have one.
+ *
+ * @throws NamingException
+ */
+ public void close() throws NamingException
+ {
+ if (orb != null && factory !=null)
+ {
+ factory.checkIfReferenced(orb);
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public Name composeName(Name name, Name prefix) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Not supported
+ */
+ public String composeName(String name1, String name2) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context. The returned object will wrap around the newly created CORBA
+ * subcontext
+ *
+ * @param subContext
+ * the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException
+ * if this name is already bound
+ * @throws InvalidAttributesException
+ * if the creation of the new context requires the missing mandatory
+ * attributes
+ * @throws NamingException
+ */
+ public Context createSubcontext(Name subContext) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object subcontext = service.bind_new_context(
+ toGiop(subContext));
+ Hashtable clonedProps = new Hashtable();
+ clonedProps.putAll(properties);
+
+ // Nulls are passed both for orb and factory, as the child contexts
+ // need not to do any cleanup.
+ return new ContextContinuation(subcontext, clonedProps, null, null);
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException();
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception ex)
+ {
+ throw new NamingException(ex.toString());
+ }
+ }
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context. The returned object will wrap around the newly created CORBA
+ * subcontext
+ *
+ * @param subContext
+ * the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException
+ * if this name is already bound
+ * @throws InvalidAttributesException
+ * if the creation of the new context requires the missing mandatory
+ * attributes
+ * @throws NamingException
+ */
+ public Context createSubcontext(String subContext) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object subcontext =
+ service.bind_new_context(transformer.toName(subContext));
+ Hashtable clonedProps = new Hashtable();
+ clonedProps.putAll(properties);
+
+ // Nulls are passed both for orb and factory, as the child contexts
+ // need not to do any cleanup.
+ return new ContextContinuation(subcontext, clonedProps, null,
+ null);
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException(subContext);
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException(subContext);
+ }
+ catch (Exception ex)
+ {
+ throw new NamingException(ex.toString());
+ }
+ }
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param subContext
+ * the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException
+ * if the named context is not empty.
+ * @throws NamingException
+ */
+ public void destroySubcontext(Name subContext) throws NamingException
+ {
+ unbind(subContext);
+ }
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param subContext
+ * the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException
+ * if the named context is not empty.
+ * @throws NamingException
+ */
+ public void destroySubcontext(String subContext) throws NamingException
+ {
+ unbind(subContext);
+ }
+
+ /**
+ * Returs the full name of this naming context. The returned string is not a
+ * JNDI composite name and should not be passed directly to the methods of the
+ * naming context. This implementation returns the IOR.
+ *
+ * @return the full name of this naming context, in its own namespace.
+ * @throws OperationNotSupportedException
+ * if the naming system, represented by this context, does not
+ * support the notation of the full name.
+ * @throws NamingException
+ */
+ public String getNameInNamespace() throws NamingException
+ {
+ if (orb != null)
+ return orb.object_to_string(service);
+ else
+ {
+ try
+ {
+ ObjectImpl impl = (ObjectImpl) service;
+ return impl._orb().object_to_string(impl);
+ }
+ catch (ClassCastException e)
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public NameParser getNameParser(Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not supported.
+ */
+ public NameParser getNameParser(String name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration list(Name name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ if (name.size() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve(toGiop(name))));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListEnumeration(bl, bi, howMany);
+ }
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration list(String name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ if (name.length() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve_str(name)));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListEnumeration(bl, bi, howMany);
+ }
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration listBindings(Name name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ if (name.size() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve(toGiop(name))));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListBindingsEnumeration(bl, bi, howMany, subcontext);
+ }
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration listBindings(String name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ if (name.length() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve_str(name)));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListBindingsEnumeration(bl, bi, howMany, subcontext);
+ }
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name
+ * the name of the object being searched in this context
+ * @return the named object
+ * @throws NameNotFountException
+ * if the name is not found
+ */
+ public Object lookup(Name name) throws NamingException
+ {
+ try
+ {
+ return service.resolve(toGiop(name));
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException();
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name
+ * the name of the object being searched in this context
+ * @return the named object
+ * @throws NamingException
+ * if the naming fails.
+ */
+ public Object lookup(String name) throws NamingException
+ {
+ try
+ {
+ return service.resolve_str(name);
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException();
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public Object lookupLink(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Not supported.
+ */
+ public Object lookupLink(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rebind(Name name, Object obj) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ service.rebind(toGiop(name), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rebind(String name, Object obj) throws NamingException
+ {
+ try
+ {
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ service.rebind(transformer.toName(name), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName
+ * the existing name of the known object
+ * @param newName
+ * the new name of the same object
+ * @throws NameNotFoundException
+ * if the oldName is unknown for this context
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rename(Name oldName, Name newName) throws NamingException
+ {
+ Object object = lookup(oldName);
+ unbind(oldName);
+ bind(newName, object);
+ }
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName
+ * the existing name of the known object
+ * @param newName
+ * the new name of the same object
+ * @throws NameNotFoundException
+ * if the oldName is unknown for this context
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rename(String oldName, String newName) throws NamingException
+ {
+ Object object = lookup(oldName);
+ unbind(oldName);
+ bind(newName, object);
+ }
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name
+ * the name to be removed
+ * @throws NameNotFoundException
+ * if one of the intermediate naming contexts does not exist. Will
+ * not be thrown if just the terminal binding is missing.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void unbind(Name name) throws NamingException
+ {
+ try
+ {
+ service.unbind(toGiop(name));
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException();
+ }
+ catch (CannotProceed e)
+ {
+ throw new ContextNotEmptyException();
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ }
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name
+ * the name to be removed
+ * @throws NameNotFoundException
+ * if one of the intermediate naming contexts does not exist. Will
+ * not be thrown if just the terminal binding is missing.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void unbind(String name) throws NamingException
+ {
+ try
+ {
+ service.unbind(transformer.toName(name));
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException(name);
+ }
+ catch (CannotProceed e)
+ {
+ throw new ContextNotEmptyException(name);
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException(name);
+ }
+ }
+
+ /**
+ * Add new environment property to the environment of this context. Both name
+ * and value of the new property must not be null. If the property is already
+ * defined, is current value is replaced by the propVal.
+ *
+ * @param key
+ * the name of the new property
+ * @param value
+ * the value of the new property
+ * @return the previous value of this property or null if the property has not
+ * been previously defined
+ * @throws NamingException
+ */
+ public Object addToEnvironment(String key, Object value)
+ throws NamingException
+ {
+ if (key == null || value == null)
+ throw new NullPointerException();
+ return properties.put(key, value);
+ }
+
+ /**
+ * Returns the environment, associated with this naming context. The returned
+ * table should never be modified by the caller. Use {@link #addToEnvironment}
+ * and {@link #removeFromEnvironment} to modify the environement, if needed.
+ *
+ * @return the table, representing the environment of this context
+ * @throws NamingException
+ */
+ public Hashtable getEnvironment() throws NamingException
+ {
+ return properties;
+ }
+
+ /**
+ * Removes the property with the given name from the environment. Returns
+ * without action if this property is not defined.
+ *
+ * @param propName
+ * the name of the property being removed.
+ * @return the value of the property that has been removed or null if the
+ * property was not defined.
+ * @throws NamingException
+ */
+ public Object removeFromEnvironment(String propName) throws NamingException
+ {
+ return properties.remove(propName);
+ }
+
+ /**
+ * Convert the {@link Name} into array of the name components, required to the
+ * CORBA naming service. First the string representation is obtained, then
+ * it is converted using parsing rules of the CORBA name.
+ *
+ * @param name
+ * then name to convert
+ * @return the converted array of components.
+ */
+ public NameComponent[] toGiop(Name name) throws InvalidName
+ {
+ return transformer.toName(name.toString());
+ }
+
+ /**
+ * Get the batch size from the environment properties. The batch size is used
+ * for listing operations.
+ *
+ * @return the batch size, or some default value if not specified.
+ */
+ public int getBatchSize()
+ {
+ int batchSize = DEFAULT_BATCH_SIZE;
+ Object bs = properties.get(Context.BATCHSIZE);
+ if (bs != null)
+ {
+ try
+ {
+ int b = Integer.parseInt(bs.toString());
+ if (b >= 0)
+ batchSize = b;
+ }
+ catch (NumberFormatException e)
+ {
+ // OK, use default value.
+ }
+ }
+ return batchSize;
+ }
+
+
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/CorbalocParser.java b/libjava/classpath/gnu/javax/naming/giop/CorbalocParser.java
new file mode 100644
index 000000000..4b7883969
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/CorbalocParser.java
@@ -0,0 +1,441 @@
+/* CorbalocParser.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import gnu.CORBA.IOR;
+import gnu.CORBA.Minor;
+import gnu.CORBA.Unexpected;
+import gnu.CORBA.Version;
+import gnu.CORBA.NamingService.NameTransformer;
+
+import gnu.java.lang.CPStringBuilder;
+
+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;
+
+import javax.naming.InvalidNameException;
+
+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;
+
+/**
+ * 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 (AudriusA@Bioinformatics.org)
+ */
+public class CorbalocParser
+ 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 arrey of strings, first member being the IOR of the
+ * naming service, second member the name in the naming service.
+ */
+ public synchronized String[] corbaloc(String corbaloc,
+ ORB orb)
+ throws InvalidNameException
+ {
+ return corbaloc(corbaloc, orb, 0);
+ }
+
+ /**
+ * Parse controlling against the infinite recursion loop.
+ */
+ private String[] corbaloc(String corbaloc,
+ ORB orb, int recursion) throws InvalidNameException
+ {
+ // 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);
+
+ // 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))
+ throw new InvalidNameException(corbaloc+" must start with "+pxCORBANAME);
+
+ 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 resolve(orb.object_to_string(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();
+
+ return resolve(ior.toStringifiedReference());
+ }
+
+ else
+ throw new InvalidNameException("Unsupported protocol '" + t[p] +
+ "' (iiop expected)");
+ }
+
+ /**
+ * 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 String[] resolve(String nsIor)
+ {
+ String [] n = new String[2];
+ n[0] = nsIor;
+ n[1] = readKey("#");
+ return n;
+ }
+
+ 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);
+ }
+ }
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/GiopNamingEnumeration.java b/libjava/classpath/gnu/javax/naming/giop/GiopNamingEnumeration.java
new file mode 100644
index 000000000..c2de75b38
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/GiopNamingEnumeration.java
@@ -0,0 +1,187 @@
+/* GiopNamingEnumeration.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import java.util.NoSuchElementException;
+
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+import org.omg.CosNaming.Binding;
+import org.omg.CosNaming.BindingIterator;
+import org.omg.CosNaming.BindingIteratorHolder;
+import org.omg.CosNaming.BindingListHolder;
+
+/**
+ * Iterates over name class pairs, obtaining values first from the binding list
+ * and then from the binding iterator.
+ *
+ * @author Audrius Meskauskas
+ */
+public abstract class GiopNamingEnumeration implements NamingEnumeration
+{
+ /**
+ * The array of bindings, returned at once.
+ */
+ Binding[] list;
+
+ /**
+ * The binding iterator to obtain the subsequent bindings. May be null,
+ * if all values are stored in the <code>list</code>.
+ */
+ BindingIterator iterator;
+
+ /**
+ * The batch size.
+ */
+ int batch;
+
+ /**
+ * The position of the element in the binding list, that must be returned
+ * during the subsequent call of the next(). If this field is grater or equal
+ * to the lenght of the list, the subsequent values must be requested from the
+ * iterator.
+ */
+ int p;
+
+ GiopNamingEnumeration(BindingListHolder bh, BindingIteratorHolder bih, int batchSize)
+ {
+ list = bh.value;
+ iterator = bih.value;
+ batch = batchSize;
+ }
+
+ /**
+ * Convert from the CORBA binding into that this enumeration should return.
+ *
+ * @param binding
+ * the binding to convert
+ * @return the value, that must be returned by the {@link #next()}.
+ */
+ public abstract Object convert(Binding binding);
+
+ public void close() throws NamingException
+ {
+ if (iterator != null)
+ {
+ iterator.destroy();
+ iterator = null;
+ }
+ }
+
+ /**
+ * Checks if there are more elements to return.
+ *
+ * @throws NamingException
+ * never
+ */
+ public boolean hasMore() throws NamingException
+ {
+ return hasMoreElements();
+ }
+
+ /**
+ * Returns the next element.
+ *
+ * @throws NamingException
+ * never
+ */
+ public Object next() throws NamingException
+ {
+ return nextElement();
+ }
+
+ /**
+ * Checks if there are more elements to return.
+ */
+ public boolean hasMoreElements()
+ {
+ if (p < 0)
+ return false;
+ else if (p < list.length)
+ return true;
+ else
+ return getMore();
+ }
+
+ /**
+ * Returns the next element.
+ */
+ public Object nextElement()
+ {
+ if (p < 0)
+ throw new NoSuchElementException();
+ else if (p < list.length)
+ return convert(list[p++]);
+ else if (getMore())
+ // getMore updates p
+ return convert(list[p++]);
+ else
+ throw new NoSuchElementException();
+ }
+
+ /**
+ * Tries to obtain more elements, return true on success. Updates the fields
+ * accordingly.
+ */
+ boolean getMore()
+ {
+ if (iterator != null)
+ {
+ BindingListHolder holder = new BindingListHolder();
+ boolean rt = iterator.next_n(batch, holder);
+ if (rt)
+ {
+ // The new pack of the bindings arrived.
+ p = 0;
+ list = holder.value;
+ return true;
+ }
+ else
+ {
+ iterator.destroy();
+ iterator = null;
+ p = -1;
+ return false;
+ }
+ }
+ else
+ return false;
+ }
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceFactory.java b/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceFactory.java
new file mode 100644
index 000000000..e8aac3b65
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceFactory.java
@@ -0,0 +1,179 @@
+/* GiopNamingServiceFactory.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import gnu.CORBA.OrbFunctional;
+
+import gnu.java.lang.CPStringBuilder;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+import javax.naming.Context;
+import javax.naming.Name;
+
+import org.omg.CORBA.ORB;
+
+/**
+ * The context factory to represent the corbaname: style urls. Such URL states
+ * that the CORBA naming service exists on the given host. This service can
+ * return the required object, finding it by the given name. The names are
+ * parsed using the specification of the corbaname urls. Being the naming
+ * service, the returned context supports creating the subcontexts, forwarding
+ * this task to the existing naming service.
+ *
+ * @author Audrius Meskauskas (audriusa@Bioinformatics.org)
+ */
+public class GiopNamingServiceFactory
+{
+ /**
+ * The default naming service provider. It is assumed, that the naming service
+ * is running on the port 900 of the local host, using the GIOP version 1.2
+ */
+ public static final String DEFAULT_PROVIDER =
+ "corbaloc:iiop:1.2@127.0.0.1:900/NameService";
+
+ /**
+ * The table of all instantiated ORB's that are found by they ORB
+ * properties signatures. If all ORB related properties are the same,
+ * the ORB's are shared.
+ */
+ public static Hashtable orbs = new Hashtable();
+
+
+ /**
+ * Create a new instance of the corbaname URL context.
+ */
+ public Object getObjectInstance(Object refObj, Name name, Context nameCtx,
+ Hashtable environment)
+ {
+ String provider = (String) environment.get(Context.PROVIDER_URL);
+ if (provider == null)
+ provider = DEFAULT_PROVIDER;
+
+ String orbSignature = getOrbSignature(environment);
+
+ ORB orb;
+ synchronized (orbs)
+ {
+ orb = (ORB) orbs.get(orbSignature);
+ if (orb == null)
+ {
+ Properties props = new Properties();
+ props.putAll(environment);
+ orb = ORB.init(new String[0], props);
+ orbs.put(orbSignature, orb);
+ final ORB runIt = orb;
+ new Thread()
+ {
+ public void run()
+ {
+ runIt.run();
+ }
+ }.start();
+ }
+ }
+
+ return new GiopNamingServiceURLContext(environment, this, orb);
+ }
+
+ /**
+ * Check if this ORB is still in use (maybe it is time to shutdown it). This
+ * method only works when the Classpath CORBA implementation is used
+ * (otherwise it return without action). The method is called from the close()
+ * method of the created context.
+ *
+ * @param orb
+ * the ORB that maybe is no longer referenced.
+ */
+ public void checkIfReferenced(ORB orb)
+ {
+ synchronized (orbs)
+ {
+ // We can only do this with the Classpath implementation.
+ if (orb instanceof OrbFunctional)
+ {
+ OrbFunctional cOrb = (OrbFunctional) orb;
+ // If there are no connected objects, we can destroy the orb.
+ if (cOrb.countConnectedObjects() == 0)
+ {
+ cOrb.shutdown(false);
+ cOrb.destroy();
+
+ Enumeration keys = orbs.keys();
+ Object key;
+ Remove: while (keys.hasMoreElements())
+ {
+ key = keys.nextElement();
+ if (orbs.get(key) == orb)
+ {
+ orbs.remove(key);
+ break Remove;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Get all properties.
+ */
+ public String getOrbSignature(Map props)
+ {
+ TreeMap map = new TreeMap();
+ map.putAll(props);
+ CPStringBuilder b = new CPStringBuilder(50*props.size());
+
+ Iterator iter = map.entrySet().iterator();
+ Map.Entry m;
+ while (iter.hasNext())
+ {
+ m = (Map.Entry) iter.next();
+ b.append(m.getKey());
+ b.append('=');
+ b.append(m.getValue());
+ }
+ return b.toString();
+ }
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceURLContext.java b/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceURLContext.java
new file mode 100644
index 000000000..0d2e290b4
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/GiopNamingServiceURLContext.java
@@ -0,0 +1,840 @@
+/* GiopNamingServiceURLContext.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import gnu.CORBA.NamingService.Ext;
+import gnu.CORBA.NamingService.NameTransformer;
+
+import java.util.Hashtable;
+
+import javax.naming.Binding;
+import javax.naming.Context;
+import javax.naming.ContextNotEmptyException;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.directory.InvalidAttributesException;
+
+import org.omg.CORBA.ORB;
+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.NamingContextExt;
+import org.omg.CosNaming.NamingContextExtHelper;
+import org.omg.CosNaming.NamingContextHelper;
+import org.omg.CosNaming._NamingContextExtStub;
+import org.omg.CosNaming._NamingContextStub;
+import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
+import org.omg.CosNaming.NamingContextPackage.CannotProceed;
+import org.omg.CosNaming.NamingContextPackage.InvalidName;
+import org.omg.CosNaming.NamingContextPackage.NotFound;
+
+/**
+ * The context to represent the corba naming service. Being the naming service,
+ * the returned context supports creating the subcontexts, forwarding this task
+ * to the existing naming service. When listing bindings, it uses the
+ * {@link Context#BATCHSIZE} property to determine, how many bindings should
+ * be returned at once (the process is transparend)
+ *
+ * @author Audrius Meskauskas (audriusa@Bioinformatics.org)
+ */
+public class GiopNamingServiceURLContext extends CorbalocParser implements
+ Context
+{
+ /**
+ * This number of bindings will be requested from the naming server at once,
+ * while the subsequent bindings will be requested via binding iterator one by
+ * one. Use {@link Context#BATCHSIZE} to override the value of this constant.
+ */
+ public int DEFAULT_BATCH_SIZE = 20;
+
+ /**
+ * The object request broker, used to access the naming service. This field
+ * is only initialised when the context is constructed from the URL.
+ */
+ ORB orb;
+
+ /**
+ * The properties.
+ */
+ Hashtable properties;
+
+ /**
+ * The parent factory.
+ */
+ GiopNamingServiceFactory factory;
+
+ /**
+ * The name transformer to obtain the name from its string representation. The
+ * to_name method of the naming service is avoided as it may be remote and
+ * hence expensive. The conversion rules are standard and cannot be service
+ * specific.
+ */
+ static NameTransformer transformer = new NameTransformer();
+
+ /**
+ * The batch size for list operations - how many to return at once.
+ */
+ public final int howMany;
+
+ /**
+ * Creates a new naming context that uses naming service, represented by the
+ * given CORBA object.
+ *
+ * @param props
+ * the environment table.
+ * @param aFactory
+ * parent factory. This reference is used during cleanup.
+ * @param anOrb
+ * the associated ORB. This reference is used during cleanup.
+ */
+ public GiopNamingServiceURLContext(Hashtable props,
+ GiopNamingServiceFactory aFactory,
+ ORB anOrb)
+ {
+ factory = aFactory;
+ orb = anOrb;
+
+ properties = props;
+ howMany = getBatchSize();
+ }
+
+ public NamingContextExt getService(String address)
+ {
+ org.omg.CORBA.Object nsObject = orb.string_to_object(address);
+ Delegate delegate = ((ObjectImpl) nsObject)._get_delegate();
+
+ // If the IOR provides the IDL ID, we can check if our name
+ // service is old NamingContext or new NamingContextExt.
+ // Not all forms of the URL always provide the IDL id.
+ if (!nsObject._is_a(NamingContextExtHelper.id())
+ && nsObject._is_a(NamingContextHelper.id()))
+ {
+ // We are surely working with the old version.
+ _NamingContextStub stub = new _NamingContextStub();
+ stub._set_delegate(delegate);
+ // The Ext object will add the necessary extensions.
+ return new Ext(stub);
+ }
+ else
+ {
+ // We expecte the service to be the NamingContextExt (this is true
+ // for both Sun's and our implementations). There is no easy way
+ // to check the version.
+ _NamingContextExtStub stub = new _NamingContextExtStub();
+ stub._set_delegate(delegate);
+ return stub;
+ }
+ }
+
+ /**
+ * Split the corbaname name into the address of the naming service (first
+ * part) and the name of the object in the naming service (second part)
+ */
+ public String[] split(String corbaloc) throws InvalidNameException
+ {
+ if (corbaloc.endsWith("#"))
+ corbaloc = corbaloc.substring(0, corbaloc.length() - 1);
+
+ // No name part - parse as corbaname.
+ if (corbaloc.indexOf('#') < 0)
+ {
+ if (!corbaloc.regionMatches(true, 0, pxCORBANAME, 0,
+ pxCORBANAME.length()))
+ throw new InvalidNameException(corbaloc + " must start with "
+ + pxCORBANAME);
+ corbaloc = pxCORBALOC + corbaloc.substring(pxCORBANAME.length());
+ return new String[] { corbaloc, "" };
+ }
+
+ return corbaloc(corbaloc, orb);
+ }
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object. The components of the name are
+ * mapped into the components of the CORBA name.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws NameAlreadyBoundException
+ * if this name is already used to name some object.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void bind(Name name, Object obj) throws NamingException
+ {
+ bind(name.toString(), obj);
+ }
+
+ /**
+ * Give the specified name for the specified object. The passed name must not
+ * be already bound to some other object.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws NameAlreadyBoundException
+ * if this name is already used to name some object.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void bind(String name, Object obj) throws NamingException
+ {
+ try
+ {
+ String[] n = split(name);
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ getService(n[0]).bind(transformer.toName(n[1]), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Releases all resources, associated with this context. The close() method
+ * can be called several times, but after it has been once invoked, it is not
+ * allowed to call any other method of this context. This method destroys
+ * the ORB, if we have one.
+ *
+ * @throws NamingException
+ */
+ public void close() throws NamingException
+ {
+ if (orb != null && factory != null)
+ {
+ factory.checkIfReferenced(orb);
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public Name composeName(Name name, Name prefix) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Not supported
+ */
+ public String composeName(String name1, String name2) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context. The returned object will wrap around the newly created CORBA
+ * subcontext
+ *
+ * @param subContext
+ * the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException
+ * if this name is already bound
+ * @throws InvalidAttributesException
+ * if the creation of the new context requires the missing mandatory
+ * attributes
+ * @throws NamingException
+ */
+ public Context createSubcontext(Name subContext) throws NamingException
+ {
+ return createSubcontext(subContext.toString());
+ }
+
+ /**
+ * Creates the new naming subcontext and binds it to the current (this)
+ * context. The returned object will wrap around the newly created CORBA
+ * subcontext
+ *
+ * @param subContext
+ * the name of the new context being created
+ * @return the newly created context, bound to the instance of the context on
+ * that the method has been called
+ * @throws NameAlreadyBoundException
+ * if this name is already bound
+ * @throws InvalidAttributesException
+ * if the creation of the new context requires the missing mandatory
+ * attributes
+ * @throws NamingException
+ */
+ public Context createSubcontext(String subContext) throws NamingException
+ {
+ try
+ {
+ String[] n = split(subContext);
+ org.omg.CORBA.Object subcontext = getService(n[0]).bind_new_context(
+ transformer.toName(n[1]));
+ Hashtable clonedProps = new Hashtable();
+ clonedProps.putAll(properties);
+
+ // Nulls are passed both for orb and factory, as the child contexts
+ // need not to do any cleanup.
+ return new ContextContinuation(subcontext, clonedProps, null, null);
+ }
+ catch (AlreadyBound e)
+ {
+ throw new NameAlreadyBoundException(subContext);
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException(subContext);
+ }
+ catch (Exception ex)
+ {
+ throw new NamingException(ex.toString());
+ }
+ }
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param subContext
+ * the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException
+ * if the named context is not empty.
+ * @throws NamingException
+ */
+ public void destroySubcontext(Name subContext) throws NamingException
+ {
+ unbind(subContext);
+ }
+
+ /**
+ * Removes the naming subcontext from this naming context. Returns without
+ * action if such subcontext does not exist. The context being destroyed must
+ * be empty.
+ *
+ * @param subContext
+ * the name of the subcontext beig removed.
+ * @throws ContextNotEmptyException
+ * if the named context is not empty.
+ * @throws NamingException
+ */
+ public void destroySubcontext(String subContext) throws NamingException
+ {
+ unbind(subContext);
+ }
+
+ /**
+ * Returs the empty string.
+ */
+ public String getNameInNamespace() throws NamingException
+ {
+ return "";
+ }
+
+ /**
+ * Not supported.
+ */
+ public NameParser getNameParser(Name name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not supported.
+ */
+ public NameParser getNameParser(String name) throws NamingException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration list(Name name) throws NamingException
+ {
+ return list(name.toString());
+ }
+
+ /**
+ * Creates and returns the enumeration over the name bindings that are present
+ * the given subcontext. The enumeration elements have the type of
+ * {@link NameClassPair}, providing also information about the class of the
+ * bound object. The behaviour in the case if the bindings are added or
+ * removed later is not defined. The contents of the subcontexts are not
+ * included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration list(String name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ String [] n = split(name);
+ NamingContextExt service = getService(n[0]);
+
+ if (n[1].length() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve_str(n[1])));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListEnumeration(bl, bi, howMany);
+ }
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration listBindings(Name name) throws NamingException
+ {
+ return listBindings(name.toString());
+ }
+
+ /**
+ * Creates and returns the enumeration over the name - object bindings that
+ * are present the given subcontext. The enumeration elements have the type of
+ * {@link Binding}, providing also information about the class of the bound
+ * object. The behaviour in the case if the bindings are added or removed
+ * later is not defined. The contents of the subcontexts are not included.
+ *
+ * @param name
+ * the name of the subcontext
+ * @return the enumeration over the names, known for the given subcontext.
+ * @throws NamingException
+ */
+ public NamingEnumeration listBindings(String name) throws NamingException
+ {
+ BindingIteratorHolder bi = new BindingIteratorHolder();
+ BindingListHolder bl = new BindingListHolder();
+
+ NamingContext subcontext;
+
+ String [] n = split(name);
+ NamingContextExt service = getService(n[0]);
+
+ if (n[1].length() == 0)
+ subcontext = service;
+ else
+ {
+ try
+ {
+ subcontext = (NamingContextHelper.narrow(service.resolve_str(n[1])));
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+
+ }
+
+ subcontext.list(howMany, bl, bi);
+
+ return new ListBindingsEnumeration(bl, bi, howMany, subcontext);
+ }
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name
+ * the name of the object being searched in this context
+ * @return the named object
+ * @throws NameNotFoundException
+ * if the name is not found
+ */
+ public Object lookup(Name name) throws NamingException
+ {
+ return lookup(name.toString());
+ }
+
+ /**
+ * Gets the previously named object by name. If the passed name is empty, the
+ * method should return a cloned instance of this naming context.
+ *
+ * @param name
+ * the name of the object being searched in this context
+ * @return the named object
+ * @throws NamingException
+ * if the naming fails.
+ */
+ public Object lookup(String name) throws NamingException
+ {
+ try
+ {
+ String [] n = split(name);
+ NamingContextExt service = getService(n[0]);
+ return service.resolve_str(n[1]);
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException();
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Not supported.
+ */
+ public Object lookupLink(Name name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Not supported.
+ */
+ public Object lookupLink(String name) throws NamingException
+ {
+ throw new OperationNotSupportedException();
+ }
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rebind(Name name, Object obj) throws NamingException
+ {
+ rebind(name.toString(), obj);
+ }
+
+ /**
+ * Give the specified name for the specified object. Unlike bind, this method
+ * silently replaces the existing binding for this name, if one exists.
+ *
+ * @param name
+ * the name that will be given to the object (in the scope of this
+ * context).
+ * @param obj
+ * the object being named.
+ * @throws InvalidAttributesException
+ * if the object does not supply all required attributes.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rebind(String name, Object obj) throws NamingException
+ {
+ try
+ {
+ String[] n = split(name);
+ NamingContextExt service = getService(n[0]);
+
+ org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj;
+ service.rebind(transformer.toName(n[1]), object);
+ }
+ catch (ClassCastException e)
+ {
+ throw new NamingException(org.omg.CORBA.Object.class + " required ");
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException();
+ }
+ catch (Exception e)
+ {
+ throw new NamingException(e.toString());
+ }
+ }
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName
+ * the existing name of the known object
+ * @param newName
+ * the new name of the same object
+ * @throws NameNotFoundException
+ * if the oldName is unknown for this context
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rename(Name oldName, Name newName) throws NamingException
+ {
+ Object object = lookup(oldName);
+ unbind(oldName);
+ bind(newName, object);
+ }
+
+ /**
+ * Renames the existing binding, removing the existing and giving the new name
+ * for the same object.
+ *
+ * @param oldName
+ * the existing name of the known object
+ * @param newName
+ * the new name of the same object
+ * @throws NameNotFoundException
+ * if the oldName is unknown for this context
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void rename(String oldName, String newName) throws NamingException
+ {
+ Object object = lookup(oldName);
+ unbind(oldName);
+ bind(newName, object);
+ }
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name
+ * the name to be removed
+ * @throws NameNotFoundException
+ * if one of the intermediate naming contexts does not exist. Will
+ * not be thrown if just the terminal binding is missing.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void unbind(Name name) throws NamingException
+ {
+ unbind(name.toString());
+ }
+
+ /**
+ * Removes the name - object mapping from the current context. This method
+ * returns without action if the name is not bound to an object in the
+ * terminal context, but throws {@link NameNotFoundException} if one of the
+ * intermadiate contexts does not exist.
+ *
+ * @param name
+ * the name to be removed
+ * @throws NameNotFoundException
+ * if one of the intermediate naming contexts does not exist. Will
+ * not be thrown if just the terminal binding is missing.
+ * @throws NamingException
+ * if the naming operation has failed due other reasons.
+ */
+ public void unbind(String name) throws NamingException
+ {
+ try
+ {
+ String[] n = split(name);
+ NamingContextExt service = getService(n[0]);
+
+ service.unbind(transformer.toName(n[1]));
+ }
+ catch (NotFound e)
+ {
+ throw new NameNotFoundException(name);
+ }
+ catch (CannotProceed e)
+ {
+ throw new ContextNotEmptyException(name);
+ }
+ catch (InvalidName e)
+ {
+ throw new InvalidNameException(name);
+ }
+ }
+
+ /**
+ * Add new environment property to the environment of this context. Both name
+ * and value of the new property must not be null. If the property is already
+ * defined, is current value is replaced by the propVal.
+ *
+ * @param key
+ * the name of the new property
+ * @param value
+ * the value of the new property
+ * @return the previous value of this property or null if the property has not
+ * been previously defined
+ * @throws NamingException
+ */
+ public Object addToEnvironment(String key, Object value)
+ throws NamingException
+ {
+ if (key == null || value == null)
+ throw new NullPointerException();
+ return properties.put(key, value);
+ }
+
+ /**
+ * Returns the environment, associated with this naming context. The returned
+ * table should never be modified by the caller. Use {@link #addToEnvironment}
+ * and {@link #removeFromEnvironment} to modify the environement, if needed.
+ *
+ * @return the table, representing the environment of this context
+ * @throws NamingException
+ */
+ public Hashtable getEnvironment() throws NamingException
+ {
+ return properties;
+ }
+
+ /**
+ * Removes the property with the given name from the environment. Returns
+ * without action if this property is not defined.
+ *
+ * @param propName
+ * the name of the property being removed.
+ * @return the value of the property that has been removed or null if the
+ * property was not defined.
+ * @throws NamingException
+ */
+ public Object removeFromEnvironment(String propName) throws NamingException
+ {
+ return properties.remove(propName);
+ }
+
+ /**
+ * Convert the {@link Name} into array of the name components, required to the
+ * CORBA naming service. First the string representation is obtained, then
+ * it is converted using parsing rules of the CORBA name.
+ *
+ * @param name
+ * then name to convert
+ * @return the converted array of components.
+ */
+ public NameComponent[] toGiop(Name name) throws InvalidName
+ {
+ return transformer.toName(name.toString());
+ }
+
+ /**
+ * Get the batch size from the environment properties. The batch size is used
+ * for listing operations.
+ *
+ * @return the batch size, or some default value if not specified.
+ */
+ public int getBatchSize()
+ {
+ int batchSize = DEFAULT_BATCH_SIZE;
+ Object bs = properties.get(Context.BATCHSIZE);
+ if (bs != null)
+ {
+ try
+ {
+ int b = Integer.parseInt(bs.toString());
+ if (b >= 0)
+ batchSize = b;
+ }
+ catch (NumberFormatException e)
+ {
+ // OK, use default value.
+ }
+ }
+ return batchSize;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/ListBindingsEnumeration.java b/libjava/classpath/gnu/javax/naming/giop/ListBindingsEnumeration.java
new file mode 100644
index 000000000..dd9ed0265
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/ListBindingsEnumeration.java
@@ -0,0 +1,118 @@
+/* ListBindingsEnumeration.java -- handles corbaname: urls
+ 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.javax.naming.giop;
+
+import gnu.java.lang.CPStringBuilder;
+
+import javax.naming.NamingEnumeration;
+
+import org.omg.CosNaming.Binding;
+import org.omg.CosNaming.BindingIteratorHolder;
+import org.omg.CosNaming.BindingListHolder;
+import org.omg.CosNaming.NamingContext;
+
+/**
+ * Iterates over bindings, obtaining values first from the binding list and then
+ * from the binding iterator.
+ *
+ * @author Audrius Meskauskas
+ */
+public class ListBindingsEnumeration extends GiopNamingEnumeration implements
+ NamingEnumeration
+{
+ /**
+ * The naming service, to resolve the objects.
+ */
+ NamingContext service;
+
+ /**
+ * Create the new enumeration
+ *
+ * @param bh
+ * holder, containing the first portion of the bindings
+ * @param bih
+ * the iterator, containing the remaining bindings
+ * @param batchSize
+ * the number of bindings the the iterator will be requested to
+ * return as a single pack
+ * @param aService
+ * the naming service, used to obtain the objects, bound to the
+ * names.
+ */
+ public ListBindingsEnumeration(BindingListHolder bh,
+ BindingIteratorHolder bih, int batchSize,
+ NamingContext aService)
+ {
+ super(bh, bih, batchSize);
+ service = aService;
+ }
+
+ /**
+ * Convert from the CORBA binding into the javax.naming binding. As the CORBA
+ * naming service binding does not contain the object itself, this method
+ * makes the additional calls to the naming service.
+ *
+ * @param binding
+ * the binding to convert
+ * @return the value, that must be returned by the {@link #next()}.
+ */
+ public Object convert(Binding binding)
+ {
+ CPStringBuilder name = new CPStringBuilder();
+
+ for (int i = 0; i < binding.binding_name.length; i++)
+ {
+ name.append(binding.binding_name[i]);
+ if (i < binding.binding_name.length - 1)
+ name.append('/');
+ }
+
+ try
+ {
+ Object object = service.resolve(binding.binding_name);
+ return new javax.naming.Binding(name.toString(), object);
+ }
+ catch (Exception e)
+ {
+ // Probably was removed by the concurent thread.
+ return null;
+ }
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/naming/giop/ListEnumeration.java b/libjava/classpath/gnu/javax/naming/giop/ListEnumeration.java
new file mode 100644
index 000000000..68a40fcf0
--- /dev/null
+++ b/libjava/classpath/gnu/javax/naming/giop/ListEnumeration.java
@@ -0,0 +1,118 @@
+/* ListEnumeration.java -- handles corbaname: urls
+ 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
+odule. 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.javax.naming.giop;
+
+import gnu.java.lang.CPStringBuilder;
+
+import javax.naming.NameClassPair;
+import javax.naming.NamingEnumeration;
+
+import org.omg.CosNaming.Binding;
+import org.omg.CosNaming.BindingIteratorHolder;
+import org.omg.CosNaming.BindingListHolder;
+import org.omg.CosNaming.BindingType;
+import org.omg.CosNaming.NamingContext;
+
+/**
+ * Iterates over name class pairs, obtaining values first from the binding list
+ * and then from the binding iterator.
+ *
+ * @author Audrius Meskauskas
+ */
+public class ListEnumeration extends GiopNamingEnumeration implements
+ NamingEnumeration
+{
+ /**
+ * Create the new enumeration
+ *
+ * @param bh
+ * holder, containing the first portion of the bindings
+ * @param bih
+ * the iterator, containing the remaining bindings
+ * @param batchSize
+ * the number of bindings the the iterator will be requested to
+ * return as a single pack
+ */
+ public ListEnumeration(BindingListHolder bh,
+ BindingIteratorHolder bih, int batchSize)
+ {
+ super(bh, bih, batchSize);
+ }
+
+ /**
+ * Convert from the CORBA binding into the {@link NameClassPair} that this
+ * enumeration should return. This method converts into NameClassPair,
+ * connecting the name components with slashes and setting the class name
+ * to either NamingContext or GIOP Object.
+ *
+ * @param binding
+ * the binding to convert
+ * @return the value, that must be returned by the {@link #next()}.
+ */
+ public Object convert(Binding binding)
+ {
+ CPStringBuilder name = new CPStringBuilder();
+
+ for (int i = 0; i < binding.binding_name.length; i++)
+ {
+ name.append(binding.binding_name[i]);
+ if (i < binding.binding_name.length - 1)
+ name.append('/');
+ }
+
+ String className;
+
+ switch (binding.binding_type.value())
+ {
+ case BindingType._ncontext:
+ className = NamingContext.class.getName();
+ break;
+ case BindingType._nobject:
+ className = org.omg.CORBA.Object.class.getName();
+ break;
+ default:
+ className = Object.class.getName();
+ break;
+ }
+
+ NameClassPair pair = new NameClassPair(name.toString(), className);
+ return pair;
+ }
+
+}