feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when an authentication error occurs while
* accessing the naming or directory service.
* An authentication error can happen, for example, when the credentials
* supplied by the user program is invalid or otherwise fails to
* authenticate the user to the naming/directory service.
*<p>
* If the program wants to handle this exception in particular, it
* should catch AuthenticationException explicitly before attempting to
* catch NamingException. After catching AuthenticationException, the
* program could reattempt the authentication by updating
* the resolved context's environment properties with the appropriate
* appropriate credentials.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class AuthenticationException extends NamingSecurityException {
/**
* Constructs a new instance of AuthenticationException using the
* explanation supplied. All other fields default to null.
*
* @param explanation A possibly null string containing
* additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public AuthenticationException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of AuthenticationException.
* All fields are set to null.
*/
public AuthenticationException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 3678497619904568096L;
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when
* the particular flavor of authentication requested is not supported.
* For example, if the program
* is attempting to use strong authentication but the directory/naming
* supports only simple authentication, this exception would be thrown.
* Identification of a particular flavor of authentication is
* provider- and server-specific. It may be specified using
* specific authentication schemes such
* those identified using SASL, or a generic authentication specifier
* (such as "simple" and "strong").
*<p>
* If the program wants to handle this exception in particular, it
* should catch AuthenticationNotSupportedException explicitly before
* attempting to catch NamingException. After catching
* <code>AuthenticationNotSupportedException</code>, the program could
* reattempt the authentication using a different authentication flavor
* by updating the resolved context's environment properties accordingly.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class AuthenticationNotSupportedException extends NamingSecurityException {
/**
* Constructs a new instance of AuthenticationNotSupportedException using
* an explanation. All other fields default to null.
*
* @param explanation A possibly null string containing additional
* detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public AuthenticationNotSupportedException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of AuthenticationNotSupportedException
* all name resolution fields and explanation initialized to null.
*/
public AuthenticationNotSupportedException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -7149033933259492300L;
}

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents the binary form of the address of
* a communications end-point.
*<p>
* A BinaryRefAddr consists of a type that describes the communication mechanism
* and an opaque buffer containing the address description
* specific to that communication mechanism. The format and interpretation of
* the address type and the contents of the opaque buffer are based on
* the agreement of three parties: the client that uses the address,
* the object/server that can be reached using the address,
* and the administrator or program that creates the address.
*<p>
* An example of a binary reference address is an BER X.500 presentation address.
* Another example of a binary reference address is a serialized form of
* a service's object handle.
*<p>
* A binary reference address is immutable in the sense that its fields
* once created, cannot be replaced. However, it is possible to access
* the byte array used to hold the opaque buffer. Programs are strongly
* recommended against changing this byte array. Changes to this
* byte array need to be explicitly synchronized.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see RefAddr
* @see StringRefAddr
* @since 1.3
*/
/*
* The serialized form of a BinaryRefAddr object consists of its type
* name String and a byte array containing its "contents".
*/
public class BinaryRefAddr extends RefAddr {
/**
* Contains the bytes of the address.
* This field is initialized by the constructor and returned
* using getAddressBytes() and getAddressContents().
* @serial
*/
private byte[] buf = null;
/**
* Constructs a new instance of BinaryRefAddr using its address type and a byte
* array for contents.
*
* @param addrType A non-null string describing the type of the address.
* @param src The non-null contents of the address as a byte array.
* The contents of src is copied into the new BinaryRefAddr.
*/
public BinaryRefAddr(String addrType, byte[] src) {
this(addrType, src, 0, src.length);
}
/**
* Constructs a new instance of BinaryRefAddr using its address type and
* a region of a byte array for contents.
*
* @param addrType A non-null string describing the type of the address.
* @param src The non-null contents of the address as a byte array.
* The contents of src is copied into the new BinaryRefAddr.
* @param offset The starting index in src to get the bytes.
* {@code 0 <= offset <= src.length}.
* @param count The number of bytes to extract from src.
* {@code 0 <= count <= src.length-offset}.
*/
public BinaryRefAddr(String addrType, byte[] src, int offset, int count) {
super(addrType);
buf = new byte[count];
System.arraycopy(src, offset, buf, 0, count);
}
/**
* Retrieves the contents of this address as an Object.
* The result is a byte array.
* Changes to this array will affect this BinaryRefAddr's contents.
* Programs are recommended against changing this array's contents
* and to lock the buffer if they need to change it.
*
* @return The non-null buffer containing this address's contents.
*/
public Object getContent() {
return buf;
}
/**
* Determines whether obj is equal to this address. It is equal if
* it contains the same address type and their contents are byte-wise
* equivalent.
* @param obj The possibly null object to check.
* @return true if the object is equal; false otherwise.
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof BinaryRefAddr)) {
BinaryRefAddr target = (BinaryRefAddr)obj;
if (addrType.compareTo(target.addrType) == 0) {
if (buf == null && target.buf == null)
return true;
if (buf == null || target.buf == null ||
buf.length != target.buf.length)
return false;
for (int i = 0; i < buf.length; i++)
if (buf[i] != target.buf[i])
return false;
return true;
}
}
return false;
}
/**
* Computes the hash code of this address using its address type and contents.
* Two BinaryRefAddrs have the same hash code if they have
* the same address type and the same contents.
* It is also possible for different BinaryRefAddrs to have
* the same hash code.
*
* @return The hash code of this address as an int.
*/
public int hashCode() {
int hash = addrType.hashCode();
for (int i = 0; i < buf.length; i++) {
hash += buf[i]; // %%% improve later
}
return hash;
}
/**
* Generates the string representation of this address.
* The string consists of the address's type and contents with labels.
* The first 32 bytes of contents are displayed (in hexadecimal).
* If there are more than 32 bytes, "..." is used to indicate more.
* This string is meant to used for debugging purposes and not
* meant to be interpreted programmatically.
* @return The non-null string representation of this address.
*/
public String toString(){
StringBuffer str = new StringBuffer("Address Type: " + addrType + "\n");
str.append("AddressContents: ");
for (int i = 0; i<buf.length && i < 32; i++) {
str.append(Integer.toHexString(buf[i]) +" ");
}
if (buf.length >= 32)
str.append(" ...\n");
return (str.toString());
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3415254970957330361L;
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents a name-to-object binding found in a context.
*<p>
* A context consists of name-to-object bindings.
* The Binding class represents such a binding. It consists
* of a name and an object. The <code>Context.listBindings()</code>
* method returns an enumeration of Binding.
*<p>
* Use subclassing for naming systems that generate contents of
* a binding dynamically.
*<p>
* A Binding instance is not synchronized against concurrent access by multiple
* threads. Threads that need to access a Binding concurrently should
* synchronize amongst themselves and provide the necessary locking.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class Binding extends NameClassPair {
/**
* Contains this binding's object.
* It is initialized by the constructor and can be updated using
* <tt>setObject</tt>.
* @serial
* @see #getObject
* @see #setObject
*/
private Object boundObj;
/**
* Constructs an instance of a Binding given its name and object.
*<p>
* <tt>getClassName()</tt> will return
* the class name of <tt>obj</tt> (or null if <tt>obj</tt> is null)
* unless the class name has been explicitly set using <tt>setClassName()</tt>
*
* @param name The non-null name of the object. It is relative
* to the <em>target context</em> (which is
* named by the first parameter of the <code>listBindings()</code> method)
* @param obj The possibly null object bound to name.
* @see NameClassPair#setClassName
*/
public Binding(String name, Object obj) {
super(name, null);
this.boundObj = obj;
}
/**
* Constructs an instance of a Binding given its name, object, and whether
* the name is relative.
*<p>
* <tt>getClassName()</tt> will return the class name of <tt>obj</tt>
* (or null if <tt>obj</tt> is null) unless the class name has been
* explicitly set using <tt>setClassName()</tt>
*
* @param name The non-null string name of the object.
* @param obj The possibly null object bound to name.
* @param isRelative true if <code>name</code> is a name relative
* to the target context (which is named by
* the first parameter of the <code>listBindings()</code> method);
* false if <code>name</code> is a URL string.
* @see NameClassPair#isRelative
* @see NameClassPair#setRelative
* @see NameClassPair#setClassName
*/
public Binding(String name, Object obj, boolean isRelative) {
super(name, null, isRelative);
this.boundObj = obj;
}
/**
* Constructs an instance of a Binding given its name, class name, and object.
*
* @param name The non-null name of the object. It is relative
* to the <em>target context</em> (which is
* named by the first parameter of the <code>listBindings()</code> method)
* @param className The possibly null class name of the object
* bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
* returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also
* null, <tt>getClassName()</tt> will return null.
* @param obj The possibly null object bound to name.
* @see NameClassPair#setClassName
*/
public Binding(String name, String className, Object obj) {
super(name, className);
this.boundObj = obj;
}
/**
* Constructs an instance of a Binding given its
* name, class name, object, and whether the name is relative.
*
* @param name The non-null string name of the object.
* @param className The possibly null class name of the object
* bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
* returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also
* null, <tt>getClassName()</tt> will return null.
* @param obj The possibly null object bound to name.
* @param isRelative true if <code>name</code> is a name relative
* to the target context (which is named by
* the first parameter of the <code>listBindings()</code> method);
* false if <code>name</code> is a URL string.
* @see NameClassPair#isRelative
* @see NameClassPair#setRelative
* @see NameClassPair#setClassName
*/
public Binding(String name, String className, Object obj, boolean isRelative) {
super(name, className, isRelative);
this.boundObj = obj;
}
/**
* Retrieves the class name of the object bound to the name of this binding.
* If the class name has been set explicitly, return it.
* Otherwise, if this binding contains a non-null object,
* that object's class name is used. Otherwise, null is returned.
*
* @return A possibly null string containing class name of object bound.
*/
public String getClassName() {
String cname = super.getClassName();
if (cname != null) {
return cname;
}
if (boundObj != null)
return boundObj.getClass().getName();
else
return null;
}
/**
* Retrieves the object bound to the name of this binding.
*
* @return The object bound; null if this binding does not contain an object.
* @see #setObject
*/
public Object getObject() {
return boundObj;
}
/**
* Sets the object associated with this binding.
* @param obj The possibly null object to use.
* @see #getObject
*/
public void setObject(Object obj) {
boundObj = obj;
}
/**
* Generates the string representation of this binding.
* The string representation consists of the string representation
* of the name/class pair and the string representation of
* this binding's object, separated by ':'.
* The contents of this string is useful
* for debugging and is not meant to be interpreted programmatically.
*
* @return The non-null string representation of this binding.
*/
public String toString() {
return super.toString() + ":" + getObject();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 8839217842691845890L;
};

View File

@@ -0,0 +1,286 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Hashtable;
/**
* This exception is thrown to indicate that the operation reached
* a point in the name where the operation cannot proceed any further.
* When performing an operation on a composite name, a naming service
* provider may reach a part of the name that does not belong to its
* namespace. At that point, it can construct a
* CannotProceedException and then invoke methods provided by
* javax.naming.spi.NamingManager (such as getContinuationContext())
* to locate another provider to continue the operation. If this is
* not possible, this exception is raised to the caller of the
* context operation.
*<p>
* If the program wants to handle this exception in particular, it
* should catch CannotProceedException explicitly before attempting to
* catch NamingException.
*<p>
* A CannotProceedException instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* CannotProceedException should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
/*
* The serialized form of a CannotProceedException object consists of
* the serialized fields of its NamingException superclass, the remaining new
* name (a Name object), the environment (a Hashtable), the altName field
* (a Name object), and the serialized form of the altNameCtx field.
*/
public class CannotProceedException extends NamingException {
/**
* Contains the remaining unresolved part of the second
* "name" argument to Context.rename().
* This information necessary for
* continuing the Context.rename() operation.
* <p>
* This field is initialized to null.
* It should not be manipulated directly: it should
* be accessed and updated using getRemainingName() and setRemainingName().
* @serial
*
* @see #getRemainingNewName
* @see #setRemainingNewName
*/
protected Name remainingNewName = null;
/**
* Contains the environment
* relevant for the Context or DirContext method that cannot proceed.
* <p>
* This field is initialized to null.
* It should not be manipulated directly: it should be accessed
* and updated using getEnvironment() and setEnvironment().
* @serial
*
* @see #getEnvironment
* @see #setEnvironment
*/
protected Hashtable<?,?> environment = null;
/**
* Contains the name of the resolved object, relative
* to the context <code>altNameCtx</code>. It is a composite name.
* If null, then no name is specified.
* See the <code>javax.naming.spi.ObjectFactory.getObjectInstance</code>
* method for details on how this is used.
* <p>
* This field is initialized to null.
* It should not be manipulated directly: it should
* be accessed and updated using getAltName() and setAltName().
* @serial
*
* @see #getAltName
* @see #setAltName
* @see #altNameCtx
* @see javax.naming.spi.ObjectFactory#getObjectInstance
*/
protected Name altName = null;
/**
* Contains the context relative to which
* <code>altName</code> is specified. If null, then the default initial
* context is implied.
* See the <code>javax.naming.spi.ObjectFactory.getObjectInstance</code>
* method for details on how this is used.
* <p>
* This field is initialized to null.
* It should not be manipulated directly: it should
* be accessed and updated using getAltNameCtx() and setAltNameCtx().
* @serial
*
* @see #getAltNameCtx
* @see #setAltNameCtx
* @see #altName
* @see javax.naming.spi.ObjectFactory#getObjectInstance
*/
protected Context altNameCtx = null;
/**
* Constructs a new instance of CannotProceedException using an
* explanation. All unspecified fields default to null.
*
* @param explanation A possibly null string containing additional
* detail about this exception.
* If null, this exception has no detail message.
* @see java.lang.Throwable#getMessage
*/
public CannotProceedException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of CannotProceedException.
* All fields default to null.
*/
public CannotProceedException() {
super();
}
/**
* Retrieves the environment that was in effect when this exception
* was created.
* @return Possibly null environment property set.
* null means no environment was recorded for this exception.
* @see #setEnvironment
*/
public Hashtable<?,?> getEnvironment() {
return environment;
}
/**
* Sets the environment that will be returned when getEnvironment()
* is called.
* @param environment A possibly null environment property set.
* null means no environment is being recorded for
* this exception.
* @see #getEnvironment
*/
public void setEnvironment(Hashtable<?,?> environment) {
this.environment = environment; // %%% clone it??
}
/**
* Retrieves the "remaining new name" field of this exception, which is
* used when this exception is thrown during a rename() operation.
*
* @return The possibly null part of the new name that has not been resolved.
* It is a composite name. It can be null, which means
* the remaining new name field has not been set.
*
* @see #setRemainingNewName
*/
public Name getRemainingNewName() {
return remainingNewName;
}
/**
* Sets the "remaining new name" field of this exception.
* This is the value returned by <code>getRemainingNewName()</code>.
*<p>
* <tt>newName</tt> is a composite name. If the intent is to set
* this field using a compound name or string, you must
* "stringify" the compound name, and create a composite
* name with a single component using the string. You can then
* invoke this method using the resulting composite name.
*<p>
* A copy of <code>newName</code> is made and stored.
* Subsequent changes to <code>name</code> does not
* affect the copy in this NamingException and vice versa.
*
* @param newName The possibly null name to set the "remaining new name" to.
* If null, it sets the remaining name field to null.
*
* @see #getRemainingNewName
*/
public void setRemainingNewName(Name newName) {
if (newName != null)
this.remainingNewName = (Name)(newName.clone());
else
this.remainingNewName = null;
}
/**
* Retrieves the <code>altName</code> field of this exception.
* This is the name of the resolved object, relative to the context
* <code>altNameCtx</code>. It will be used during a subsequent call to the
* <code>javax.naming.spi.ObjectFactory.getObjectInstance</code> method.
*
* @return The name of the resolved object, relative to
* <code>altNameCtx</code>.
* It is a composite name. If null, then no name is specified.
*
* @see #setAltName
* @see #getAltNameCtx
* @see javax.naming.spi.ObjectFactory#getObjectInstance
*/
public Name getAltName() {
return altName;
}
/**
* Sets the <code>altName</code> field of this exception.
*
* @param altName The name of the resolved object, relative to
* <code>altNameCtx</code>.
* It is a composite name.
* If null, then no name is specified.
*
* @see #getAltName
* @see #setAltNameCtx
*/
public void setAltName(Name altName) {
this.altName = altName;
}
/**
* Retrieves the <code>altNameCtx</code> field of this exception.
* This is the context relative to which <code>altName</code> is named.
* It will be used during a subsequent call to the
* <code>javax.naming.spi.ObjectFactory.getObjectInstance</code> method.
*
* @return The context relative to which <code>altName</code> is named.
* If null, then the default initial context is implied.
*
* @see #setAltNameCtx
* @see #getAltName
* @see javax.naming.spi.ObjectFactory#getObjectInstance
*/
public Context getAltNameCtx() {
return altNameCtx;
}
/**
* Sets the <code>altNameCtx</code> field of this exception.
*
* @param altNameCtx
* The context relative to which <code>altName</code>
* is named. If null, then the default initial context
* is implied.
*
* @see #getAltNameCtx
* @see #setAltName
*/
public void setAltNameCtx(Context altNameCtx) {
this.altNameCtx = altNameCtx;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 1219724816191576813L;
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when the client is
* unable to communicate with the directory or naming service.
* The inability to communicate with the service might be a result
* of many factors, such as network partitioning, hardware or interface problems,
* failures on either the client or server side.
* This exception is meant to be used to capture such communication problems.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class CommunicationException extends NamingException {
/**
* Constructs a new instance of CommunicationException using the
* arguments supplied.
*
* @param explanation Additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public CommunicationException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of CommunicationException.
*/
public CommunicationException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 3618507780299986611L;
}

View File

@@ -0,0 +1,630 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Enumeration;
import java.util.Properties;
/**
* This class represents a composite name -- a sequence of
* component names spanning multiple namespaces.
* Each component is a string name from the namespace of a
* naming system. If the component comes from a hierarchical
* namespace, that component can be further parsed into
* its atomic parts by using the CompoundName class.
*<p>
* The components of a composite name are numbered. The indexes of a
* composite name with N components range from 0 up to, but not including, N.
* This range may be written as [0,N).
* The most significant component is at index 0.
* An empty composite name has no components.
*
* <h1>JNDI Composite Name Syntax</h1>
* JNDI defines a standard string representation for composite names. This
* representation is the concatenation of the components of a composite name
* from left to right using the component separator (a forward
* slash character (/)) to separate each component.
* The JNDI syntax defines the following meta characters:
* <ul>
* <li>escape (backward slash \),
* <li>quote characters (single (') and double quotes (")), and
* <li>component separator (forward slash character (/)).
* </ul>
* Any occurrence of a leading quote, an escape preceding any meta character,
* an escape at the end of a component, or a component separator character
* in an unquoted component must be preceded by an escape character when
* that component is being composed into a composite name string.
* Alternatively, to avoid adding escape characters as described,
* the entire component can be quoted using matching single quotes
* or matching double quotes. A single quote occurring within a double-quoted
* component is not considered a meta character (and need not be escaped),
* and vice versa.
*<p>
* When two composite names are compared, the case of the characters
* is significant.
*<p>
* A leading component separator (the composite name string begins with
* a separator) denotes a leading empty component (a component consisting
* of an empty string).
* A trailing component separator (the composite name string ends with
* a separator) denotes a trailing empty component.
* Adjacent component separators denote an empty component.
*
*<h1>Composite Name Examples</h1>
*This table shows examples of some composite names. Each row shows
*the string form of a composite name and its corresponding structural form
*(<tt>CompositeName</tt>).
*
<table border="1" cellpadding=3 summary="examples showing string form of composite name and its corresponding structural form (CompositeName)">
<tr>
<th>String Name</th>
<th>CompositeName</th>
</tr>
<tr>
<td>
""
</td>
<td>{} (the empty name == new CompositeName("") == new CompositeName())
</td>
</tr>
<tr>
<td>
"x"
</td>
<td>{"x"}
</td>
</tr>
<tr>
<td>
"x/y"
</td>
<td>{"x", "y"}</td>
</tr>
<tr>
<td>"x/"</td>
<td>{"x", ""}</td>
</tr>
<tr>
<td>"/x"</td>
<td>{"", "x"}</td>
</tr>
<tr>
<td>"/"</td>
<td>{""}</td>
</tr>
<tr>
<td>"//"</td>
<td>{"", ""}</td>
</tr>
<tr><td>"/x/"</td>
<td>{"", "x", ""}</td>
</tr>
<tr><td>"x//y"</td>
<td>{"x", "", "y"}</td>
</tr>
</table>
*
*<h1>Composition Examples</h1>
* Here are some composition examples. The right column shows composing
* string composite names while the left column shows composing the
* corresponding <tt>CompositeName</tt>s. Notice that composing the
* string forms of two composite names simply involves concatenating
* their string forms together.
<table border="1" cellpadding=3 summary="composition examples showing string names and composite names">
<tr>
<th>String Names</th>
<th>CompositeNames</th>
</tr>
<tr>
<td>
"x/y" + "/" = x/y/
</td>
<td>
{"x", "y"} + {""} = {"x", "y", ""}
</td>
</tr>
<tr>
<td>
"" + "x" = "x"
</td>
<td>
{} + {"x"} = {"x"}
</td>
</tr>
<tr>
<td>
"/" + "x" = "/x"
</td>
<td>
{""} + {"x"} = {"", "x"}
</td>
</tr>
<tr>
<td>
"x" + "" + "" = "x"
</td>
<td>
{"x"} + {} + {} = {"x"}
</td>
</tr>
</table>
*
*<h1>Multithreaded Access</h1>
* A <tt>CompositeName</tt> instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify a
* <tt>CompositeName</tt> should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class CompositeName implements Name {
private transient NameImpl impl;
/**
* Constructs a new composite name instance using the components
* specified by 'comps'. This protected method is intended to be
* to be used by subclasses of CompositeName when they override
* methods such as clone(), getPrefix(), getSuffix().
*
* @param comps A non-null enumeration containing the components for the new
* composite name. Each element is of class String.
* The enumeration will be consumed to extract its
* elements.
*/
protected CompositeName(Enumeration<String> comps) {
impl = new NameImpl(null, comps); // null means use default syntax
}
/**
* Constructs a new composite name instance by parsing the string n
* using the composite name syntax (left-to-right, slash separated).
* The composite name syntax is described in detail in the class
* description.
*
* @param n The non-null string to parse.
* @exception InvalidNameException If n has invalid composite name syntax.
*/
public CompositeName(String n) throws InvalidNameException {
impl = new NameImpl(null, n); // null means use default syntax
}
/**
* Constructs a new empty composite name. Such a name returns true
* when <code>isEmpty()</code> is invoked on it.
*/
public CompositeName() {
impl = new NameImpl(null); // null means use default syntax
}
/**
* Generates the string representation of this composite name.
* The string representation consists of enumerating in order
* each component of the composite name and separating
* each component by a forward slash character. Quoting and
* escape characters are applied where necessary according to
* the JNDI syntax, which is described in the class description.
* An empty component is represented by an empty string.
*
* The string representation thus generated can be passed to
* the CompositeName constructor to create a new equivalent
* composite name.
*
* @return A non-null string representation of this composite name.
*/
public String toString() {
return impl.toString();
}
/**
* Determines whether two composite names are equal.
* If obj is null or not a composite name, false is returned.
* Two composite names are equal if each component in one is equal
* to the corresponding component in the other. This implies
* both have the same number of components, and each component's
* equals() test against the corresponding component in the other name
* returns true.
*
* @param obj The possibly null object to compare against.
* @return true if obj is equal to this composite name, false otherwise.
* @see #hashCode
*/
public boolean equals(Object obj) {
return (obj != null &&
obj instanceof CompositeName &&
impl.equals(((CompositeName)obj).impl));
}
/**
* Computes the hash code of this composite name.
* The hash code is the sum of the hash codes of individual components
* of this composite name.
*
* @return An int representing the hash code of this name.
* @see #equals
*/
public int hashCode() {
return impl.hashCode();
}
/**
* Compares this CompositeName with the specified Object for order.
* Returns a
* negative integer, zero, or a positive integer as this Name is less
* than, equal to, or greater than the given Object.
* <p>
* If obj is null or not an instance of CompositeName, ClassCastException
* is thrown.
* <p>
* See equals() for what it means for two composite names to be equal.
* If two composite names are equal, 0 is returned.
* <p>
* Ordering of composite names follows the lexicographical rules for
* string comparison, with the extension that this applies to all
* the components in the composite name. The effect is as if all the
* components were lined up in their specified ordered and the
* lexicographical rules applied over the two line-ups.
* If this composite name is "lexicographically" lesser than obj,
* a negative number is returned.
* If this composite name is "lexicographically" greater than obj,
* a positive number is returned.
* @param obj The non-null object to compare against.
*
* @return a negative integer, zero, or a positive integer as this Name
* is less than, equal to, or greater than the given Object.
* @exception ClassCastException if obj is not a CompositeName.
*/
public int compareTo(Object obj) {
if (!(obj instanceof CompositeName)) {
throw new ClassCastException("Not a CompositeName");
}
return impl.compareTo(((CompositeName)obj).impl);
}
/**
* Generates a copy of this composite name.
* Changes to the components of this composite name won't
* affect the new copy and vice versa.
*
* @return A non-null copy of this composite name.
*/
public Object clone() {
return (new CompositeName(getAll()));
}
/**
* Retrieves the number of components in this composite name.
*
* @return The nonnegative number of components in this composite name.
*/
public int size() {
return (impl.size());
}
/**
* Determines whether this composite name is empty. A composite name
* is empty if it has zero components.
*
* @return true if this composite name is empty, false otherwise.
*/
public boolean isEmpty() {
return (impl.isEmpty());
}
/**
* Retrieves the components of this composite name as an enumeration
* of strings.
* The effects of updates to this composite name on this enumeration
* is undefined.
*
* @return A non-null enumeration of the components of
* this composite name. Each element of the enumeration is of
* class String.
*/
public Enumeration<String> getAll() {
return (impl.getAll());
}
/**
* Retrieves a component of this composite name.
*
* @param posn The 0-based index of the component to retrieve.
* Must be in the range [0,size()).
* @return The non-null component at index posn.
* @exception ArrayIndexOutOfBoundsException if posn is outside the
* specified range.
*/
public String get(int posn) {
return (impl.get(posn));
}
/**
* Creates a composite name whose components consist of a prefix of the
* components in this composite name. Subsequent changes to
* this composite name does not affect the name that is returned.
*
* @param posn The 0-based index of the component at which to stop.
* Must be in the range [0,size()].
* @return A composite name consisting of the components at indexes in
* the range [0,posn).
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getPrefix(int posn) {
Enumeration<String> comps = impl.getPrefix(posn);
return (new CompositeName(comps));
}
/**
* Creates a composite name whose components consist of a suffix of the
* components in this composite name. Subsequent changes to
* this composite name does not affect the name that is returned.
*
* @param posn The 0-based index of the component at which to start.
* Must be in the range [0,size()].
* @return A composite name consisting of the components at indexes in
* the range [posn,size()). If posn is equal to
* size(), an empty composite name is returned.
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getSuffix(int posn) {
Enumeration<String> comps = impl.getSuffix(posn);
return (new CompositeName(comps));
}
/**
* Determines whether a composite name is a prefix of this composite name.
* A composite name 'n' is a prefix if it is equal to
* getPrefix(n.size())--in other words, this composite name
* starts with 'n'. If 'n' is null or not a composite name, false is returned.
*
* @param n The possibly null name to check.
* @return true if n is a CompositeName and
* is a prefix of this composite name, false otherwise.
*/
public boolean startsWith(Name n) {
if (n instanceof CompositeName) {
return (impl.startsWith(n.size(), n.getAll()));
} else {
return false;
}
}
/**
* Determines whether a composite name is a suffix of this composite name.
* A composite name 'n' is a suffix if it it is equal to
* getSuffix(size()-n.size())--in other words, this
* composite name ends with 'n'.
* If n is null or not a composite name, false is returned.
*
* @param n The possibly null name to check.
* @return true if n is a CompositeName and
* is a suffix of this composite name, false otherwise.
*/
public boolean endsWith(Name n) {
if (n instanceof CompositeName) {
return (impl.endsWith(n.size(), n.getAll()));
} else {
return false;
}
}
/**
* Adds the components of a composite name -- in order -- to the end of
* this composite name.
*
* @param suffix The non-null components to add.
* @return The updated CompositeName, not a new one. Cannot be null.
* @exception InvalidNameException If suffix is not a composite name.
*/
public Name addAll(Name suffix)
throws InvalidNameException
{
if (suffix instanceof CompositeName) {
impl.addAll(suffix.getAll());
return this;
} else {
throw new InvalidNameException("Not a composite name: " +
suffix.toString());
}
}
/**
* Adds the components of a composite name -- in order -- at a specified
* position within this composite name.
* Components of this composite name at or after the index of the first
* new component are shifted up (away from index 0)
* to accommodate the new components.
*
* @param n The non-null components to add.
* @param posn The index in this name at which to add the new
* components. Must be in the range [0,size()].
* @return The updated CompositeName, not a new one. Cannot be null.
* @exception InvalidNameException If n is not a composite name.
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name addAll(int posn, Name n)
throws InvalidNameException
{
if (n instanceof CompositeName) {
impl.addAll(posn, n.getAll());
return this;
} else {
throw new InvalidNameException("Not a composite name: " +
n.toString());
}
}
/**
* Adds a single component to the end of this composite name.
*
* @param comp The non-null component to add.
* @return The updated CompositeName, not a new one. Cannot be null.
* @exception InvalidNameException If adding comp at end of the name
* would violate the name's syntax.
*/
public Name add(String comp) throws InvalidNameException {
impl.add(comp);
return this;
}
/**
* Adds a single component at a specified position within this
* composite name.
* Components of this composite name at or after the index of the new
* component are shifted up by one (away from index 0) to accommodate
* the new component.
*
* @param comp The non-null component to add.
* @param posn The index at which to add the new component.
* Must be in the range [0,size()].
* @return The updated CompositeName, not a new one. Cannot be null.
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
* @exception InvalidNameException If adding comp at the specified position
* would violate the name's syntax.
*/
public Name add(int posn, String comp)
throws InvalidNameException
{
impl.add(posn, comp);
return this;
}
/**
* Deletes a component from this composite name.
* The component of this composite name at position 'posn' is removed,
* and components at indices greater than 'posn'
* are shifted down (towards index 0) by one.
*
* @param posn The index of the component to delete.
* Must be in the range [0,size()).
* @return The component removed (a String).
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range (includes case where
* composite name is empty).
* @exception InvalidNameException If deleting the component
* would violate the name's syntax.
*/
public Object remove(int posn) throws InvalidNameException{
return impl.remove(posn);
}
/**
* Overridden to avoid implementation dependency.
* @serialData The number of components (an <tt>int</tt>) followed by
* the individual components (each a <tt>String</tt>).
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.writeInt(size());
Enumeration<String> comps = getAll();
while (comps.hasMoreElements()) {
s.writeObject(comps.nextElement());
}
}
/**
* Overridden to avoid implementation dependency.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
impl = new NameImpl(null); // null means use default syntax
int n = s.readInt(); // number of components
try {
while (--n >= 0) {
add((String)s.readObject());
}
} catch (InvalidNameException e) {
throw (new java.io.StreamCorruptedException("Invalid name"));
}
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 1667768148915813118L;
/*
// %%% Test code for serialization.
public static void main(String[] args) throws Exception {
CompositeName c = new CompositeName("aaa/bbb");
java.io.FileOutputStream f1 = new java.io.FileOutputStream("/tmp/ser");
java.io.ObjectOutputStream s1 = new java.io.ObjectOutputStream(f1);
s1.writeObject(c);
s1.close();
java.io.FileInputStream f2 = new java.io.FileInputStream("/tmp/ser");
java.io.ObjectInputStream s2 = new java.io.ObjectInputStream(f2);
c = (CompositeName)s2.readObject();
System.out.println("Size: " + c.size());
System.out.println("Size: " + c.snit);
}
*/
/*
%%% Testing code
public static void main(String[] args) {
try {
for (int i = 0; i < args.length; i++) {
Name name;
Enumeration e;
System.out.println("Given name: " + args[i]);
name = new CompositeName(args[i]);
e = name.getComponents();
while (e.hasMoreElements()) {
System.out.println("Element: " + e.nextElement());
}
System.out.println("Constructed name: " + name.toString());
}
} catch (Exception ne) {
ne.printStackTrace();
}
}
*/
}

View File

@@ -0,0 +1,624 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Enumeration;
import java.util.Properties;
/**
* This class represents a compound name -- a name from
* a hierarchical name space.
* Each component in a compound name is an atomic name.
* <p>
* The components of a compound name are numbered. The indexes of a
* compound name with N components range from 0 up to, but not including, N.
* This range may be written as [0,N).
* The most significant component is at index 0.
* An empty compound name has no components.
*
* <h1>Compound Name Syntax</h1>
* The syntax of a compound name is specified using a set of properties:
*<dl>
* <dt>jndi.syntax.direction
* <dd>Direction for parsing ("right_to_left", "left_to_right", "flat").
* If unspecified, defaults to "flat", which means the namespace is flat
* with no hierarchical structure.
*
* <dt>jndi.syntax.separator
* <dd>Separator between atomic name components.
* Required unless direction is "flat".
*
* <dt>jndi.syntax.ignorecase
* <dd>If present, "true" means ignore the case when comparing name
* components. If its value is not "true", or if the property is not
* present, case is considered when comparing name components.
*
* <dt>jndi.syntax.escape
* <dd>If present, specifies the escape string for overriding separator,
* escapes and quotes.
*
* <dt>jndi.syntax.beginquote
* <dd>If present, specifies the string delimiting start of a quoted string.
*
* <dt>jndi.syntax.endquote
* <dd>String delimiting end of quoted string.
* If present, specifies the string delimiting the end of a quoted string.
* If not present, use syntax.beginquote as end quote.
* <dt>jndi.syntax.beginquote2
* <dd>Alternative set of begin/end quotes.
*
* <dt>jndi.syntax.endquote2
* <dd>Alternative set of begin/end quotes.
*
* <dt>jndi.syntax.trimblanks
* <dd>If present, "true" means trim any leading and trailing whitespaces
* in a name component for comparison purposes. If its value is not
* "true", or if the property is not present, blanks are significant.
* <dt>jndi.syntax.separator.ava
* <dd>If present, specifies the string that separates
* attribute-value-assertions when specifying multiple attribute/value
* pairs. (e.g. "," in age=65,gender=male).
* <dt>jndi.syntax.separator.typeval
* <dd>If present, specifies the string that separators attribute
* from value (e.g. "=" in "age=65")
*</dl>
* These properties are interpreted according to the following rules:
*<ol>
*<li>
* In a string without quotes or escapes, any instance of the
* separator delimits two atomic names. Each atomic name is referred
* to as a <em>component</em>.
*<li>
* A separator, quote or escape is escaped if preceded immediately
* (on the left) by the escape.
*<li>
* If there are two sets of quotes, a specific begin-quote must be matched
* by its corresponding end-quote.
*<li>
* A non-escaped begin-quote which precedes a component must be
* matched by a non-escaped end-quote at the end of the component.
* A component thus quoted is referred to as a
* <em>quoted component</em>. It is parsed by
* removing the being- and end- quotes, and by treating the intervening
* characters as ordinary characters unless one of the rules involving
* quoted components listed below applies.
*<li>
* Quotes embedded in non-quoted components are treated as ordinary strings
* and need not be matched.
*<li>
* A separator that is escaped or appears between non-escaped
* quotes is treated as an ordinary string and not a separator.
*<li>
* An escape string within a quoted component acts as an escape only when
* followed by the corresponding end-quote string.
* This can be used to embed an escaped quote within a quoted component.
*<li>
* An escaped escape string is not treated as an escape string.
*<li>
* An escape string that does not precede a meta string (quotes or separator)
* and is not at the end of a component is treated as an ordinary string.
*<li>
* A leading separator (the compound name string begins with
* a separator) denotes a leading empty atomic component (consisting
* of an empty string).
* A trailing separator (the compound name string ends with
* a separator) denotes a trailing empty atomic component.
* Adjacent separators denote an empty atomic component.
*</ol>
* <p>
* The string form of the compound name follows the syntax described above.
* When the components of the compound name are turned into their
* string representation, the reserved syntax rules described above are
* applied (e.g. embedded separators are escaped or quoted)
* so that when the same string is parsed, it will yield the same components
* of the original compound name.
*
*<h1>Multithreaded Access</h1>
* A <tt>CompoundName</tt> instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify a
* <tt>CompoundName</tt> should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class CompoundName implements Name {
/**
* Implementation of this compound name.
* This field is initialized by the constructors and cannot be null.
* It should be treated as a read-only variable by subclasses.
*/
protected transient NameImpl impl;
/**
* Syntax properties for this compound name.
* This field is initialized by the constructors and cannot be null.
* It should be treated as a read-only variable by subclasses.
* Any necessary changes to mySyntax should be made within constructors
* and not after the compound name has been instantiated.
*/
protected transient Properties mySyntax;
/**
* Constructs a new compound name instance using the components
* specified in comps and syntax. This protected method is intended to be
* to be used by subclasses of CompoundName when they override
* methods such as clone(), getPrefix(), getSuffix().
*
* @param comps A non-null enumeration of the components to add.
* Each element of the enumeration is of class String.
* The enumeration will be consumed to extract its
* elements.
* @param syntax A non-null properties that specify the syntax of
* this compound name. See class description for
* contents of properties.
*/
protected CompoundName(Enumeration<String> comps, Properties syntax) {
if (syntax == null) {
throw new NullPointerException();
}
mySyntax = syntax;
impl = new NameImpl(syntax, comps);
}
/**
* Constructs a new compound name instance by parsing the string n
* using the syntax specified by the syntax properties supplied.
*
* @param n The non-null string to parse.
* @param syntax A non-null list of properties that specify the syntax of
* this compound name. See class description for
* contents of properties.
* @exception InvalidNameException If 'n' violates the syntax specified
* by <code>syntax</code>.
*/
public CompoundName(String n, Properties syntax) throws InvalidNameException {
if (syntax == null) {
throw new NullPointerException();
}
mySyntax = syntax;
impl = new NameImpl(syntax, n);
}
/**
* Generates the string representation of this compound name, using
* the syntax rules of the compound name. The syntax rules
* are described in the class description.
* An empty component is represented by an empty string.
*
* The string representation thus generated can be passed to
* the CompoundName constructor with the same syntax properties
* to create a new equivalent compound name.
*
* @return A non-null string representation of this compound name.
*/
public String toString() {
return (impl.toString());
}
/**
* Determines whether obj is syntactically equal to this compound name.
* If obj is null or not a CompoundName, false is returned.
* Two compound names are equal if each component in one is "equal"
* to the corresponding component in the other.
*<p>
* Equality is also defined in terms of the syntax of this compound name.
* The default implementation of CompoundName uses the syntax properties
* jndi.syntax.ignorecase and jndi.syntax.trimblanks when comparing
* two components for equality. If case is ignored, two strings
* with the same sequence of characters but with different cases
* are considered equal. If blanks are being trimmed, leading and trailing
* blanks are ignored for the purpose of the comparison.
*<p>
* Both compound names must have the same number of components.
*<p>
* Implementation note: Currently the syntax properties of the two compound
* names are not compared for equality. They might be in the future.
*
* @param obj The possibly null object to compare against.
* @return true if obj is equal to this compound name, false otherwise.
* @see #compareTo(java.lang.Object obj)
*/
public boolean equals(Object obj) {
// %%% check syntax too?
return (obj != null &&
obj instanceof CompoundName &&
impl.equals(((CompoundName)obj).impl));
}
/**
* Computes the hash code of this compound name.
* The hash code is the sum of the hash codes of the "canonicalized"
* forms of individual components of this compound name.
* Each component is "canonicalized" according to the
* compound name's syntax before its hash code is computed.
* For a case-insensitive name, for example, the uppercased form of
* a name has the same hash code as its lowercased equivalent.
*
* @return An int representing the hash code of this name.
*/
public int hashCode() {
return impl.hashCode();
}
/**
* Creates a copy of this compound name.
* Changes to the components of this compound name won't
* affect the new copy and vice versa.
* The clone and this compound name share the same syntax.
*
* @return A non-null copy of this compound name.
*/
public Object clone() {
return (new CompoundName(getAll(), mySyntax));
}
/**
* Compares this CompoundName with the specified Object for order.
* Returns a
* negative integer, zero, or a positive integer as this Name is less
* than, equal to, or greater than the given Object.
* <p>
* If obj is null or not an instance of CompoundName, ClassCastException
* is thrown.
* <p>
* See equals() for what it means for two compound names to be equal.
* If two compound names are equal, 0 is returned.
*<p>
* Ordering of compound names depend on the syntax of the compound name.
* By default, they follow lexicographical rules for string comparison
* with the extension that this applies to all the components in the
* compound name and that comparison of individual components is
* affected by the jndi.syntax.ignorecase and jndi.syntax.trimblanks
* properties, identical to how they affect equals().
* If this compound name is "lexicographically" lesser than obj,
* a negative number is returned.
* If this compound name is "lexicographically" greater than obj,
* a positive number is returned.
*<p>
* Implementation note: Currently the syntax properties of the two compound
* names are not compared when checking order. They might be in the future.
* @param obj The non-null object to compare against.
* @return a negative integer, zero, or a positive integer as this Name
* is less than, equal to, or greater than the given Object.
* @exception ClassCastException if obj is not a CompoundName.
* @see #equals(java.lang.Object)
*/
public int compareTo(Object obj) {
if (!(obj instanceof CompoundName)) {
throw new ClassCastException("Not a CompoundName");
}
return impl.compareTo(((CompoundName)obj).impl);
}
/**
* Retrieves the number of components in this compound name.
*
* @return The nonnegative number of components in this compound name.
*/
public int size() {
return (impl.size());
}
/**
* Determines whether this compound name is empty.
* A compound name is empty if it has zero components.
*
* @return true if this compound name is empty, false otherwise.
*/
public boolean isEmpty() {
return (impl.isEmpty());
}
/**
* Retrieves the components of this compound name as an enumeration
* of strings.
* The effects of updates to this compound name on this enumeration
* is undefined.
*
* @return A non-null enumeration of the components of this
* compound name. Each element of the enumeration is of class String.
*/
public Enumeration<String> getAll() {
return (impl.getAll());
}
/**
* Retrieves a component of this compound name.
*
* @param posn The 0-based index of the component to retrieve.
* Must be in the range [0,size()).
* @return The component at index posn.
* @exception ArrayIndexOutOfBoundsException if posn is outside the
* specified range.
*/
public String get(int posn) {
return (impl.get(posn));
}
/**
* Creates a compound name whose components consist of a prefix of the
* components in this compound name.
* The result and this compound name share the same syntax.
* Subsequent changes to
* this compound name does not affect the name that is returned and
* vice versa.
*
* @param posn The 0-based index of the component at which to stop.
* Must be in the range [0,size()].
* @return A compound name consisting of the components at indexes in
* the range [0,posn).
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getPrefix(int posn) {
Enumeration<String> comps = impl.getPrefix(posn);
return (new CompoundName(comps, mySyntax));
}
/**
* Creates a compound name whose components consist of a suffix of the
* components in this compound name.
* The result and this compound name share the same syntax.
* Subsequent changes to
* this compound name does not affect the name that is returned.
*
* @param posn The 0-based index of the component at which to start.
* Must be in the range [0,size()].
* @return A compound name consisting of the components at indexes in
* the range [posn,size()). If posn is equal to
* size(), an empty compound name is returned.
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getSuffix(int posn) {
Enumeration<String> comps = impl.getSuffix(posn);
return (new CompoundName(comps, mySyntax));
}
/**
* Determines whether a compound name is a prefix of this compound name.
* A compound name 'n' is a prefix if it is equal to
* getPrefix(n.size())--in other words, this compound name
* starts with 'n'.
* If n is null or not a compound name, false is returned.
*<p>
* Implementation note: Currently the syntax properties of n
* are not used when doing the comparison. They might be in the future.
* @param n The possibly null compound name to check.
* @return true if n is a CompoundName and
* is a prefix of this compound name, false otherwise.
*/
public boolean startsWith(Name n) {
if (n instanceof CompoundName) {
return (impl.startsWith(n.size(), n.getAll()));
} else {
return false;
}
}
/**
* Determines whether a compound name is a suffix of this compound name.
* A compound name 'n' is a suffix if it it is equal to
* getSuffix(size()-n.size())--in other words, this
* compound name ends with 'n'.
* If n is null or not a compound name, false is returned.
*<p>
* Implementation note: Currently the syntax properties of n
* are not used when doing the comparison. They might be in the future.
* @param n The possibly null compound name to check.
* @return true if n is a CompoundName and
* is a suffix of this compound name, false otherwise.
*/
public boolean endsWith(Name n) {
if (n instanceof CompoundName) {
return (impl.endsWith(n.size(), n.getAll()));
} else {
return false;
}
}
/**
* Adds the components of a compound name -- in order -- to the end of
* this compound name.
*<p>
* Implementation note: Currently the syntax properties of suffix
* is not used or checked. They might be in the future.
* @param suffix The non-null components to add.
* @return The updated CompoundName, not a new one. Cannot be null.
* @exception InvalidNameException If suffix is not a compound name,
* or if the addition of the components violates the syntax
* of this compound name (e.g. exceeding number of components).
*/
public Name addAll(Name suffix) throws InvalidNameException {
if (suffix instanceof CompoundName) {
impl.addAll(suffix.getAll());
return this;
} else {
throw new InvalidNameException("Not a compound name: " +
suffix.toString());
}
}
/**
* Adds the components of a compound name -- in order -- at a specified
* position within this compound name.
* Components of this compound name at or after the index of the first
* new component are shifted up (away from index 0)
* to accommodate the new components.
*<p>
* Implementation note: Currently the syntax properties of suffix
* is not used or checked. They might be in the future.
*
* @param n The non-null components to add.
* @param posn The index in this name at which to add the new
* components. Must be in the range [0,size()].
* @return The updated CompoundName, not a new one. Cannot be null.
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
* @exception InvalidNameException If n is not a compound name,
* or if the addition of the components violates the syntax
* of this compound name (e.g. exceeding number of components).
*/
public Name addAll(int posn, Name n) throws InvalidNameException {
if (n instanceof CompoundName) {
impl.addAll(posn, n.getAll());
return this;
} else {
throw new InvalidNameException("Not a compound name: " +
n.toString());
}
}
/**
* Adds a single component to the end of this compound name.
*
* @param comp The non-null component to add.
* @return The updated CompoundName, not a new one. Cannot be null.
* @exception InvalidNameException If adding comp at end of the name
* would violate the compound name's syntax.
*/
public Name add(String comp) throws InvalidNameException{
impl.add(comp);
return this;
}
/**
* Adds a single component at a specified position within this
* compound name.
* Components of this compound name at or after the index of the new
* component are shifted up by one (away from index 0)
* to accommodate the new component.
*
* @param comp The non-null component to add.
* @param posn The index at which to add the new component.
* Must be in the range [0,size()].
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range.
* @return The updated CompoundName, not a new one. Cannot be null.
* @exception InvalidNameException If adding comp at the specified position
* would violate the compound name's syntax.
*/
public Name add(int posn, String comp) throws InvalidNameException{
impl.add(posn, comp);
return this;
}
/**
* Deletes a component from this compound name.
* The component of this compound name at position 'posn' is removed,
* and components at indices greater than 'posn'
* are shifted down (towards index 0) by one.
*
* @param posn The index of the component to delete.
* Must be in the range [0,size()).
* @return The component removed (a String).
* @exception ArrayIndexOutOfBoundsException
* If posn is outside the specified range (includes case where
* compound name is empty).
* @exception InvalidNameException If deleting the component
* would violate the compound name's syntax.
*/
public Object remove(int posn) throws InvalidNameException {
return impl.remove(posn);
}
/**
* Overridden to avoid implementation dependency.
* @serialData The syntax <tt>Properties</tt>, followed by
* the number of components (an <tt>int</tt>), and the individual
* components (each a <tt>String</tt>).
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.writeObject(mySyntax);
s.writeInt(size());
Enumeration<String> comps = getAll();
while (comps.hasMoreElements()) {
s.writeObject(comps.nextElement());
}
}
/**
* Overridden to avoid implementation dependency.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
mySyntax = (Properties)s.readObject();
impl = new NameImpl(mySyntax);
int n = s.readInt(); // number of components
try {
while (--n >= 0) {
add((String)s.readObject());
}
} catch (InvalidNameException e) {
throw (new java.io.StreamCorruptedException("Invalid name"));
}
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 3513100557083972036L;
/*
// For testing
public static void main(String[] args) {
Properties dotSyntax = new Properties();
dotSyntax.put("jndi.syntax.direction", "right_to_left");
dotSyntax.put("jndi.syntax.separator", ".");
dotSyntax.put("jndi.syntax.ignorecase", "true");
dotSyntax.put("jndi.syntax.escape", "\\");
// dotSyntax.put("jndi.syntax.beginquote", "\"");
// dotSyntax.put("jndi.syntax.beginquote2", "'");
Name first = null;
try {
for (int i = 0; i < args.length; i++) {
Name name;
Enumeration e;
System.out.println("Given name: " + args[i]);
name = new CompoundName(args[i], dotSyntax);
if (first == null) {
first = name;
}
e = name.getComponents();
while (e.hasMoreElements()) {
System.out.println("Element: " + e.nextElement());
}
System.out.println("Constructed name: " + name.toString());
System.out.println("Compare " + first.toString() + " with "
+ name.toString() + " = " + first.compareTo(name));
}
} catch (Exception ne) {
ne.printStackTrace();
}
}
*/
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when there is a configuration problem.
* This can arise when installation of a provider was
* not done correctly, or if there are configuration problems with the
* server, or if configuration information required to access
* the provider or service is malformed or missing.
* For example, a request to use SSL as the security protocol when
* the service provider software was not configured with the SSL
* component would cause such an exception. Another example is
* if the provider requires that a URL be specified as one of the
* environment properties but the client failed to provide it.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class ConfigurationException extends NamingException {
/**
* Constructs a new instance of ConfigurationException using an
* explanation. All other fields default to null.
*
* @param explanation A possibly null string containing
* additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public ConfigurationException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of ConfigurationException with
* all name resolution fields and explanation initialized to null.
*/
public ConfigurationException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -2535156726228855704L;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when attempting to destroy a context that
* is not empty.
*<p>
* If the program wants to handle this exception in particular, it
* should catch ContextNotEmptyException explicitly before attempting to
* catch NamingException. For example, after catching ContextNotEmptyException,
* the program might try to remove the contents of the context before
* reattempting the destroy.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context#destroySubcontext
* @since 1.3
*/
public class ContextNotEmptyException extends NamingException {
/**
* Constructs a new instance of ContextNotEmptyException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null string containing
* additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public ContextNotEmptyException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of ContextNotEmptyException with
* all name resolution fields and explanation initialized to null.
*/
public ContextNotEmptyException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 1090963683348219877L;
}

View File

@@ -0,0 +1,565 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Hashtable;
import javax.naming.spi.NamingManager;
import com.sun.naming.internal.ResourceManager;
/**
* This class is the starting context for performing naming operations.
*<p>
* All naming operations are relative to a context.
* The initial context implements the Context interface and
* provides the starting point for resolution of names.
*<p>
* <a name=ENVIRONMENT></a>
* When the initial context is constructed, its environment
* is initialized with properties defined in the environment parameter
* passed to the constructor, and in any
* <a href=Context.html#RESOURCEFILES>application resource files</a>.
* In addition, a small number of standard JNDI properties may
* be specified as system properties or as applet parameters
* (through the use of {@link Context#APPLET}).
* These special properties are listed in the field detail sections of the
* <a href=Context.html#field_detail><tt>Context</tt></a> and
* <a href=ldap/LdapContext.html#field_detail><tt>LdapContext</tt></a>
* interface documentation.
*<p>
* JNDI determines each property's value by merging
* the values from the following two sources, in order:
* <ol>
* <li>
* The first occurrence of the property from the constructor's
* environment parameter and (for appropriate properties) the applet
* parameters and system properties.
* <li>
* The application resource files (<tt>jndi.properties</tt>).
* </ol>
* For each property found in both of these two sources, or in
* more than one application resource file, the property's value
* is determined as follows. If the property is
* one of the standard JNDI properties that specify a list of JNDI
* factories (see <a href=Context.html#LISTPROPS><tt>Context</tt></a>),
* all of the values are
* concatenated into a single colon-separated list. For other
* properties, only the first value found is used.
*
*<p>
* The initial context implementation is determined at runtime.
* The default policy uses the environment property
* "{@link Context#INITIAL_CONTEXT_FACTORY java.naming.factory.initial}",
* which contains the class name of the initial context factory.
* An exception to this policy is made when resolving URL strings, as described
* below.
*<p>
* When a URL string (a <tt>String</tt> of the form
* <em>scheme_id:rest_of_name</em>) is passed as a name parameter to
* any method, a URL context factory for handling that scheme is
* located and used to resolve the URL. If no such factory is found,
* the initial context specified by
* <tt>"java.naming.factory.initial"</tt> is used. Similarly, when a
* <tt>CompositeName</tt> object whose first component is a URL string is
* passed as a name parameter to any method, a URL context factory is
* located and used to resolve the first name component.
* See {@link NamingManager#getURLContext
* <tt>NamingManager.getURLContext()</tt>} for a description of how URL
* context factories are located.
*<p>
* This default policy of locating the initial context and URL context
* factories may be overridden
* by calling
* <tt>NamingManager.setInitialContextFactoryBuilder()</tt>.
*<p>
* NoInitialContextException is thrown when an initial context cannot
* be instantiated. This exception can be thrown during any interaction
* with the InitialContext, not only when the InitialContext is constructed.
* For example, the implementation of the initial context might lazily
* retrieve the context only when actual methods are invoked on it.
* The application should not have any dependency on when the existence
* of an initial context is determined.
*<p>
* When the environment property "java.naming.factory.initial" is
* non-null, the InitialContext constructor will attempt to create the
* initial context specified therein. At that time, the initial context factory
* involved might throw an exception if a problem is encountered. However,
* it is provider implementation-dependent when it verifies and indicates
* to the users of the initial context any environment property- or
* connection- related problems. It can do so lazily--delaying until
* an operation is performed on the context, or eagerly, at the time
* the context is constructed.
*<p>
* An InitialContext instance is not synchronized against concurrent
* access by multiple threads. Multiple threads each manipulating a
* different InitialContext instance need not synchronize.
* Threads that need to access a single InitialContext instance
* concurrently should synchronize amongst themselves and provide the
* necessary locking.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context
* @see NamingManager#setInitialContextFactoryBuilder
* NamingManager.setInitialContextFactoryBuilder
* @since JNDI 1.1 / Java 2 Platform, Standard Edition, v 1.3
*/
public class InitialContext implements Context {
/**
* The environment associated with this InitialContext.
* It is initialized to null and is updated by the constructor
* that accepts an environment or by the <tt>init()</tt> method.
* @see #addToEnvironment
* @see #removeFromEnvironment
* @see #getEnvironment
*/
protected Hashtable<Object,Object> myProps = null;
/**
* Field holding the result of calling NamingManager.getInitialContext().
* It is set by getDefaultInitCtx() the first time getDefaultInitCtx()
* is called. Subsequent invocations of getDefaultInitCtx() return
* the value of defaultInitCtx.
* @see #getDefaultInitCtx
*/
protected Context defaultInitCtx = null;
/**
* Field indicating whether the initial context has been obtained
* by calling NamingManager.getInitialContext().
* If true, its result is in <code>defaultInitCtx</code>.
*/
protected boolean gotDefault = false;
/**
* Constructs an initial context with the option of not
* initializing it. This may be used by a constructor in
* a subclass when the value of the environment parameter
* is not yet known at the time the <tt>InitialContext</tt>
* constructor is called. The subclass's constructor will
* call this constructor, compute the value of the environment,
* and then call <tt>init()</tt> before returning.
*
* @param lazy
* true means do not initialize the initial context; false
* is equivalent to calling <tt>new InitialContext()</tt>
* @throws NamingException if a naming exception is encountered
*
* @see #init(Hashtable)
* @since 1.3
*/
protected InitialContext(boolean lazy) throws NamingException {
if (!lazy) {
init(null);
}
}
/**
* Constructs an initial context.
* No environment properties are supplied.
* Equivalent to <tt>new InitialContext(null)</tt>.
*
* @throws NamingException if a naming exception is encountered
*
* @see #InitialContext(Hashtable)
*/
public InitialContext() throws NamingException {
init(null);
}
/**
* Constructs an initial context using the supplied environment.
* Environment properties are discussed in the class description.
*
* <p> This constructor will not modify <tt>environment</tt>
* or save a reference to it, but may save a clone.
* Caller should not modify mutable keys and values in
* <tt>environment</tt> after it has been passed to the constructor.
*
* @param environment
* environment used to create the initial context.
* Null indicates an empty environment.
*
* @throws NamingException if a naming exception is encountered
*/
public InitialContext(Hashtable<?,?> environment)
throws NamingException
{
if (environment != null) {
environment = (Hashtable)environment.clone();
}
init(environment);
}
/**
* Initializes the initial context using the supplied environment.
* Environment properties are discussed in the class description.
*
* <p> This method will modify <tt>environment</tt> and save
* a reference to it. The caller may no longer modify it.
*
* @param environment
* environment used to create the initial context.
* Null indicates an empty environment.
*
* @throws NamingException if a naming exception is encountered
*
* @see #InitialContext(boolean)
* @since 1.3
*/
@SuppressWarnings("unchecked")
protected void init(Hashtable<?,?> environment)
throws NamingException
{
myProps = (Hashtable<Object,Object>)
ResourceManager.getInitialEnvironment(environment);
if (myProps.get(Context.INITIAL_CONTEXT_FACTORY) != null) {
// user has specified initial context factory; try to get it
getDefaultInitCtx();
}
}
/**
* A static method to retrieve the named object.
* This is a shortcut method equivalent to invoking:
* <p>
* <code>
* InitialContext ic = new InitialContext();
* Object obj = ic.lookup();
* </code>
* <p> If <tt>name</tt> is empty, returns a new instance of this context
* (which represents the same naming context as this context, but its
* environment may be modified independently and it may be accessed
* concurrently).
*
* @param <T> the type of the returned object
* @param name
* the name of the object to look up
* @return the object bound to <tt>name</tt>
* @throws NamingException if a naming exception is encountered
*
* @see #doLookup(String)
* @see #lookup(Name)
* @since 1.6
*/
@SuppressWarnings("unchecked")
public static <T> T doLookup(Name name)
throws NamingException {
return (T) (new InitialContext()).lookup(name);
}
/**
* A static method to retrieve the named object.
* See {@link #doLookup(Name)} for details.
* @param <T> the type of the returned object
* @param name
* the name of the object to look up
* @return the object bound to <tt>name</tt>
* @throws NamingException if a naming exception is encountered
* @since 1.6
*/
@SuppressWarnings("unchecked")
public static <T> T doLookup(String name)
throws NamingException {
return (T) (new InitialContext()).lookup(name);
}
private static String getURLScheme(String str) {
int colon_posn = str.indexOf(':');
int slash_posn = str.indexOf('/');
if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
return str.substring(0, colon_posn);
return null;
}
/**
* Retrieves the initial context by calling
* <code>NamingManager.getInitialContext()</code>
* and cache it in defaultInitCtx.
* Set <code>gotDefault</code> so that we know we've tried this before.
* @return The non-null cached initial context.
* @exception NoInitialContextException If cannot find an initial context.
* @exception NamingException If a naming exception was encountered.
*/
protected Context getDefaultInitCtx() throws NamingException{
if (!gotDefault) {
defaultInitCtx = NamingManager.getInitialContext(myProps);
gotDefault = true;
}
if (defaultInitCtx == null)
throw new NoInitialContextException();
return defaultInitCtx;
}
/**
* Retrieves a context for resolving the string name <code>name</code>.
* If <code>name</code> name is a URL string, then attempt
* to find a URL context for it. If none is found, or if
* <code>name</code> is not a URL string, then return
* <code>getDefaultInitCtx()</code>.
*<p>
* See getURLOrDefaultInitCtx(Name) for description
* of how a subclass should use this method.
* @param name The non-null name for which to get the context.
* @return A URL context for <code>name</code> or the cached
* initial context. The result cannot be null.
* @exception NoInitialContextException If cannot find an initial context.
* @exception NamingException In a naming exception is encountered.
* @see javax.naming.spi.NamingManager#getURLContext
*/
protected Context getURLOrDefaultInitCtx(String name)
throws NamingException {
if (NamingManager.hasInitialContextFactoryBuilder()) {
return getDefaultInitCtx();
}
String scheme = getURLScheme(name);
if (scheme != null) {
Context ctx = NamingManager.getURLContext(scheme, myProps);
if (ctx != null) {
return ctx;
}
}
return getDefaultInitCtx();
}
/**
* Retrieves a context for resolving <code>name</code>.
* If the first component of <code>name</code> name is a URL string,
* then attempt to find a URL context for it. If none is found, or if
* the first component of <code>name</code> is not a URL string,
* then return <code>getDefaultInitCtx()</code>.
*<p>
* When creating a subclass of InitialContext, use this method as
* follows.
* Define a new method that uses this method to get an initial
* context of the desired subclass.
* <blockquote><pre>
* protected XXXContext getURLOrDefaultInitXXXCtx(Name name)
* throws NamingException {
* Context answer = getURLOrDefaultInitCtx(name);
* if (!(answer instanceof XXXContext)) {
* if (answer == null) {
* throw new NoInitialContextException();
* } else {
* throw new NotContextException("Not an XXXContext");
* }
* }
* return (XXXContext)answer;
* }
* </pre></blockquote>
* When providing implementations for the new methods in the subclass,
* use this newly defined method to get the initial context.
* <blockquote><pre>
* public Object XXXMethod1(Name name, ...) {
* throws NamingException {
* return getURLOrDefaultInitXXXCtx(name).XXXMethod1(name, ...);
* }
* </pre></blockquote>
*
* @param name The non-null name for which to get the context.
* @return A URL context for <code>name</code> or the cached
* initial context. The result cannot be null.
* @exception NoInitialContextException If cannot find an initial context.
* @exception NamingException In a naming exception is encountered.
*
* @see javax.naming.spi.NamingManager#getURLContext
*/
protected Context getURLOrDefaultInitCtx(Name name)
throws NamingException {
if (NamingManager.hasInitialContextFactoryBuilder()) {
return getDefaultInitCtx();
}
if (name.size() > 0) {
String first = name.get(0);
String scheme = getURLScheme(first);
if (scheme != null) {
Context ctx = NamingManager.getURLContext(scheme, myProps);
if (ctx != null) {
return ctx;
}
}
}
return getDefaultInitCtx();
}
// Context methods
// Most Javadoc is deferred to the Context interface.
public Object lookup(String name) throws NamingException {
return getURLOrDefaultInitCtx(name).lookup(name);
}
public Object lookup(Name name) throws NamingException {
return getURLOrDefaultInitCtx(name).lookup(name);
}
public void bind(String name, Object obj) throws NamingException {
getURLOrDefaultInitCtx(name).bind(name, obj);
}
public void bind(Name name, Object obj) throws NamingException {
getURLOrDefaultInitCtx(name).bind(name, obj);
}
public void rebind(String name, Object obj) throws NamingException {
getURLOrDefaultInitCtx(name).rebind(name, obj);
}
public void rebind(Name name, Object obj) throws NamingException {
getURLOrDefaultInitCtx(name).rebind(name, obj);
}
public void unbind(String name) throws NamingException {
getURLOrDefaultInitCtx(name).unbind(name);
}
public void unbind(Name name) throws NamingException {
getURLOrDefaultInitCtx(name).unbind(name);
}
public void rename(String oldName, String newName) throws NamingException {
getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
}
public void rename(Name oldName, Name newName)
throws NamingException
{
getURLOrDefaultInitCtx(oldName).rename(oldName, newName);
}
public NamingEnumeration<NameClassPair> list(String name)
throws NamingException
{
return (getURLOrDefaultInitCtx(name).list(name));
}
public NamingEnumeration<NameClassPair> list(Name name)
throws NamingException
{
return (getURLOrDefaultInitCtx(name).list(name));
}
public NamingEnumeration<Binding> listBindings(String name)
throws NamingException {
return getURLOrDefaultInitCtx(name).listBindings(name);
}
public NamingEnumeration<Binding> listBindings(Name name)
throws NamingException {
return getURLOrDefaultInitCtx(name).listBindings(name);
}
public void destroySubcontext(String name) throws NamingException {
getURLOrDefaultInitCtx(name).destroySubcontext(name);
}
public void destroySubcontext(Name name) throws NamingException {
getURLOrDefaultInitCtx(name).destroySubcontext(name);
}
public Context createSubcontext(String name) throws NamingException {
return getURLOrDefaultInitCtx(name).createSubcontext(name);
}
public Context createSubcontext(Name name) throws NamingException {
return getURLOrDefaultInitCtx(name).createSubcontext(name);
}
public Object lookupLink(String name) throws NamingException {
return getURLOrDefaultInitCtx(name).lookupLink(name);
}
public Object lookupLink(Name name) throws NamingException {
return getURLOrDefaultInitCtx(name).lookupLink(name);
}
public NameParser getNameParser(String name) throws NamingException {
return getURLOrDefaultInitCtx(name).getNameParser(name);
}
public NameParser getNameParser(Name name) throws NamingException {
return getURLOrDefaultInitCtx(name).getNameParser(name);
}
/**
* Composes the name of this context with a name relative to
* this context.
* Since an initial context may never be named relative
* to any context other than itself, the value of the
* <tt>prefix</tt> parameter must be an empty name (<tt>""</tt>).
*/
public String composeName(String name, String prefix)
throws NamingException {
return name;
}
/**
* Composes the name of this context with a name relative to
* this context.
* Since an initial context may never be named relative
* to any context other than itself, the value of the
* <tt>prefix</tt> parameter must be an empty name.
*/
public Name composeName(Name name, Name prefix)
throws NamingException
{
return (Name)name.clone();
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException {
myProps.put(propName, propVal);
return getDefaultInitCtx().addToEnvironment(propName, propVal);
}
public Object removeFromEnvironment(String propName)
throws NamingException {
myProps.remove(propName);
return getDefaultInitCtx().removeFromEnvironment(propName);
}
public Hashtable<?,?> getEnvironment() throws NamingException {
return getDefaultInitCtx().getEnvironment();
}
public void close() throws NamingException {
myProps = null;
if (defaultInitCtx != null) {
defaultInitCtx.close();
defaultInitCtx = null;
}
gotDefault = false;
}
public String getNameInNamespace() throws NamingException {
return getDefaultInitCtx().getNameInNamespace();
}
};

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when resources are not available to complete
* the requested operation. This might due to a lack of resources on
* the server or on the client. There are no restrictions to resource types,
* as different services might make use of different resources. Such
* restrictions might be due to physical limits and/or administrative quotas.
* Examples of limited resources are internal buffers, memory, network bandwidth.
*<p>
* InsufficientResourcesException is different from LimitExceededException in that
* the latter is due to user/system specified limits. See LimitExceededException
* for details.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InsufficientResourcesException extends NamingException {
/**
* Constructs a new instance of InsufficientResourcesException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public InsufficientResourcesException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of InsufficientResourcesException with
* all name resolution fields and explanation initialized to null.
*/
public InsufficientResourcesException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 6227672693037844532L;
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when the naming operation
* being invoked has been interrupted. For example, an application
* might interrupt a thread that is performing a search. If the
* search supports being interrupted, it will throw
* InterruptedNamingException. Whether an operation is interruptible
* and when depends on its implementation (as provided by the
* service providers). Different implementations have different ways
* of protecting their resources and objects from being damaged
* due to unexpected interrupts.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context
* @see javax.naming.directory.DirContext
* @see java.lang.Thread#interrupt
* @see java.lang.InterruptedException
* @since 1.3
*/
public class InterruptedNamingException extends NamingException {
/**
* Constructs an instance of InterruptedNamingException using an
* explanation of the problem.
* All name resolution-related fields are initialized to null.
* @param explanation A possibly null message explaining the problem.
* @see java.lang.Throwable#getMessage
*/
public InterruptedNamingException(String explanation) {
super(explanation);
}
/**
* Constructs an instance of InterruptedNamingException with
* all name resolution fields and explanation initialized to null.
*/
public InterruptedNamingException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 6404516648893194728L;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception indicates that the name being specified does
* not conform to the naming syntax of a naming system.
* This exception is thrown by any of the methods that does name
* parsing (such as those in Context, DirContext, CompositeName and CompoundName).
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context
* @see javax.naming.directory.DirContext
* @see CompositeName
* @see CompoundName
* @see NameParser
* @since 1.3
*/
public class InvalidNameException extends NamingException {
/**
* Constructs an instance of InvalidNameException using an
* explanation of the problem.
* All other fields are initialized to null.
* @param explanation A possibly null message explaining the problem.
* @see java.lang.Throwable#getMessage
*/
public InvalidNameException(String explanation) {
super(explanation);
}
/**
* Constructs an instance of InvalidNameException with
* all fields set to null.
*/
public InvalidNameException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -8370672380823801105L;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import javax.naming.Name;
/**
* This exception is thrown when a method
* terminates abnormally due to a user or system specified limit.
* This is different from a InsufficientResourceException in that
* LimitExceededException is due to a user/system specified limit.
* For example, running out of memory to complete the request would
* be an insufficient resource. The client asking for 10 answers and
* getting back 11 is a size limit exception.
*<p>
* Examples of these limits include client and server configuration
* limits such as size, time, number of hops, etc.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class LimitExceededException extends NamingException {
/**
* Constructs a new instance of LimitExceededException with
* all name resolution fields and explanation initialized to null.
*/
public LimitExceededException() {
super();
}
/**
* Constructs a new instance of LimitExceededException using an
* explanation. All other fields default to null.
* @param explanation Possibly null detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public LimitExceededException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -776898738660207856L;
}

View File

@@ -0,0 +1,304 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is used to describe problems encounter while resolving links.
* Addition information is added to the base NamingException for pinpointing
* the problem with the link.
*<p>
* Analogous to how NamingException captures name resolution information,
* LinkException captures "link"-name resolution information pinpointing
* the problem encountered while resolving a link. All these fields may
* be null.
* <ul>
* <li> Link Resolved Name. Portion of link name that has been resolved.
* <li> Link Resolved Object. Object to which resolution of link name proceeded.
* <li> Link Remaining Name. Portion of link name that has not been resolved.
* <li> Link Explanation. Detail explaining why link resolution failed.
*</ul>
*
*<p>
* A LinkException instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single LinkException instance should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context#lookupLink
* @see LinkRef
* @since 1.3
*/
/*<p>
* The serialized form of a LinkException object consists of the
* serialized fields of its NamingException superclass, the link resolved
* name (a Name object), the link resolved object, link remaining name
* (a Name object), and the link explanation String.
*/
public class LinkException extends NamingException {
/**
* Contains the part of the link that has been successfully resolved.
* It is a composite name and can be null.
* This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getLinkResolvedName
* @see #setLinkResolvedName
*/
protected Name linkResolvedName;
/**
* Contains the object to which resolution of the part of the link was successful.
* Can be null. This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getLinkResolvedObj
* @see #setLinkResolvedObj
*/
protected Object linkResolvedObj;
/**
* Contains the remaining link name that has not been resolved yet.
* It is a composite name and can be null.
* This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getLinkRemainingName
* @see #setLinkRemainingName
*/
protected Name linkRemainingName;
/**
* Contains the exception of why resolution of the link failed.
* Can be null. This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getLinkExplanation
* @see #setLinkExplanation
*/
protected String linkExplanation;
/**
* Constructs a new instance of LinkException with an explanation
* All the other fields are initialized to null.
* @param explanation A possibly null string containing additional
* detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public LinkException(String explanation) {
super(explanation);
linkResolvedName = null;
linkResolvedObj = null;
linkRemainingName = null;
linkExplanation = null;
}
/**
* Constructs a new instance of LinkException.
* All the non-link-related and link-related fields are initialized to null.
*/
public LinkException() {
super();
linkResolvedName = null;
linkResolvedObj = null;
linkRemainingName = null;
linkExplanation = null;
}
/**
* Retrieves the leading portion of the link name that was resolved
* successfully.
*
* @return The part of the link name that was resolved successfully.
* It is a composite name. It can be null, which means
* the link resolved name field has not been set.
* @see #getLinkResolvedObj
* @see #setLinkResolvedName
*/
public Name getLinkResolvedName() {
return this.linkResolvedName;
}
/**
* Retrieves the remaining unresolved portion of the link name.
* @return The part of the link name that has not been resolved.
* It is a composite name. It can be null, which means
* the link remaining name field has not been set.
* @see #setLinkRemainingName
*/
public Name getLinkRemainingName() {
return this.linkRemainingName;
}
/**
* Retrieves the object to which resolution was successful.
* This is the object to which the resolved link name is bound.
*
* @return The possibly null object that was resolved so far.
* If null, it means the link resolved object field has not been set.
* @see #getLinkResolvedName
* @see #setLinkResolvedObj
*/
public Object getLinkResolvedObj() {
return this.linkResolvedObj;
}
/**
* Retrieves the explanation associated with the problem encounter
* when resolving a link.
*
* @return The possibly null detail string explaining more about the problem
* with resolving a link.
* If null, it means there is no
* link detail message for this exception.
* @see #setLinkExplanation
*/
public String getLinkExplanation() {
return this.linkExplanation;
}
/**
* Sets the explanation associated with the problem encounter
* when resolving a link.
*
* @param msg The possibly null detail string explaining more about the problem
* with resolving a link. If null, it means no detail will be recorded.
* @see #getLinkExplanation
*/
public void setLinkExplanation(String msg) {
this.linkExplanation = msg;
}
/**
* Sets the resolved link name field of this exception.
*<p>
* <tt>name</tt> is a composite name. If the intent is to set
* this field using a compound name or string, you must
* "stringify" the compound name, and create a composite
* name with a single component using the string. You can then
* invoke this method using the resulting composite name.
*<p>
* A copy of <code>name</code> is made and stored.
* Subsequent changes to <code>name</code> does not
* affect the copy in this NamingException and vice versa.
*
*
* @param name The name to set resolved link name to. This can be null.
* If null, it sets the link resolved name field to null.
* @see #getLinkResolvedName
*/
public void setLinkResolvedName(Name name) {
if (name != null) {
this.linkResolvedName = (Name)(name.clone());
} else {
this.linkResolvedName = null;
}
}
/**
* Sets the remaining link name field of this exception.
*<p>
* <tt>name</tt> is a composite name. If the intent is to set
* this field using a compound name or string, you must
* "stringify" the compound name, and create a composite
* name with a single component using the string. You can then
* invoke this method using the resulting composite name.
*<p>
* A copy of <code>name</code> is made and stored.
* Subsequent changes to <code>name</code> does not
* affect the copy in this NamingException and vice versa.
*
* @param name The name to set remaining link name to. This can be null.
* If null, it sets the remaining name field to null.
* @see #getLinkRemainingName
*/
public void setLinkRemainingName(Name name) {
if (name != null)
this.linkRemainingName = (Name)(name.clone());
else
this.linkRemainingName = null;
}
/**
* Sets the link resolved object field of this exception.
* This indicates the last successfully resolved object of link name.
* @param obj The object to set link resolved object to. This can be null.
* If null, the link resolved object field is set to null.
* @see #getLinkResolvedObj
*/
public void setLinkResolvedObj(Object obj) {
this.linkResolvedObj = obj;
}
/**
* Generates the string representation of this exception.
* This string consists of the NamingException information plus
* the link's remaining name.
* This string is used for debugging and not meant to be interpreted
* programmatically.
* @return The non-null string representation of this link exception.
*/
public String toString() {
return super.toString() + "; Link Remaining Name: '" +
this.linkRemainingName + "'";
}
/**
* Generates the string representation of this exception.
* This string consists of the NamingException information plus
* the additional information of resolving the link.
* If 'detail' is true, the string also contains information on
* the link resolved object. If false, this method is the same
* as the form of toString() that accepts no parameters.
* This string is used for debugging and not meant to be interpreted
* programmatically.
*
* @param detail If true, add information about the link resolved
* object.
* @return The non-null string representation of this link exception.
*/
public String toString(boolean detail) {
if (!detail || this.linkResolvedObj == null)
return this.toString();
return this.toString() + "; Link Resolved Object: " +
this.linkResolvedObj;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -7967662604076777712L;
};

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when
* a loop was detected will attempting to resolve a link, or an implementation
* specific limit on link counts has been reached.
* <p>
* Synchronization and serialization issues that apply to LinkException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see LinkRef
* @since 1.3
*/
public class LinkLoopException extends LinkException {
/**
* Constructs a new instance of LinkLoopException with an explanation
* All the other fields are initialized to null.
* @param explanation A possibly null string containing additional
* detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public LinkLoopException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of LinkLoopException.
* All the non-link-related and link-related fields are initialized to null.
*/
public LinkLoopException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3119189944325198009L;
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents a Reference whose contents is a name, called the link name,
* that is bound to an atomic name in a context.
*<p>
* The name is a URL, or a name to be resolved relative to the initial
* context, or if the first character of the name is ".", the name
* is relative to the context in which the link is bound.
*<p>
* Normal resolution of names in context operations always follow links.
* Resolution of the link name itself may cause resolution to pass through
* other links. This gives rise to the possibility of a cycle of links whose
* resolution could not terminate normally. As a simple means to avoid such
* non-terminating resolutions, service providers may define limits on the
* number of links that may be involved in any single operation invoked
* by the caller.
*<p>
* A LinkRef contains a single StringRefAddr, whose type is "LinkAddress",
* and whose contents is the link name. The class name field of the
* Reference is that of this (LinkRef) class.
*<p>
* LinkRef is bound to a name using the normal Context.bind()/rebind(), and
* DirContext.bind()/rebind(). Context.lookupLink() is used to retrieve the link
* itself if the terminal atomic name is bound to a link.
*<p>
* Many naming systems support a native notion of link that may be used
* within the naming system itself. JNDI does not specify whether
* there is any relationship between such native links and JNDI links.
*<p>
* A LinkRef instance is not synchronized against concurrent access by multiple
* threads. Threads that need to access a LinkRef instance concurrently should
* synchronize amongst themselves and provide the necessary locking.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see LinkException
* @see LinkLoopException
* @see MalformedLinkException
* @see Context#lookupLink
* @since 1.3
*/
/*<p>
* The serialized form of a LinkRef object consists of the serialized
* fields of its Reference superclass.
*/
public class LinkRef extends Reference {
/* code for link handling */
static final String linkClassName = LinkRef.class.getName();
static final String linkAddrType = "LinkAddress";
/**
* Constructs a LinkRef for a name.
* @param linkName The non-null name for which to create this link.
*/
public LinkRef(Name linkName) {
super(linkClassName, new StringRefAddr(linkAddrType, linkName.toString()));
}
/**
* Constructs a LinkRef for a string name.
* @param linkName The non-null name for which to create this link.
*/
public LinkRef(String linkName) {
super(linkClassName, new StringRefAddr(linkAddrType, linkName));
}
/**
* Retrieves the name of this link.
*
* @return The non-null name of this link.
* @exception MalformedLinkException If a link name could not be extracted
* @exception NamingException If a naming exception was encountered.
*/
public String getLinkName() throws NamingException {
if (className != null && className.equals(linkClassName)) {
RefAddr addr = get(linkAddrType);
if (addr != null && addr instanceof StringRefAddr) {
return (String)((StringRefAddr)addr).getContent();
}
}
throw new MalformedLinkException();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -5386290613498931298L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when a malformed link was encountered while
* resolving or constructing a link.
* <p>
* Synchronization and serialization issues that apply to LinkException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see LinkRef#getLinkName
* @see LinkRef
* @since 1.3
*/
public class MalformedLinkException extends LinkException {
/**
* Constructs a new instance of MalformedLinkException with an explanation
* All the other fields are initialized to null.
* @param explanation A possibly null string containing additional
* detail about this exception.
*/
public MalformedLinkException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of Malformed LinkException.
* All fields are initialized to null.
*/
public MalformedLinkException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3066740437737830242L;
}

View File

@@ -0,0 +1,277 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Enumeration;
/**
* The <tt>Name</tt> interface represents a generic name -- an ordered
* sequence of components. It can be a composite name (names that
* span multiple namespaces), or a compound name (names that are
* used within individual hierarchical naming systems).
*
* <p> There can be different implementations of <tt>Name</tt>; for example,
* composite names, URLs, or namespace-specific compound names.
*
* <p> The components of a name are numbered. The indexes of a name
* with N components range from 0 up to, but not including, N. This
* range may be written as [0,N).
* The most significant component is at index 0.
* An empty name has no components.
*
* <p> None of the methods in this interface accept null as a valid
* value for a parameter that is a name or a name component.
* Likewise, methods that return a name or name component never return null.
*
* <p> An instance of a <tt>Name</tt> may not be synchronized against
* concurrent multithreaded access if that access is not read-only.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author R. Vasudevan
* @since 1.3
*/
public interface Name
extends Cloneable, java.io.Serializable, Comparable<Object>
{
/**
* The class fingerprint that is set to indicate
* serialization compatibility with a previous
* version of the class.
*/
static final long serialVersionUID = -3617482732056931635L;
/**
* Generates a new copy of this name.
* Subsequent changes to the components of this name will not
* affect the new copy, and vice versa.
*
* @return a copy of this name
*
* @see Object#clone()
*/
public Object clone();
/**
* Compares this name with another name for order.
* Returns a negative integer, zero, or a positive integer as this
* name is less than, equal to, or greater than the given name.
*
* <p> As with <tt>Object.equals()</tt>, the notion of ordering for names
* depends on the class that implements this interface.
* For example, the ordering may be
* based on lexicographical ordering of the name components.
* Specific attributes of the name, such as how it treats case,
* may affect the ordering. In general, two names of different
* classes may not be compared.
*
* @param obj the non-null object to compare against.
* @return a negative integer, zero, or a positive integer as this name
* is less than, equal to, or greater than the given name
* @throws ClassCastException if obj is not a <tt>Name</tt> of a
* type that may be compared with this name
*
* @see Comparable#compareTo(Object)
*/
public int compareTo(Object obj);
/**
* Returns the number of components in this name.
*
* @return the number of components in this name
*/
public int size();
/**
* Determines whether this name is empty.
* An empty name is one with zero components.
*
* @return true if this name is empty, false otherwise
*/
public boolean isEmpty();
/**
* Retrieves the components of this name as an enumeration
* of strings. The effect on the enumeration of updates to
* this name is undefined. If the name has zero components,
* an empty (non-null) enumeration is returned.
*
* @return an enumeration of the components of this name, each a string
*/
public Enumeration<String> getAll();
/**
* Retrieves a component of this name.
*
* @param posn
* the 0-based index of the component to retrieve.
* Must be in the range [0,size()).
* @return the component at index posn
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
*/
public String get(int posn);
/**
* Creates a name whose components consist of a prefix of the
* components of this name. Subsequent changes to
* this name will not affect the name that is returned and vice versa.
*
* @param posn
* the 0-based index of the component at which to stop.
* Must be in the range [0,size()].
* @return a name consisting of the components at indexes in
* the range [0,posn).
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
*/
public Name getPrefix(int posn);
/**
* Creates a name whose components consist of a suffix of the
* components in this name. Subsequent changes to
* this name do not affect the name that is returned and vice versa.
*
* @param posn
* the 0-based index of the component at which to start.
* Must be in the range [0,size()].
* @return a name consisting of the components at indexes in
* the range [posn,size()). If posn is equal to
* size(), an empty name is returned.
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
*/
public Name getSuffix(int posn);
/**
* Determines whether this name starts with a specified prefix.
* A name <tt>n</tt> is a prefix if it is equal to
* <tt>getPrefix(n.size())</tt>.
*
* @param n
* the name to check
* @return true if <tt>n</tt> is a prefix of this name, false otherwise
*/
public boolean startsWith(Name n);
/**
* Determines whether this name ends with a specified suffix.
* A name <tt>n</tt> is a suffix if it is equal to
* <tt>getSuffix(size()-n.size())</tt>.
*
* @param n
* the name to check
* @return true if <tt>n</tt> is a suffix of this name, false otherwise
*/
public boolean endsWith(Name n);
/**
* Adds the components of a name -- in order -- to the end of this name.
*
* @param suffix
* the components to add
* @return the updated name (not a new one)
*
* @throws InvalidNameException if <tt>suffix</tt> is not a valid name,
* or if the addition of the components would violate the syntax
* rules of this name
*/
public Name addAll(Name suffix) throws InvalidNameException;
/**
* Adds the components of a name -- in order -- at a specified position
* within this name.
* Components of this name at or after the index of the first new
* component are shifted up (away from 0) to accommodate the new
* components.
*
* @param n
* the components to add
* @param posn
* the index in this name at which to add the new
* components. Must be in the range [0,size()].
* @return the updated name (not a new one)
*
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
* @throws InvalidNameException if <tt>n</tt> is not a valid name,
* or if the addition of the components would violate the syntax
* rules of this name
*/
public Name addAll(int posn, Name n) throws InvalidNameException;
/**
* Adds a single component to the end of this name.
*
* @param comp
* the component to add
* @return the updated name (not a new one)
*
* @throws InvalidNameException if adding <tt>comp</tt> would violate
* the syntax rules of this name
*/
public Name add(String comp) throws InvalidNameException;
/**
* Adds a single component at a specified position within this name.
* Components of this name at or after the index of the new component
* are shifted up by one (away from index 0) to accommodate the new
* component.
*
* @param comp
* the component to add
* @param posn
* the index at which to add the new component.
* Must be in the range [0,size()].
* @return the updated name (not a new one)
*
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
* @throws InvalidNameException if adding <tt>comp</tt> would violate
* the syntax rules of this name
*/
public Name add(int posn, String comp) throws InvalidNameException;
/**
* Removes a component from this name.
* The component of this name at the specified position is removed.
* Components with indexes greater than this position
* are shifted down (toward index 0) by one.
*
* @param posn
* the index of the component to remove.
* Must be in the range [0,size()).
* @return the component removed (a String)
*
* @throws ArrayIndexOutOfBoundsException
* if posn is outside the specified range
* @throws InvalidNameException if deleting the component
* would violate the syntax rules of the name
*/
public Object remove(int posn) throws InvalidNameException;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown by methods to indicate that
* a binding cannot be added because the name is already bound to
* another object.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context#bind
* @see Context#rebind
* @see Context#createSubcontext
* @see javax.naming.directory.DirContext#bind
* @see javax.naming.directory.DirContext#rebind
* @see javax.naming.directory.DirContext#createSubcontext
* @since 1.3
*/
public class NameAlreadyBoundException extends NamingException {
/**
* Constructs a new instance of NameAlreadyBoundException using the
* explanation supplied. All other fields default to null.
*
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public NameAlreadyBoundException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NameAlreadyBoundException.
* All fields are set to null;
*/
public NameAlreadyBoundException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -8491441000356780586L;
}

View File

@@ -0,0 +1,298 @@
/*
* Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents the object name and class name pair of a binding
* found in a context.
*<p>
* A context consists of name-to-object bindings.
* The NameClassPair class represents the name and the
* class of the bound object. It consists
* of a name and a string representing the
* package-qualified class name.
*<p>
* Use subclassing for naming systems that generate contents of
* a name/class pair dynamically.
*<p>
* A NameClassPair instance is not synchronized against concurrent
* access by multiple threads. Threads that need to access a NameClassPair
* concurrently should synchronize amongst themselves and provide
* the necessary locking.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context#list
* @since 1.3
*/
/*
* <p>
* The serialized form of a NameClassPair object consists of the name (a
* String), class name (a String), and isRelative flag (a boolean).
*/
public class NameClassPair implements java.io.Serializable {
/**
* Contains the name of this NameClassPair.
* It is initialized by the constructor and can be updated using
* <tt>setName()</tt>.
* @serial
* @see #getName
* @see #setName
*/
private String name;
/**
*Contains the class name contained in this NameClassPair.
* It is initialized by the constructor and can be updated using
* <tt>setClassName()</tt>.
* @serial
* @see #getClassName
* @see #setClassName
*/
private String className;
/**
* Contains the full name of this NameClassPair within its
* own namespace.
* It is initialized using <tt>setNameInNamespace()</tt>
* @serial
* @see #getNameInNamespace
* @see #setNameInNamespace
*/
private String fullName = null;
/**
* Records whether the name of this <tt>NameClassPair</tt>
* is relative to the target context.
* It is initialized by the constructor and can be updated using
* <tt>setRelative()</tt>.
* @serial
* @see #isRelative
* @see #setRelative
* @see #getName
* @see #setName
*/
private boolean isRel = true;
/**
* Constructs an instance of a NameClassPair given its
* name and class name.
*
* @param name The non-null name of the object. It is relative
* to the <em>target context</em> (which is
* named by the first parameter of the <code>list()</code> method)
* @param className The possibly null class name of the object
* bound to name. It is null if the object bound is null.
* @see #getClassName
* @see #setClassName
* @see #getName
* @see #setName
*/
public NameClassPair(String name, String className) {
this.name = name;
this.className = className;
}
/**
* Constructs an instance of a NameClassPair given its
* name, class name, and whether it is relative to the listing context.
*
* @param name The non-null name of the object.
* @param className The possibly null class name of the object
* bound to name. It is null if the object bound is null.
* @param isRelative true if <code>name</code> is a name relative
* to the target context (which is named by the first parameter
* of the <code>list()</code> method); false if <code>name</code>
* is a URL string.
* @see #getClassName
* @see #setClassName
* @see #getName
* @see #setName
* @see #isRelative
* @see #setRelative
*/
public NameClassPair(String name, String className, boolean isRelative) {
this.name = name;
this.className = className;
this.isRel = isRelative;
}
/**
* Retrieves the class name of the object bound to the name of this binding.
* If a reference or some other indirect information is bound,
* retrieves the class name of the eventual object that
* will be returned by <tt>Binding.getObject()</tt>.
*
* @return The possibly null class name of object bound.
* It is null if the object bound is null.
* @see Binding#getObject
* @see Binding#getClassName
* @see #setClassName
*/
public String getClassName() {
return className;
}
/**
* Retrieves the name of this binding.
* If <tt>isRelative()</tt> is true, this name is relative to the
* target context (which is named by the first parameter of the
* <tt>list()</tt>).
* If <tt>isRelative()</tt> is false, this name is a URL string.
*
* @return The non-null name of this binding.
* @see #isRelative
* @see #setName
*/
public String getName() {
return name;
}
/**
* Sets the name of this binding.
*
* @param name the non-null string to use as the name.
* @see #getName
* @see #setRelative
*/
public void setName(String name) {
this.name = name;
}
/**
* Sets the class name of this binding.
*
* @param name the possibly null string to use as the class name.
* If null, <tt>Binding.getClassName()</tt> will return
* the actual class name of the object in the binding.
* The class name will be null if the object bound is null.
* @see #getClassName
* @see Binding#getClassName
*/
public void setClassName(String name) {
this.className = name;
}
/**
* Determines whether the name of this binding is
* relative to the target context (which is named by
* the first parameter of the <code>list()</code> method).
*
* @return true if the name of this binding is relative to the
* target context;
* false if the name of this binding is a URL string.
* @see #setRelative
* @see #getName
*/
public boolean isRelative() {
return isRel;
}
/**
* Sets whether the name of this binding is relative to the target
* context (which is named by the first parameter of the <code>list()</code>
* method).
*
* @param r If true, the name of binding is relative to the target context;
* if false, the name of binding is a URL string.
* @see #isRelative
* @see #setName
*/
public void setRelative(boolean r) {
isRel = r;
}
/**
* Retrieves the full name of this binding.
* The full name is the absolute name of this binding within
* its own namespace. See {@link Context#getNameInNamespace()}.
* <p>
*
* In naming systems for which the notion of full name does not
* apply to this binding an <tt>UnsupportedOperationException</tt>
* is thrown.
* This exception is also thrown when a service provider written before
* the introduction of the method is in use.
* <p>
* The string returned by this method is not a JNDI composite name and
* should not be passed directly to context methods.
*
* @return The full name of this binding.
* @throws UnsupportedOperationException if the notion of full name
* does not apply to this binding in the naming system.
* @since 1.5
* @see #setNameInNamespace
* @see #getName
*/
public String getNameInNamespace() {
if (fullName == null) {
throw new UnsupportedOperationException();
}
return fullName;
}
/**
* Sets the full name of this binding.
* This method must be called to set the full name whenever a
* <tt>NameClassPair</tt> is created and a full name is
* applicable to this binding.
* <p>
* Setting the full name to null, or not setting it at all, will
* cause <tt>getNameInNamespace()</tt> to throw an exception.
*
* @param fullName The full name to use.
* @since 1.5
* @see #getNameInNamespace
* @see #setName
*/
public void setNameInNamespace(String fullName) {
this.fullName = fullName;
}
/**
* Generates the string representation of this name/class pair.
* The string representation consists of the name and class name separated
* by a colon (':').
* The contents of this string is useful
* for debugging and is not meant to be interpreted programmatically.
*
* @return The string representation of this name/class pair.
*/
public String toString() {
return (isRelative() ? "" : "(not relative)") + getName() + ": " +
getClassName();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 5620776610160863339L;
}

View File

@@ -0,0 +1,735 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Locale;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Properties;
import java.util.NoSuchElementException;
/**
* The implementation class for CompoundName and CompositeName.
* This class is package private.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Aravindan Ranganathan
* @since 1.3
*/
class NameImpl {
private static final byte LEFT_TO_RIGHT = 1;
private static final byte RIGHT_TO_LEFT = 2;
private static final byte FLAT = 0;
private Vector<String> components;
private byte syntaxDirection = LEFT_TO_RIGHT;
private String syntaxSeparator = "/";
private String syntaxSeparator2 = null;
private boolean syntaxCaseInsensitive = false;
private boolean syntaxTrimBlanks = false;
private String syntaxEscape = "\\";
private String syntaxBeginQuote1 = "\"";
private String syntaxEndQuote1 = "\"";
private String syntaxBeginQuote2 = "'";
private String syntaxEndQuote2 = "'";
private String syntaxAvaSeparator = null;
private String syntaxTypevalSeparator = null;
// escapingStyle gives the method used at creation time for
// quoting or escaping characters in the name. It is set to the
// first style of quote or escape encountered if and when the name
// is parsed.
private static final int STYLE_NONE = 0;
private static final int STYLE_QUOTE1 = 1;
private static final int STYLE_QUOTE2 = 2;
private static final int STYLE_ESCAPE = 3;
private int escapingStyle = STYLE_NONE;
// Returns true if "match" is not null, and n contains "match" at
// position i.
private final boolean isA(String n, int i, String match) {
return (match != null && n.startsWith(match, i));
}
private final boolean isMeta(String n, int i) {
return (isA(n, i, syntaxEscape) ||
isA(n, i, syntaxBeginQuote1) ||
isA(n, i, syntaxBeginQuote2) ||
isSeparator(n, i));
}
private final boolean isSeparator(String n, int i) {
return (isA(n, i, syntaxSeparator) ||
isA(n, i, syntaxSeparator2));
}
private final int skipSeparator(String name, int i) {
if (isA(name, i, syntaxSeparator)) {
i += syntaxSeparator.length();
} else if (isA(name, i, syntaxSeparator2)) {
i += syntaxSeparator2.length();
}
return (i);
}
private final int extractComp(String name, int i, int len, Vector<String> comps)
throws InvalidNameException {
String beginQuote;
String endQuote;
boolean start = true;
boolean one = false;
StringBuffer answer = new StringBuffer(len);
while (i < len) {
// handle quoted strings
if (start && ((one = isA(name, i, syntaxBeginQuote1)) ||
isA(name, i, syntaxBeginQuote2))) {
// record choice of quote chars being used
beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2;
endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2;
if (escapingStyle == STYLE_NONE) {
escapingStyle = one ? STYLE_QUOTE1 : STYLE_QUOTE2;
}
// consume string until matching quote
for (i += beginQuote.length();
((i < len) && !name.startsWith(endQuote, i));
i++) {
// skip escape character if it is escaping ending quote
// otherwise leave as is.
if (isA(name, i, syntaxEscape) &&
isA(name, i + syntaxEscape.length(), endQuote)) {
i += syntaxEscape.length();
}
answer.append(name.charAt(i)); // copy char
}
// no ending quote found
if (i >= len)
throw
new InvalidNameException(name + ": no close quote");
// new Exception("no close quote");
i += endQuote.length();
// verify that end-quote occurs at separator or end of string
if (i == len || isSeparator(name, i)) {
break;
}
// throw (new Exception(
throw (new InvalidNameException(name +
": close quote appears before end of component"));
} else if (isSeparator(name, i)) {
break;
} else if (isA(name, i, syntaxEscape)) {
if (isMeta(name, i + syntaxEscape.length())) {
// if escape precedes meta, consume escape and let
// meta through
i += syntaxEscape.length();
if (escapingStyle == STYLE_NONE) {
escapingStyle = STYLE_ESCAPE;
}
} else if (i + syntaxEscape.length() >= len) {
throw (new InvalidNameException(name +
": unescaped " + syntaxEscape + " at end of component"));
}
} else if (isA(name, i, syntaxTypevalSeparator) &&
((one = isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote1)) ||
isA(name, i+syntaxTypevalSeparator.length(), syntaxBeginQuote2))) {
// Handle quote occurring after typeval separator
beginQuote = one ? syntaxBeginQuote1 : syntaxBeginQuote2;
endQuote = one ? syntaxEndQuote1 : syntaxEndQuote2;
i += syntaxTypevalSeparator.length();
answer.append(syntaxTypevalSeparator+beginQuote); // add back
// consume string until matching quote
for (i += beginQuote.length();
((i < len) && !name.startsWith(endQuote, i));
i++) {
// skip escape character if it is escaping ending quote
// otherwise leave as is.
if (isA(name, i, syntaxEscape) &&
isA(name, i + syntaxEscape.length(), endQuote)) {
i += syntaxEscape.length();
}
answer.append(name.charAt(i)); // copy char
}
// no ending quote found
if (i >= len)
throw
new InvalidNameException(name + ": typeval no close quote");
i += endQuote.length();
answer.append(endQuote); // add back
// verify that end-quote occurs at separator or end of string
if (i == len || isSeparator(name, i)) {
break;
}
throw (new InvalidNameException(name.substring(i) +
": typeval close quote appears before end of component"));
}
answer.append(name.charAt(i++));
start = false;
}
if (syntaxDirection == RIGHT_TO_LEFT)
comps.insertElementAt(answer.toString(), 0);
else
comps.addElement(answer.toString());
return i;
}
private static boolean getBoolean(Properties p, String name) {
return toBoolean(p.getProperty(name));
}
private static boolean toBoolean(String name) {
return ((name != null) &&
name.toLowerCase(Locale.ENGLISH).equals("true"));
}
private final void recordNamingConvention(Properties p) {
String syntaxDirectionStr =
p.getProperty("jndi.syntax.direction", "flat");
if (syntaxDirectionStr.equals("left_to_right")) {
syntaxDirection = LEFT_TO_RIGHT;
} else if (syntaxDirectionStr.equals("right_to_left")) {
syntaxDirection = RIGHT_TO_LEFT;
} else if (syntaxDirectionStr.equals("flat")) {
syntaxDirection = FLAT;
} else {
throw new IllegalArgumentException(syntaxDirectionStr +
"is not a valid value for the jndi.syntax.direction property");
}
if (syntaxDirection != FLAT) {
syntaxSeparator = p.getProperty("jndi.syntax.separator");
syntaxSeparator2 = p.getProperty("jndi.syntax.separator2");
if (syntaxSeparator == null) {
throw new IllegalArgumentException(
"jndi.syntax.separator property required for non-flat syntax");
}
} else {
syntaxSeparator = null;
}
syntaxEscape = p.getProperty("jndi.syntax.escape");
syntaxCaseInsensitive = getBoolean(p, "jndi.syntax.ignorecase");
syntaxTrimBlanks = getBoolean(p, "jndi.syntax.trimblanks");
syntaxBeginQuote1 = p.getProperty("jndi.syntax.beginquote");
syntaxEndQuote1 = p.getProperty("jndi.syntax.endquote");
if (syntaxEndQuote1 == null && syntaxBeginQuote1 != null)
syntaxEndQuote1 = syntaxBeginQuote1;
else if (syntaxBeginQuote1 == null && syntaxEndQuote1 != null)
syntaxBeginQuote1 = syntaxEndQuote1;
syntaxBeginQuote2 = p.getProperty("jndi.syntax.beginquote2");
syntaxEndQuote2 = p.getProperty("jndi.syntax.endquote2");
if (syntaxEndQuote2 == null && syntaxBeginQuote2 != null)
syntaxEndQuote2 = syntaxBeginQuote2;
else if (syntaxBeginQuote2 == null && syntaxEndQuote2 != null)
syntaxBeginQuote2 = syntaxEndQuote2;
syntaxAvaSeparator = p.getProperty("jndi.syntax.separator.ava");
syntaxTypevalSeparator =
p.getProperty("jndi.syntax.separator.typeval");
}
NameImpl(Properties syntax) {
if (syntax != null) {
recordNamingConvention(syntax);
}
components = new Vector<>();
}
NameImpl(Properties syntax, String n) throws InvalidNameException {
this(syntax);
boolean rToL = (syntaxDirection == RIGHT_TO_LEFT);
boolean compsAllEmpty = true;
int len = n.length();
for (int i = 0; i < len; ) {
i = extractComp(n, i, len, components);
String comp = rToL
? components.firstElement()
: components.lastElement();
if (comp.length() >= 1) {
compsAllEmpty = false;
}
if (i < len) {
i = skipSeparator(n, i);
if ((i == len) && !compsAllEmpty) {
// Trailing separator found. Add an empty component.
if (rToL) {
components.insertElementAt("", 0);
} else {
components.addElement("");
}
}
}
}
}
NameImpl(Properties syntax, Enumeration<String> comps) {
this(syntax);
// %% comps could shrink in the middle.
while (comps.hasMoreElements())
components.addElement(comps.nextElement());
}
/*
// Determines whether this component needs any escaping.
private final boolean escapingNeeded(String comp) {
int len = comp.length();
for (int i = 0; i < len; i++) {
if (i == 0) {
if (isA(comp, 0, syntaxBeginQuote1) ||
isA(comp, 0, syntaxBeginQuote2)) {
return (true);
}
}
if (isSeparator(comp, i)) {
return (true);
}
if (isA(comp, i, syntaxEscape)) {
i += syntaxEscape.length();
if (i >= len || isMeta(comp, i)) {
return (true);
}
}
}
return (false);
}
*/
private final String stringifyComp(String comp) {
int len = comp.length();
boolean escapeSeparator = false, escapeSeparator2 = false;
String beginQuote = null, endQuote = null;
StringBuffer strbuf = new StringBuffer(len);
// determine whether there are any separators; if so escape
// or quote them
if (syntaxSeparator != null &&
comp.indexOf(syntaxSeparator) >= 0) {
if (syntaxBeginQuote1 != null) {
beginQuote = syntaxBeginQuote1;
endQuote = syntaxEndQuote1;
} else if (syntaxBeginQuote2 != null) {
beginQuote = syntaxBeginQuote2;
endQuote = syntaxEndQuote2;
} else if (syntaxEscape != null)
escapeSeparator = true;
}
if (syntaxSeparator2 != null &&
comp.indexOf(syntaxSeparator2) >= 0) {
if (syntaxBeginQuote1 != null) {
if (beginQuote == null) {
beginQuote = syntaxBeginQuote1;
endQuote = syntaxEndQuote1;
}
} else if (syntaxBeginQuote2 != null) {
if (beginQuote == null) {
beginQuote = syntaxBeginQuote2;
endQuote = syntaxEndQuote2;
}
} else if (syntaxEscape != null)
escapeSeparator2 = true;
}
// if quoting component,
if (beginQuote != null) {
// start string off with opening quote
strbuf = strbuf.append(beginQuote);
// component is being quoted, so we only need to worry about
// escaping end quotes that occur in component
for (int i = 0; i < len; ) {
if (comp.startsWith(endQuote, i)) {
// end-quotes must be escaped when inside a quoted string
strbuf.append(syntaxEscape).append(endQuote);
i += endQuote.length();
} else {
// no special treatment required
strbuf.append(comp.charAt(i++));
}
}
// end with closing quote
strbuf.append(endQuote);
} else {
// When component is not quoted, add escape for:
// 1. leading quote
// 2. an escape preceding any meta char
// 3. an escape at the end of a component
// 4. separator
// go through characters in component and escape where necessary
boolean start = true;
for (int i = 0; i < len; ) {
// leading quote must be escaped
if (start && isA(comp, i, syntaxBeginQuote1)) {
strbuf.append(syntaxEscape).append(syntaxBeginQuote1);
i += syntaxBeginQuote1.length();
} else if (start && isA(comp, i, syntaxBeginQuote2)) {
strbuf.append(syntaxEscape).append(syntaxBeginQuote2);
i += syntaxBeginQuote2.length();
} else
// Escape an escape preceding meta characters, or at end.
// Other escapes pass through.
if (isA(comp, i, syntaxEscape)) {
if (i + syntaxEscape.length() >= len) {
// escape an ending escape
strbuf.append(syntaxEscape);
} else if (isMeta(comp, i + syntaxEscape.length())) {
// escape meta strings
strbuf.append(syntaxEscape);
}
strbuf.append(syntaxEscape);
i += syntaxEscape.length();
} else
// escape unescaped separator
if (escapeSeparator && comp.startsWith(syntaxSeparator, i)) {
// escape separator
strbuf.append(syntaxEscape).append(syntaxSeparator);
i += syntaxSeparator.length();
} else if (escapeSeparator2 &&
comp.startsWith(syntaxSeparator2, i)) {
// escape separator2
strbuf.append(syntaxEscape).append(syntaxSeparator2);
i += syntaxSeparator2.length();
} else {
// no special treatment required
strbuf.append(comp.charAt(i++));
}
start = false;
}
}
return (strbuf.toString());
}
public String toString() {
StringBuffer answer = new StringBuffer();
String comp;
boolean compsAllEmpty = true;
int size = components.size();
for (int i = 0; i < size; i++) {
if (syntaxDirection == RIGHT_TO_LEFT) {
comp =
stringifyComp(components.elementAt(size - 1 - i));
} else {
comp = stringifyComp(components.elementAt(i));
}
if ((i != 0) && (syntaxSeparator != null))
answer.append(syntaxSeparator);
if (comp.length() >= 1)
compsAllEmpty = false;
answer = answer.append(comp);
}
if (compsAllEmpty && (size >= 1) && (syntaxSeparator != null))
answer = answer.append(syntaxSeparator);
return (answer.toString());
}
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof NameImpl)) {
NameImpl target = (NameImpl)obj;
if (target.size() == this.size()) {
Enumeration<String> mycomps = getAll();
Enumeration<String> comps = target.getAll();
while (mycomps.hasMoreElements()) {
// %% comps could shrink in the middle.
String my = mycomps.nextElement();
String his = comps.nextElement();
if (syntaxTrimBlanks) {
my = my.trim();
his = his.trim();
}
if (syntaxCaseInsensitive) {
if (!(my.equalsIgnoreCase(his)))
return false;
} else {
if (!(my.equals(his)))
return false;
}
}
return true;
}
}
return false;
}
/**
* Compares obj to this NameImpl to determine ordering.
* Takes into account syntactic properties such as
* elimination of blanks, case-ignore, etc, if relevant.
*
* Note: using syntax of this NameImpl and ignoring
* that of comparison target.
*/
public int compareTo(NameImpl obj) {
if (this == obj) {
return 0;
}
int len1 = size();
int len2 = obj.size();
int n = Math.min(len1, len2);
int index1 = 0, index2 = 0;
while (n-- != 0) {
String comp1 = get(index1++);
String comp2 = obj.get(index2++);
// normalize according to syntax
if (syntaxTrimBlanks) {
comp1 = comp1.trim();
comp2 = comp2.trim();
}
int local;
if (syntaxCaseInsensitive) {
local = comp1.compareToIgnoreCase(comp2);
} else {
local = comp1.compareTo(comp2);
}
if (local != 0) {
return local;
}
}
return len1 - len2;
}
public int size() {
return (components.size());
}
public Enumeration<String> getAll() {
return components.elements();
}
public String get(int posn) {
return components.elementAt(posn);
}
public Enumeration<String> getPrefix(int posn) {
if (posn < 0 || posn > size()) {
throw new ArrayIndexOutOfBoundsException(posn);
}
return new NameImplEnumerator(components, 0, posn);
}
public Enumeration<String> getSuffix(int posn) {
int cnt = size();
if (posn < 0 || posn > cnt) {
throw new ArrayIndexOutOfBoundsException(posn);
}
return new NameImplEnumerator(components, posn, cnt);
}
public boolean isEmpty() {
return (components.isEmpty());
}
public boolean startsWith(int posn, Enumeration<String> prefix) {
if (posn < 0 || posn > size()) {
return false;
}
try {
Enumeration<String> mycomps = getPrefix(posn);
while (mycomps.hasMoreElements()) {
String my = mycomps.nextElement();
String his = prefix.nextElement();
if (syntaxTrimBlanks) {
my = my.trim();
his = his.trim();
}
if (syntaxCaseInsensitive) {
if (!(my.equalsIgnoreCase(his)))
return false;
} else {
if (!(my.equals(his)))
return false;
}
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
public boolean endsWith(int posn, Enumeration<String> suffix) {
// posn is number of elements in suffix
// startIndex is the starting position in this name
// at which to start the comparison. It is calculated by
// subtracting 'posn' from size()
int startIndex = size() - posn;
if (startIndex < 0 || startIndex > size()) {
return false;
}
try {
Enumeration<String> mycomps = getSuffix(startIndex);
while (mycomps.hasMoreElements()) {
String my = mycomps.nextElement();
String his = suffix.nextElement();
if (syntaxTrimBlanks) {
my = my.trim();
his = his.trim();
}
if (syntaxCaseInsensitive) {
if (!(my.equalsIgnoreCase(his)))
return false;
} else {
if (!(my.equals(his)))
return false;
}
}
} catch (NoSuchElementException e) {
return false;
}
return true;
}
public boolean addAll(Enumeration<String> comps) throws InvalidNameException {
boolean added = false;
while (comps.hasMoreElements()) {
try {
String comp = comps.nextElement();
if (size() > 0 && syntaxDirection == FLAT) {
throw new InvalidNameException(
"A flat name can only have a single component");
}
components.addElement(comp);
added = true;
} catch (NoSuchElementException e) {
break; // "comps" has shrunk.
}
}
return added;
}
public boolean addAll(int posn, Enumeration<String> comps)
throws InvalidNameException {
boolean added = false;
for (int i = posn; comps.hasMoreElements(); i++) {
try {
String comp = comps.nextElement();
if (size() > 0 && syntaxDirection == FLAT) {
throw new InvalidNameException(
"A flat name can only have a single component");
}
components.insertElementAt(comp, i);
added = true;
} catch (NoSuchElementException e) {
break; // "comps" has shrunk.
}
}
return added;
}
public void add(String comp) throws InvalidNameException {
if (size() > 0 && syntaxDirection == FLAT) {
throw new InvalidNameException(
"A flat name can only have a single component");
}
components.addElement(comp);
}
public void add(int posn, String comp) throws InvalidNameException {
if (size() > 0 && syntaxDirection == FLAT) {
throw new InvalidNameException(
"A flat name can only zero or one component");
}
components.insertElementAt(comp, posn);
}
public Object remove(int posn) {
Object r = components.elementAt(posn);
components.removeElementAt(posn);
return r;
}
public int hashCode() {
int hash = 0;
for (Enumeration<String> e = getAll(); e.hasMoreElements();) {
String comp = e.nextElement();
if (syntaxTrimBlanks) {
comp = comp.trim();
}
if (syntaxCaseInsensitive) {
comp = comp.toLowerCase(Locale.ENGLISH);
}
hash += comp.hashCode();
}
return hash;
}
}
final
class NameImplEnumerator implements Enumeration<String> {
Vector<String> vector;
int count;
int limit;
NameImplEnumerator(Vector<String> v, int start, int lim) {
vector = v;
count = start;
limit = lim;
}
public boolean hasMoreElements() {
return count < limit;
}
public String nextElement() {
if (count < limit) {
return vector.elementAt(count++);
}
throw new NoSuchElementException("NameImplEnumerator");
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when a component of the name cannot be resolved
* because it is not bound.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NameNotFoundException extends NamingException {
/**
* Constructs a new instance of NameNotFoundException using the
* explanation supplied. All other fields default to null.
*
* @param explanation Possibly null additional detail about
* this exception.
* @see java.lang.Throwable#getMessage
*/
public NameNotFoundException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NameNotFoundException.
* all name resolution fields and explanation initialized to null.
*/
public NameNotFoundException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -8007156725367842053L;
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This interface is used for parsing names from a hierarchical
* namespace. The NameParser contains knowledge of the syntactic
* information (like left-to-right orientation, name separator, etc.)
* needed to parse names.
*
* The equals() method, when used to compare two NameParsers, returns
* true if and only if they serve the same namespace.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see CompoundName
* @see Name
* @since 1.3
*/
public interface NameParser {
/**
* Parses a name into its components.
*
* @param name The non-null string name to parse.
* @return A non-null parsed form of the name using the naming convention
* of this parser.
* @exception InvalidNameException If name does not conform to
* syntax defined for the namespace.
* @exception NamingException If a naming exception was encountered.
*/
Name parse(String name) throws NamingException;
}

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Enumeration;
/**
* This interface is for enumerating lists returned by
* methods in the javax.naming and javax.naming.directory packages.
* It extends Enumeration to allow as exceptions to be thrown during
* the enumeration.
*<p>
* When a method such as list(), listBindings(), or search() returns
* a NamingEnumeration, any exceptions encountered are reserved until
* all results have been returned. At the end of the enumeration, the
* exception is thrown (by hasMore());
* <p>
* For example, if the list() is
* returning only a partial answer, the corresponding exception would
* be PartialResultException. list() would first return a NamingEnumeration.
* When the last of the results has been returned by the NamingEnumeration's
* next(), invoking hasMore() would result in PartialResultException being thrown.
*<p>
* In another example, if a search() method was invoked with a specified
* size limit of 'n'. If the answer consists of more than 'n' results,
* search() would first return a NamingEnumeration.
* When the n'th result has been returned by invoking next() on the
* NamingEnumeration, a SizeLimitExceedException would then thrown when
* hasMore() is invoked.
*<p>
* Note that if the program uses hasMoreElements() and nextElement() instead
* to iterate through the NamingEnumeration, because these methods
* cannot throw exceptions, no exception will be thrown. Instead,
* in the previous example, after the n'th result has been returned by
* nextElement(), invoking hasMoreElements() would return false.
*<p>
* Note also that NoSuchElementException is thrown if the program invokes
* next() or nextElement() when there are no elements left in the enumeration.
* The program can always avoid this exception by using hasMore() and
* hasMoreElements() to check whether the end of the enumeration has been reached.
*<p>
* If an exception is thrown during an enumeration,
* the enumeration becomes invalid.
* Subsequent invocation of any method on that enumeration
* will yield undefined results.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Context#list
* @see Context#listBindings
* @see javax.naming.directory.DirContext#search
* @see javax.naming.directory.Attributes#getAll
* @see javax.naming.directory.Attributes#getIDs
* @see javax.naming.directory.Attribute#getAll
* @since 1.3
*/
public interface NamingEnumeration<T> extends Enumeration<T> {
/**
* Retrieves the next element in the enumeration.
* This method allows naming exceptions encountered while
* retrieving the next element to be caught and handled
* by the application.
* <p>
* Note that <tt>next()</tt> can also throw the runtime exception
* NoSuchElementException to indicate that the caller is
* attempting to enumerate beyond the end of the enumeration.
* This is different from a NamingException, which indicates
* that there was a problem in obtaining the next element,
* for example, due to a referral or server unavailability, etc.
*
* @return The possibly null element in the enumeration.
* null is only valid for enumerations that can return
* null (e.g. Attribute.getAll() returns an enumeration of
* attribute values, and an attribute value can be null).
* @exception NamingException If a naming exception is encountered while attempting
* to retrieve the next element. See NamingException
* and its subclasses for the possible naming exceptions.
* @exception java.util.NoSuchElementException If attempting to get the next element when none is available.
* @see java.util.Enumeration#nextElement
*/
public T next() throws NamingException;
/**
* Determines whether there are any more elements in the enumeration.
* This method allows naming exceptions encountered while
* determining whether there are more elements to be caught and handled
* by the application.
*
* @return true if there is more in the enumeration ; false otherwise.
* @exception NamingException
* If a naming exception is encountered while attempting
* to determine whether there is another element
* in the enumeration. See NamingException
* and its subclasses for the possible naming exceptions.
* @see java.util.Enumeration#hasMoreElements
*/
public boolean hasMore() throws NamingException;
/**
* Closes this enumeration.
*
* After this method has been invoked on this enumeration, the
* enumeration becomes invalid and subsequent invocation of any of
* its methods will yield undefined results.
* This method is intended for aborting an enumeration to free up resources.
* If an enumeration proceeds to the end--that is, until
* <tt>hasMoreElements()</tt> or <tt>hasMore()</tt> returns <tt>false</tt>--
* resources will be freed up automatically and there is no need to
* explicitly call <tt>close()</tt>.
*<p>
* This method indicates to the service provider that it is free
* to release resources associated with the enumeration, and can
* notify servers to cancel any outstanding requests. The <tt>close()</tt>
* method is a hint to implementations for managing their resources.
* Implementations are encouraged to use appropriate algorithms to
* manage their resources when client omits the <tt>close()</tt> calls.
*
* @exception NamingException If a naming exception is encountered
* while closing the enumeration.
* @since 1.3
*/
public void close() throws NamingException;
}

View File

@@ -0,0 +1,435 @@
/*
* Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This is the superclass of all exceptions thrown by
* operations in the Context and DirContext interfaces.
* The nature of the failure is described by the name of the subclass.
* This exception captures the information pinpointing where the operation
* failed, such as where resolution last proceeded to.
* <ul>
* <li> Resolved Name. Portion of name that has been resolved.
* <li> Resolved Object. Object to which resolution of name proceeded.
* <li> Remaining Name. Portion of name that has not been resolved.
* <li> Explanation. Detail explaining why name resolution failed.
* <li> Root Exception. The exception that caused this naming exception
* to be thrown.
*</ul>
* null is an acceptable value for any of these fields. When null,
* it means that no such information has been recorded for that field.
*<p>
* A NamingException instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single NamingException instance should lock the object.
*<p>
* This exception has been retrofitted to conform to
* the general purpose exception-chaining mechanism. The
* <i>root exception</i> (or <i>root cause</i>) is the same object as the
* <i>cause</i> returned by the {@link Throwable#getCause()} method.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NamingException extends Exception {
/**
* Contains the part of the name that has been successfully resolved.
* It is a composite name and can be null.
* This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getResolvedName
* @see #setResolvedName
*/
protected Name resolvedName;
/**
* Contains the object to which resolution of the part of the name was
* successful. Can be null.
* This field is initialized by the constructors.
* You should access and manipulate this field
* through its get and set methods.
* @serial
* @see #getResolvedObj
* @see #setResolvedObj
*/
protected Object resolvedObj;
/**
* Contains the remaining name that has not been resolved yet.
* It is a composite name and can be null.
* This field is initialized by the constructors.
* You should access and manipulate this field
* through its get, set, "append" methods.
* @serial
* @see #getRemainingName
* @see #setRemainingName
* @see #appendRemainingName
* @see #appendRemainingComponent
*/
protected Name remainingName;
/**
* Contains the original exception that caused this NamingException to
* be thrown. This field is set if there is additional
* information that could be obtained from the original
* exception, or if the original exception could not be
* mapped to a subclass of NamingException.
* Can be null.
*<p>
* This field predates the general-purpose exception chaining facility.
* The {@link #initCause(Throwable)} and {@link #getCause()} methods
* are now the preferred means of accessing this information.
*
* @serial
* @see #getRootCause
* @see #setRootCause(Throwable)
* @see #initCause(Throwable)
* @see #getCause
*/
protected Throwable rootException = null;
/**
* Constructs a new NamingException with an explanation.
* All unspecified fields are set to null.
*
* @param explanation A possibly null string containing
* additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public NamingException(String explanation) {
super(explanation);
resolvedName = remainingName = null;
resolvedObj = null;
}
/**
* Constructs a new NamingException.
* All fields are set to null.
*/
public NamingException() {
super();
resolvedName = remainingName = null;
resolvedObj = null;
}
/**
* Retrieves the leading portion of the name that was resolved
* successfully.
*
* @return The part of the name that was resolved successfully.
* It is a composite name. It can be null, which means
* the resolved name field has not been set.
* @see #getResolvedObj
* @see #setResolvedName
*/
public Name getResolvedName() {
return resolvedName;
}
/**
* Retrieves the remaining unresolved portion of the name.
* @return The part of the name that has not been resolved.
* It is a composite name. It can be null, which means
* the remaining name field has not been set.
* @see #setRemainingName
* @see #appendRemainingName
* @see #appendRemainingComponent
*/
public Name getRemainingName() {
return remainingName;
}
/**
* Retrieves the object to which resolution was successful.
* This is the object to which the resolved name is bound.
*
* @return The possibly null object that was resolved so far.
* null means that the resolved object field has not been set.
* @see #getResolvedName
* @see #setResolvedObj
*/
public Object getResolvedObj() {
return resolvedObj;
}
/**
* Retrieves the explanation associated with this exception.
*
* @return The possibly null detail string explaining more
* about this exception. If null, it means there is no
* detail message for this exception.
*
* @see java.lang.Throwable#getMessage
*/
public String getExplanation() {
return getMessage();
}
/**
* Sets the resolved name field of this exception.
*<p>
* <tt>name</tt> is a composite name. If the intent is to set
* this field using a compound name or string, you must
* "stringify" the compound name, and create a composite
* name with a single component using the string. You can then
* invoke this method using the resulting composite name.
*<p>
* A copy of <code>name</code> is made and stored.
* Subsequent changes to <code>name</code> does not
* affect the copy in this NamingException and vice versa.
*
* @param name The possibly null name to set resolved name to.
* If null, it sets the resolved name field to null.
* @see #getResolvedName
*/
public void setResolvedName(Name name) {
if (name != null)
resolvedName = (Name)(name.clone());
else
resolvedName = null;
}
/**
* Sets the remaining name field of this exception.
*<p>
* <tt>name</tt> is a composite name. If the intent is to set
* this field using a compound name or string, you must
* "stringify" the compound name, and create a composite
* name with a single component using the string. You can then
* invoke this method using the resulting composite name.
*<p>
* A copy of <code>name</code> is made and stored.
* Subsequent changes to <code>name</code> does not
* affect the copy in this NamingException and vice versa.
* @param name The possibly null name to set remaining name to.
* If null, it sets the remaining name field to null.
* @see #getRemainingName
* @see #appendRemainingName
* @see #appendRemainingComponent
*/
public void setRemainingName(Name name) {
if (name != null)
remainingName = (Name)(name.clone());
else
remainingName = null;
}
/**
* Sets the resolved object field of this exception.
* @param obj The possibly null object to set resolved object to.
* If null, the resolved object field is set to null.
* @see #getResolvedObj
*/
public void setResolvedObj(Object obj) {
resolvedObj = obj;
}
/**
* Add name as the last component in remaining name.
* @param name The component to add.
* If name is null, this method does not do anything.
* @see #setRemainingName
* @see #getRemainingName
* @see #appendRemainingName
*/
public void appendRemainingComponent(String name) {
if (name != null) {
try {
if (remainingName == null) {
remainingName = new CompositeName();
}
remainingName.add(name);
} catch (NamingException e) {
throw new IllegalArgumentException(e.toString());
}
}
}
/**
* Add components from 'name' as the last components in
* remaining name.
*<p>
* <tt>name</tt> is a composite name. If the intent is to append
* a compound name, you should "stringify" the compound name
* then invoke the overloaded form that accepts a String parameter.
*<p>
* Subsequent changes to <code>name</code> does not
* affect the remaining name field in this NamingException and vice versa.
* @param name The possibly null name containing ordered components to add.
* If name is null, this method does not do anything.
* @see #setRemainingName
* @see #getRemainingName
* @see #appendRemainingComponent
*/
public void appendRemainingName(Name name) {
if (name == null) {
return;
}
if (remainingName != null) {
try {
remainingName.addAll(name);
} catch (NamingException e) {
throw new IllegalArgumentException(e.toString());
}
} else {
remainingName = (Name)(name.clone());
}
}
/**
* Retrieves the root cause of this NamingException, if any.
* The root cause of a naming exception is used when the service provider
* wants to indicate to the caller a non-naming related exception
* but at the same time wants to use the NamingException structure
* to indicate how far the naming operation proceeded.
*<p>
* This method predates the general-purpose exception chaining facility.
* The {@link #getCause()} method is now the preferred means of obtaining
* this information.
*
* @return The possibly null exception that caused this naming
* exception. If null, it means no root cause has been
* set for this naming exception.
* @see #setRootCause
* @see #rootException
* @see #getCause
*/
public Throwable getRootCause() {
return rootException;
}
/**
* Records the root cause of this NamingException.
* If <tt>e</tt> is <tt>this</tt>, this method does not do anything.
*<p>
* This method predates the general-purpose exception chaining facility.
* The {@link #initCause(Throwable)} method is now the preferred means
* of recording this information.
*
* @param e The possibly null exception that caused the naming
* operation to fail. If null, it means this naming
* exception has no root cause.
* @see #getRootCause
* @see #rootException
* @see #initCause
*/
public void setRootCause(Throwable e) {
if (e != this) {
rootException = e;
}
}
/**
* Returns the cause of this exception. The cause is the
* throwable that caused this naming exception to be thrown.
* Returns <code>null</code> if the cause is nonexistent or
* unknown.
*
* @return the cause of this exception, or <code>null</code> if the
* cause is nonexistent or unknown.
* @see #initCause(Throwable)
* @since 1.4
*/
public Throwable getCause() {
return getRootCause();
}
/**
* Initializes the cause of this exception to the specified value.
* The cause is the throwable that caused this naming exception to be
* thrown.
*<p>
* This method may be called at most once.
*
* @param cause the cause, which is saved for later retrieval by
* the {@link #getCause()} method. A <tt>null</tt> value
* indicates that the cause is nonexistent or unknown.
* @return a reference to this <code>NamingException</code> instance.
* @throws IllegalArgumentException if <code>cause</code> is this
* exception. (A throwable cannot be its own cause.)
* @throws IllegalStateException if this method has already
* been called on this exception.
* @see #getCause
* @since 1.4
*/
public Throwable initCause(Throwable cause) {
super.initCause(cause);
setRootCause(cause);
return this;
}
/**
* Generates the string representation of this exception.
* The string representation consists of this exception's class name,
* its detailed message, and if it has a root cause, the string
* representation of the root cause exception, followed by
* the remaining name (if it is not null).
* This string is used for debugging and not meant to be interpreted
* programmatically.
*
* @return The non-null string containing the string representation
* of this exception.
*/
public String toString() {
String answer = super.toString();
if (rootException != null) {
answer += " [Root exception is " + rootException + "]";
}
if (remainingName != null) {
answer += "; remaining name '" + remainingName + "'";
}
return answer;
}
/**
* Generates the string representation in more detail.
* This string representation consists of the information returned
* by the toString() that takes no parameters, plus the string
* representation of the resolved object (if it is not null).
* This string is used for debugging and not meant to be interpreted
* programmatically.
*
* @param detail If true, include details about the resolved object
* in addition to the other information.
* @return The non-null string containing the string representation.
*/
public String toString(boolean detail) {
if (!detail || resolvedObj == null) {
return toString();
} else {
return (toString() + "; resolved object " + resolvedObj);
}
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -1299181962103167177L;
};

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This is the superclass of security-related exceptions
* thrown by operations in the Context and DirContext interfaces.
* The nature of the failure is described by the name of the subclass.
*<p>
* If the program wants to handle this exception in particular, it
* should catch NamingSecurityException explicitly before attempting to
* catch NamingException. A program might want to do this, for example,
* if it wants to treat security-related exceptions specially from
* other sorts of naming exception.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public abstract class NamingSecurityException extends NamingException {
/**
* Constructs a new instance of NamingSecurityException using the
* explanation supplied. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public NamingSecurityException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NamingSecurityException.
* All fields are initialized to null.
*/
public NamingSecurityException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 5855287647294685775L;
};

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when no initial context implementation
* can be created. The policy of how an initial context implementation
* is selected is described in the documentation of the InitialContext class.
*<p>
* This exception can be thrown during any interaction with the
* InitialContext, not only when the InitialContext is constructed.
* For example, the implementation of the initial context might lazily
* retrieve the context only when actual methods are invoked on it.
* The application should not have any dependency on when the existence
* of an initial context is determined.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see InitialContext
* @see javax.naming.directory.InitialDirContext
* @see javax.naming.spi.NamingManager#getInitialContext
* @see javax.naming.spi.NamingManager#setInitialContextFactoryBuilder
* @since 1.3
*/
public class NoInitialContextException extends NamingException {
/**
* Constructs an instance of NoInitialContextException.
* All fields are initialized to null.
*/
public NoInitialContextException() {
super();
}
/**
* Constructs an instance of NoInitialContextException with an
* explanation. All other fields are initialized to null.
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public NoInitialContextException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3413733186901258623L;
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when attempting to perform an operation
* for which the client has no permission. The access control/permission
* model is dictated by the directory/naming server.
*
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NoPermissionException extends NamingSecurityException {
/**
* Constructs a new instance of NoPermissionException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception.
*/
public NoPermissionException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NoPermissionException.
* All fields are initialized to null.
*/
public NoPermissionException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 8395332708699751775L;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when a naming operation proceeds to a point
* where a context is required to continue the operation, but the
* resolved object is not a context. For example, Context.destroy() requires
* that the named object be a context. If it is not, NotContextException
* is thrown. Another example is a non-context being encountered during
* the resolution phase of the Context methods.
*<p>
* It is also thrown when a particular subtype of context is required,
* such as a DirContext, and the resolved object is a context but not of
* the required subtype.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
* @see Context#destroySubcontext
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NotContextException extends NamingException {
/**
* Constructs a new instance of NotContextException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public NotContextException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NotContextException.
* All fields default to null.
*/
public NotContextException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 849752551644540417L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when a context implementation does not support
* the operation being invoked.
* For example, if a server does not support the Context.bind() method
* it would throw OperationNotSupportedException when the bind() method
* is invoked on it.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class OperationNotSupportedException extends NamingException {
/**
* Constructs a new instance of OperationNotSupportedException.
* All fields default to null.
*/
public OperationNotSupportedException() {
super();
}
/**
* Constructs a new instance of OperationNotSupportedException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception
* @see java.lang.Throwable#getMessage
*/
public OperationNotSupportedException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 5493232822427682064L;
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown to indicate that the result being returned
* or returned so far is partial, and that the operation cannot
* be completed. For example, when listing a context, this exception
* indicates that returned results only represents some of the bindings
* in the context.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class PartialResultException extends NamingException {
/**
* Constructs a new instance of the exception using the explanation
* message specified. All other fields default to null.
*
* @param explanation Possibly null detail explaining the exception.
*/
public PartialResultException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of PartialResultException.
* All fields default to null.
*/
public PartialResultException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 2572144970049426786L;
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents the address of a communications end-point.
* It consists of a type that describes the communication mechanism
* and an address contents determined by an RefAddr subclass.
*<p>
* For example, an address type could be "BSD Printer Address",
* which specifies that it is an address to be used with the BSD printing
* protocol. Its contents could be the machine name identifying the
* location of the printer server that understands this protocol.
*<p>
* A RefAddr is contained within a Reference.
*<p>
* RefAddr is an abstract class. Concrete implementations of it
* determine its synchronization properties.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see Reference
* @see LinkRef
* @see StringRefAddr
* @see BinaryRefAddr
* @since 1.3
*/
/*<p>
* The serialized form of a RefAddr object consists of only its type name
* String.
*/
public abstract class RefAddr implements java.io.Serializable {
/**
* Contains the type of this address.
* @serial
*/
protected String addrType;
/**
* Constructs a new instance of RefAddr using its address type.
*
* @param addrType A non-null string describing the type of the address.
*/
protected RefAddr(String addrType) {
this.addrType = addrType;
}
/**
* Retrieves the address type of this address.
*
* @return The non-null address type of this address.
*/
public String getType() {
return addrType;
}
/**
* Retrieves the contents of this address.
*
* @return The possibly null address contents.
*/
public abstract Object getContent();
/**
* Determines whether obj is equal to this RefAddr.
*<p>
* obj is equal to this RefAddr all of these conditions are true
*<ul>
*<li> non-null
*<li> instance of RefAddr
*<li> obj has the same address type as this RefAddr (using String.compareTo())
*<li> both obj and this RefAddr's contents are null or they are equal
* (using the equals() test).
*</ul>
* @param obj possibly null obj to check.
* @return true if obj is equal to this refaddr; false otherwise.
* @see #getContent
* @see #getType
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof RefAddr)) {
RefAddr target = (RefAddr)obj;
if (addrType.compareTo(target.addrType) == 0) {
Object thisobj = this.getContent();
Object thatobj = target.getContent();
if (thisobj == thatobj)
return true;
if (thisobj != null)
return thisobj.equals(thatobj);
}
}
return false;
}
/**
* Computes the hash code of this address using its address type and contents.
* The hash code is the sum of the hash code of the address type and
* the hash code of the address contents.
*
* @return The hash code of this address as an int.
* @see java.lang.Object#hashCode
*/
public int hashCode() {
return (getContent() == null)
? addrType.hashCode()
: addrType.hashCode() + getContent().hashCode();
}
/**
* Generates the string representation of this address.
* The string consists of the address's type and contents with labels.
* This representation is intended for display only and not to be parsed.
* @return The non-null string representation of this address.
*/
public String toString(){
StringBuffer str = new StringBuffer("Type: " + addrType + "\n");
str.append("Content: " + getContent() + "\n");
return (str.toString());
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -1468165120479154358L;
}

View File

@@ -0,0 +1,395 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Vector;
import java.util.Enumeration;
/**
* This class represents a reference to an object that is found outside of
* the naming/directory system.
*<p>
* Reference provides a way of recording address information about
* objects which themselves are not directly bound to the naming/directory system.
*<p>
* A Reference consists of an ordered list of addresses and class information
* about the object being referenced.
* Each address in the list identifies a communications endpoint
* for the same conceptual object. The "communications endpoint"
* is information that indicates how to contact the object. It could
* be, for example, a network address, a location in memory on the
* local machine, another process on the same machine, etc.
* The order of the addresses in the list may be of significance
* to object factories that interpret the reference.
*<p>
* Multiple addresses may arise for
* various reasons, such as replication or the object offering interfaces
* over more than one communication mechanism. The addresses are indexed
* starting with zero.
*<p>
* A Reference also contains information to assist in creating an instance
* of the object to which this Reference refers. It contains the class name
* of that object, and the class name and location of the factory to be used
* to create the object.
* The class factory location is a space-separated list of URLs representing
* the class path used to load the factory. When the factory class (or
* any class or resource upon which it depends) needs to be loaded,
* each URL is used (in order) to attempt to load the class.
*<p>
* A Reference instance is not synchronized against concurrent access by multiple
* threads. Threads that need to access a single Reference concurrently should
* synchronize amongst themselves and provide the necessary locking.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see RefAddr
* @see StringRefAddr
* @see BinaryRefAddr
* @since 1.3
*/
/*<p>
* The serialized form of a Reference object consists of the class
* name of the object being referenced (a String), a Vector of the
* addresses (each a RefAddr), the name of the class factory (a
* String), and the location of the class factory (a String).
*/
public class Reference implements Cloneable, java.io.Serializable {
/**
* Contains the fully-qualified name of the class of the object to which
* this Reference refers.
* @serial
* @see java.lang.Class#getName
*/
protected String className;
/**
* Contains the addresses contained in this Reference.
* Initialized by constructor.
* @serial
*/
protected Vector<RefAddr> addrs = null;
/**
* Contains the name of the factory class for creating
* an instance of the object to which this Reference refers.
* Initialized to null.
* @serial
*/
protected String classFactory = null;
/**
* Contains the location of the factory class.
* Initialized to null.
* @serial
*/
protected String classFactoryLocation = null;
/**
* Constructs a new reference for an object with class name 'className'.
* Class factory and class factory location are set to null.
* The newly created reference contains zero addresses.
*
* @param className The non-null class name of the object to which
* this reference refers.
*/
public Reference(String className) {
this.className = className;
addrs = new Vector<>();
}
/**
* Constructs a new reference for an object with class name 'className' and
* an address.
* Class factory and class factory location are set to null.
*
* @param className The non-null class name of the object to
* which this reference refers.
* @param addr The non-null address of the object.
*/
public Reference(String className, RefAddr addr) {
this.className = className;
addrs = new Vector<>();
addrs.addElement(addr);
}
/**
* Constructs a new reference for an object with class name 'className',
* and the class name and location of the object's factory.
*
* @param className The non-null class name of the object to which
* this reference refers.
* @param factory The possibly null class name of the object's factory.
* @param factoryLocation
* The possibly null location from which to load
* the factory (e.g. URL)
* @see javax.naming.spi.ObjectFactory
* @see javax.naming.spi.NamingManager#getObjectInstance
*/
public Reference(String className, String factory, String factoryLocation) {
this(className);
classFactory = factory;
classFactoryLocation = factoryLocation;
}
/**
* Constructs a new reference for an object with class name 'className',
* the class name and location of the object's factory, and the address for
* the object.
*
* @param className The non-null class name of the object to
* which this reference refers.
* @param factory The possibly null class name of the object's factory.
* @param factoryLocation The possibly null location from which
* to load the factory (e.g. URL)
* @param addr The non-null address of the object.
* @see javax.naming.spi.ObjectFactory
* @see javax.naming.spi.NamingManager#getObjectInstance
*/
public Reference(String className, RefAddr addr,
String factory, String factoryLocation) {
this(className, addr);
classFactory = factory;
classFactoryLocation = factoryLocation;
}
/**
* Retrieves the class name of the object to which this reference refers.
*
* @return The non-null fully-qualified class name of the object.
* (e.g. "java.lang.String")
*/
public String getClassName() {
return className;
}
/**
* Retrieves the class name of the factory of the object
* to which this reference refers.
*
* @return The possibly null fully-qualified class name of the factory.
* (e.g. "java.lang.String")
*/
public String getFactoryClassName() {
return classFactory;
}
/**
* Retrieves the location of the factory of the object
* to which this reference refers.
* If it is a codebase, then it is an ordered list of URLs,
* separated by spaces, listing locations from where the factory
* class definition should be loaded.
*
* @return The possibly null string containing the
* location for loading in the factory's class.
*/
public String getFactoryClassLocation() {
return classFactoryLocation;
}
/**
* Retrieves the first address that has the address type 'addrType'.
* String.compareTo() is used to test the equality of the address types.
*
* @param addrType The non-null address type for which to find the address.
* @return The address in this reference with address type 'addrType;
* null if no such address exist.
*/
public RefAddr get(String addrType) {
int len = addrs.size();
RefAddr addr;
for (int i = 0; i < len; i++) {
addr = addrs.elementAt(i);
if (addr.getType().compareTo(addrType) == 0)
return addr;
}
return null;
}
/**
* Retrieves the address at index posn.
* @param posn The index of the address to retrieve.
* @return The address at the 0-based index posn. It must be in the
* range [0,getAddressCount()).
* @exception ArrayIndexOutOfBoundsException If posn not in the specified
* range.
*/
public RefAddr get(int posn) {
return addrs.elementAt(posn);
}
/**
* Retrieves an enumeration of the addresses in this reference.
* When addresses are added, changed or removed from this reference,
* its effects on this enumeration are undefined.
*
* @return An non-null enumeration of the addresses
* (<tt>RefAddr</tt>) in this reference.
* If this reference has zero addresses, an enumeration with
* zero elements is returned.
*/
public Enumeration<RefAddr> getAll() {
return addrs.elements();
}
/**
* Retrieves the number of addresses in this reference.
*
* @return The nonnegative number of addresses in this reference.
*/
public int size() {
return addrs.size();
}
/**
* Adds an address to the end of the list of addresses.
*
* @param addr The non-null address to add.
*/
public void add(RefAddr addr) {
addrs.addElement(addr);
}
/**
* Adds an address to the list of addresses at index posn.
* All addresses at index posn or greater are shifted up
* the list by one (away from index 0).
*
* @param posn The 0-based index of the list to insert addr.
* @param addr The non-null address to add.
* @exception ArrayIndexOutOfBoundsException If posn not in the specified
* range.
*/
public void add(int posn, RefAddr addr) {
addrs.insertElementAt(addr, posn);
}
/**
* Deletes the address at index posn from the list of addresses.
* All addresses at index greater than posn are shifted down
* the list by one (towards index 0).
*
* @param posn The 0-based index of in address to delete.
* @return The address removed.
* @exception ArrayIndexOutOfBoundsException If posn not in the specified
* range.
*/
public Object remove(int posn) {
Object r = addrs.elementAt(posn);
addrs.removeElementAt(posn);
return r;
}
/**
* Deletes all addresses from this reference.
*/
public void clear() {
addrs.setSize(0);
}
/**
* Determines whether obj is a reference with the same addresses
* (in same order) as this reference.
* The addresses are checked using RefAddr.equals().
* In addition to having the same addresses, the Reference also needs to
* have the same class name as this reference.
* The class factory and class factory location are not checked.
* If obj is null or not an instance of Reference, null is returned.
*
* @param obj The possibly null object to check.
* @return true if obj is equal to this reference; false otherwise.
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof Reference)) {
Reference target = (Reference)obj;
// ignore factory information
if (target.className.equals(this.className) &&
target.size() == this.size()) {
Enumeration<RefAddr> mycomps = getAll();
Enumeration<RefAddr> comps = target.getAll();
while (mycomps.hasMoreElements())
if (!(mycomps.nextElement().equals(comps.nextElement())))
return false;
return true;
}
}
return false;
}
/**
* Computes the hash code of this reference.
* The hash code is the sum of the hash code of its addresses.
*
* @return A hash code of this reference as an int.
*/
public int hashCode() {
int hash = className.hashCode();
for (Enumeration<RefAddr> e = getAll(); e.hasMoreElements();)
hash += e.nextElement().hashCode();
return hash;
}
/**
* Generates the string representation of this reference.
* The string consists of the class name to which this reference refers,
* and the string representation of each of its addresses.
* This representation is intended for display only and not to be parsed.
*
* @return The non-null string representation of this reference.
*/
public String toString() {
StringBuffer buf = new StringBuffer("Reference Class Name: " +
className + "\n");
int len = addrs.size();
for (int i = 0; i < len; i++)
buf.append(get(i).toString());
return buf.toString();
}
/**
* Makes a copy of this reference using its class name
* list of addresses, class factory name and class factory location.
* Changes to the newly created copy does not affect this Reference
* and vice versa.
*/
public Object clone() {
Reference r = new Reference(className, classFactory, classFactoryLocation);
Enumeration<RefAddr> a = getAll();
r.addrs = new Vector<>();
while (a.hasMoreElements())
r.addrs.addElement(a.nextElement());
return r;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -1673475790065791735L;
};

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This interface is implemented by an object that can provide a
* Reference to itself.
*<p>
* A Reference represents a way of recording address information about
* objects which themselves are not directly bound to the naming system.
* Such objects can implement the Referenceable interface as a way
* for programs that use that object to determine what its Reference is.
* For example, when binding a object, if an object implements the
* Referenceable interface, getReference() can be invoked on the object to
* get its Reference to use for binding.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author R. Vasudevan
*
* @see Context#bind
* @see javax.naming.spi.NamingManager#getObjectInstance
* @see Reference
* @since 1.3
*/
public interface Referenceable {
/**
* Retrieves the Reference of this object.
*
* @return The non-null Reference of this object.
* @exception NamingException If a naming exception was encountered
* while retrieving the reference.
*/
Reference getReference() throws NamingException;
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import java.util.Hashtable;
/**
* This abstract class is used to represent a referral exception,
* which is generated in response to a <em>referral</em>
* such as that returned by LDAP v3 servers.
* <p>
* A service provider provides
* a subclass of <tt>ReferralException</tt> by providing implementations
* for <tt>getReferralInfo()</tt> and <tt>getReferralContext()</tt> (and appropriate
* constructors and/or corresponding "set" methods).
* <p>
* The following code sample shows how <tt>ReferralException</tt> can be used.
* <blockquote>{@code
* while (true) {
* try {
* bindings = ctx.listBindings(name);
* while (bindings.hasMore()) {
* b = bindings.next();
* ...
* }
* break;
* } catch (ReferralException e) {
* ctx = e.getReferralContext();
* }
* }
* }</blockquote>
*<p>
* <tt>ReferralException</tt> is an abstract class. Concrete implementations
* determine its synchronization and serialization properties.
*<p>
* An environment parameter passed to the <tt>getReferralContext()</tt>
* method is owned by the caller.
* The service provider will not modify the object or keep a reference to it,
* but may keep a reference to a clone of it.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @since 1.3
*
*/
public abstract class ReferralException extends NamingException {
/**
* Constructs a new instance of ReferralException using the
* explanation supplied. All other fields are set to null.
*
* @param explanation Additional detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
protected ReferralException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of ReferralException.
* All fields are set to null.
*/
protected ReferralException() {
super();
}
/**
* Retrieves information (such as URLs) related to this referral.
* The program may examine or display this information
* to the user to determine whether to continue with the referral,
* or to determine additional information needs to be supplied in order
* to continue with the referral.
*
* @return Non-null referral information related to this referral.
*/
public abstract Object getReferralInfo();
/**
* Retrieves the context at which to continue the method.
* Regardless of whether a referral is encountered directly during a
* context operation, or indirectly, for example, during a search
* enumeration, the referral exception should provide a context
* at which to continue the operation. The referral context is
* created using the environment properties of the context
* that threw the ReferralException.
*
*<p>
* To continue the operation, the client program should re-invoke
* the method using the same arguments as the original invocation.
*
* @return The non-null context at which to continue the method.
* @exception NamingException If a naming exception was encountered.
* Call either <tt>retryReferral()</tt> or <tt>skipReferral()</tt>
* to continue processing referrals.
*/
public abstract Context getReferralContext() throws NamingException;
/**
* Retrieves the context at which to continue the method using
* environment properties.
* Regardless of whether a referral is encountered directly during a
* context operation, or indirectly, for example, during a search
* enumeration, the referral exception should provide a context
* at which to continue the operation.
*<p>
* The referral context is created using <tt>env</tt> as its environment
* properties.
* This method should be used instead of the no-arg overloaded form
* when the caller needs to use different environment properties for
* the referral context. It might need to do this, for example, when
* it needs to supply different authentication information to the referred
* server in order to create the referral context.
*<p>
* To continue the operation, the client program should re-invoke
* the method using the same arguments as the original invocation.
*
* @param env The possibly null environment to use when retrieving the
* referral context. If null, no environment properties will be used.
*
* @return The non-null context at which to continue the method.
* @exception NamingException If a naming exception was encountered.
* Call either <tt>retryReferral()</tt> or <tt>skipReferral()</tt>
* to continue processing referrals.
*/
public abstract Context
getReferralContext(Hashtable<?,?> env)
throws NamingException;
/**
* Discards the referral about to be processed.
* A call to this method should be followed by a call to
* <code>getReferralContext</code> to allow the processing of
* other referrals to continue.
* The following code fragment shows a typical usage pattern.
* <blockquote><pre>
* } catch (ReferralException e) {
* if (!shallIFollow(e.getReferralInfo())) {
* if (!e.skipReferral()) {
* return;
* }
* }
* ctx = e.getReferralContext();
* }
* </pre></blockquote>
*
* @return true If more referral processing is pending; false otherwise.
*/
public abstract boolean skipReferral();
/**
* Retries the referral currently being processed.
* A call to this method should be followed by a call to
* <code>getReferralContext</code> to allow the current
* referral to be retried.
* The following code fragment shows a typical usage pattern.
* <blockquote><pre>
* } catch (ReferralException e) {
* while (true) {
* try {
* ctx = e.getReferralContext(env);
* break;
* } catch (NamingException ne) {
* if (! shallIRetry()) {
* return;
* }
* // modify environment properties (env), if necessary
* e.retryReferral();
* }
* }
* }
* </pre></blockquote>
*
*/
public abstract void retryReferral();
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -2881363844695698876L;
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This exception is thrown when attempting to communicate with a
* directory or naming service and that service is not available.
* It might be unavailable for different reasons. For example,
* the server might be too busy to service the request, or the server
* might not be registered to service any requests, etc.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @since 1.3
*/
public class ServiceUnavailableException extends NamingException {
/**
* Constructs a new instance of ServiceUnavailableException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public ServiceUnavailableException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of ServiceUnavailableException.
* All fields default to null.
*/
public ServiceUnavailableException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -4996964726566773444L;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import javax.naming.Name;
/**
* This exception is thrown when a method
* produces a result that exceeds a size-related limit.
* This can happen, for example, if the result contains
* more objects than the user requested, or when the size
* of the result exceeds some implementation-specific limit.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @since 1.3
*/
public class SizeLimitExceededException extends LimitExceededException {
/**
* Constructs a new instance of SizeLimitExceededException.
* All fields default to null.
*/
public SizeLimitExceededException() {
super();
}
/**
* Constructs a new instance of SizeLimitExceededException using an
* explanation. All other fields default to null.
*
* @param explanation Possibly null detail about this exception.
*/
public SizeLimitExceededException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 7129289564879168579L;
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
/**
* This class represents the string form of the address of
* a communications end-point.
* It consists of a type that describes the communication mechanism
* and a string contents specific to that communication mechanism.
* The format and interpretation of
* the address type and the contents of the address are based on
* the agreement of three parties: the client that uses the address,
* the object/server that can be reached using the address, and the
* administrator or program that creates the address.
*
* <p> An example of a string reference address is a host name.
* Another example of a string reference address is a URL.
*
* <p> A string reference address is immutable:
* once created, it cannot be changed. Multithreaded access to
* a single StringRefAddr need not be synchronized.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see RefAddr
* @see BinaryRefAddr
* @since 1.3
*/
public class StringRefAddr extends RefAddr {
/**
* Contains the contents of this address.
* Can be null.
* @serial
*/
private String contents;
/**
* Constructs a new instance of StringRefAddr using its address type
* and contents.
*
* @param addrType A non-null string describing the type of the address.
* @param addr The possibly null contents of the address in the form of a string.
*/
public StringRefAddr(String addrType, String addr) {
super(addrType);
contents = addr;
}
/**
* Retrieves the contents of this address. The result is a string.
*
* @return The possibly null address contents.
*/
public Object getContent() {
return contents;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -8913762495138505527L;
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming;
import javax.naming.Name;
/**
* This exception is thrown when a method
* does not terminate within the specified time limit.
* This can happen, for example, if the user specifies that
* the method should take no longer than 10 seconds, and the
* method fails to complete with 10 seconds.
*
* <p> Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @since 1.3
*/
public class TimeLimitExceededException extends LimitExceededException {
/**
* Constructs a new instance of TimeLimitExceededException.
* All fields default to null.
*/
public TimeLimitExceededException() {
super();
}
/**
* Constructs a new instance of TimeLimitExceededException
* using the argument supplied.
* @param explanation possibly null detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public TimeLimitExceededException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3597009011385034696L;
}

View File

@@ -0,0 +1,340 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.OperationNotSupportedException;
/**
* This interface represents an attribute associated with a named object.
*<p>
* In a directory, named objects can have associated with them
* attributes. The <tt>Attribute</tt> interface represents an attribute associated
* with a named object. An attribute contains 0 or more, possibly null, values.
* The attribute values can be ordered or unordered (see <tt>isOrdered()</tt>).
* If the values are unordered, no duplicates are allowed.
* If the values are ordered, duplicates are allowed.
*<p>
* The content and representation of an attribute and its values is defined by
* the attribute's <em>schema</em>. The schema contains information
* about the attribute's syntax and other properties about the attribute.
* See <tt>getAttributeDefinition()</tt> and
* <tt>getAttributeSyntaxDefinition()</tt>
* for details regarding how to get schema information about an attribute
* if the underlying directory service supports schemas.
*<p>
* Equality of two attributes is determined by the implementation class.
* A simple implementation can use <tt>Object.equals()</tt> to determine equality
* of attribute values, while a more sophisticated implementation might
* make use of schema information to determine equality.
* Similarly, one implementation might provide a static storage
* structure which simply returns the values passed to its
* constructor, while another implementation might define <tt>get()</tt> and
* <tt>getAll()</tt>.
* to get the values dynamically from the directory.
*<p>
* Note that updates to <tt>Attribute</tt> (such as adding or removing a
* value) do not affect the corresponding representation of the attribute
* in the directory. Updates to the directory can only be effected
* using operations in the <tt>DirContext</tt> interface.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see BasicAttribute
* @since 1.3
*/
public interface Attribute extends Cloneable, java.io.Serializable {
/**
* Retrieves an enumeration of the attribute's values.
* The behaviour of this enumeration is unspecified
* if the attribute's values are added, changed,
* or removed while the enumeration is in progress.
* If the attribute values are ordered, the enumeration's items
* will be ordered.
*
* @return A non-null enumeration of the attribute's values.
* Each element of the enumeration is a possibly null Object. The object's
* class is the class of the attribute value. The element is null
* if the attribute's value is null.
* If the attribute has zero values, an empty enumeration
* is returned.
* @exception NamingException
* If a naming exception was encountered while retrieving
* the values.
* @see #isOrdered
*/
NamingEnumeration<?> getAll() throws NamingException;
/**
* Retrieves one of this attribute's values.
* If the attribute has more than one value and is unordered, any one of
* the values is returned.
* If the attribute has more than one value and is ordered, the
* first value is returned.
*
* @return A possibly null object representing one of
* the attribute's value. It is null if the attribute's value
* is null.
* @exception NamingException
* If a naming exception was encountered while retrieving
* the value.
* @exception java.util.NoSuchElementException
* If this attribute has no values.
*/
Object get() throws NamingException;
/**
* Retrieves the number of values in this attribute.
*
* @return The nonnegative number of values in this attribute.
*/
int size();
/**
* Retrieves the id of this attribute.
*
* @return The id of this attribute. It cannot be null.
*/
String getID();
/**
* Determines whether a value is in the attribute.
* Equality is determined by the implementation, which may use
* <tt>Object.equals()</tt> or schema information to determine equality.
*
* @param attrVal The possibly null value to check. If null, check
* whether the attribute has an attribute value whose value is null.
* @return true if attrVal is one of this attribute's values; false otherwise.
* @see java.lang.Object#equals
* @see BasicAttribute#equals
*/
boolean contains(Object attrVal);
/**
* Adds a new value to the attribute.
* If the attribute values are unordered and
* <tt>attrVal</tt> is already in the attribute, this method does nothing.
* If the attribute values are ordered, <tt>attrVal</tt> is added to the end of
* the list of attribute values.
*<p>
* Equality is determined by the implementation, which may use
* <tt>Object.equals()</tt> or schema information to determine equality.
*
* @param attrVal The new possibly null value to add. If null, null
* is added as an attribute value.
* @return true if a value was added; false otherwise.
*/
boolean add(Object attrVal);
/**
* Removes a specified value from the attribute.
* If <tt>attrval</tt> is not in the attribute, this method does nothing.
* If the attribute values are ordered, the first occurrence of
* <tt>attrVal</tt> is removed and attribute values at indices greater
* than the removed
* value are shifted up towards the head of the list (and their indices
* decremented by one).
*<p>
* Equality is determined by the implementation, which may use
* <tt>Object.equals()</tt> or schema information to determine equality.
*
* @param attrval The possibly null value to remove from this attribute.
* If null, remove the attribute value that is null.
* @return true if the value was removed; false otherwise.
*/
boolean remove(Object attrval);
/**
* Removes all values from this attribute.
*/
void clear();
/**
* Retrieves the syntax definition associated with the attribute.
* An attribute's syntax definition specifies the format
* of the attribute's value(s). Note that this is different from
* the attribute value's representation as a Java object. Syntax
* definition refers to the directory's notion of <em>syntax</em>.
*<p>
* For example, even though a value might be
* a Java String object, its directory syntax might be "Printable String"
* or "Telephone Number". Or a value might be a byte array, and its
* directory syntax is "JPEG" or "Certificate".
* For example, if this attribute's syntax is "JPEG",
* this method would return the syntax definition for "JPEG".
* <p>
* The information that you can retrieve from a syntax definition
* is directory-dependent.
*<p>
* If an implementation does not support schemas, it should throw
* OperationNotSupportedException. If an implementation does support
* schemas, it should define this method to return the appropriate
* information.
* @return The attribute's syntax definition. Null if the implementation
* supports schemas but this particular attribute does not have
* any schema information.
* @exception OperationNotSupportedException If getting the schema
* is not supported.
* @exception NamingException If a naming exception occurs while getting
* the schema.
*/
DirContext getAttributeSyntaxDefinition() throws NamingException;
/**
* Retrieves the attribute's schema definition.
* An attribute's schema definition contains information
* such as whether the attribute is multivalued or single-valued,
* the matching rules to use when comparing the attribute's values.
*
* The information that you can retrieve from an attribute definition
* is directory-dependent.
*
*<p>
* If an implementation does not support schemas, it should throw
* OperationNotSupportedException. If an implementation does support
* schemas, it should define this method to return the appropriate
* information.
* @return This attribute's schema definition. Null if the implementation
* supports schemas but this particular attribute does not have
* any schema information.
* @exception OperationNotSupportedException If getting the schema
* is not supported.
* @exception NamingException If a naming exception occurs while getting
* the schema.
*/
DirContext getAttributeDefinition() throws NamingException;
/**
* Makes a copy of the attribute.
* The copy contains the same attribute values as the original attribute:
* the attribute values are not themselves cloned.
* Changes to the copy will not affect the original and vice versa.
*
* @return A non-null copy of the attribute.
*/
Object clone();
//----------- Methods to support ordered multivalued attributes
/**
* Determines whether this attribute's values are ordered.
* If an attribute's values are ordered, duplicate values are allowed.
* If an attribute's values are unordered, they are presented
* in any order and there are no duplicate values.
* @return true if this attribute's values are ordered; false otherwise.
* @see #get(int)
* @see #remove(int)
* @see #add(int, java.lang.Object)
* @see #set(int, java.lang.Object)
*/
boolean isOrdered();
/**
* Retrieves the attribute value from the ordered list of attribute values.
* This method returns the value at the <tt>ix</tt> index of the list of
* attribute values.
* If the attribute values are unordered,
* this method returns the value that happens to be at that index.
* @param ix The index of the value in the ordered list of attribute values.
* {@code 0 <= ix < size()}.
* @return The possibly null attribute value at index <tt>ix</tt>;
* null if the attribute value is null.
* @exception NamingException If a naming exception was encountered while
* retrieving the value.
* @exception IndexOutOfBoundsException If <tt>ix</tt> is outside the specified range.
*/
Object get(int ix) throws NamingException;
/**
* Removes an attribute value from the ordered list of attribute values.
* This method removes the value at the <tt>ix</tt> index of the list of
* attribute values.
* If the attribute values are unordered,
* this method removes the value that happens to be at that index.
* Values located at indices greater than <tt>ix</tt> are shifted up towards
* the front of the list (and their indices decremented by one).
*
* @param ix The index of the value to remove.
* {@code 0 <= ix < size()}.
* @return The possibly null attribute value at index <tt>ix</tt> that was removed;
* null if the attribute value is null.
* @exception IndexOutOfBoundsException If <tt>ix</tt> is outside the specified range.
*/
Object remove(int ix);
/**
* Adds an attribute value to the ordered list of attribute values.
* This method adds <tt>attrVal</tt> to the list of attribute values at
* index <tt>ix</tt>.
* Values located at indices at or greater than <tt>ix</tt> are
* shifted down towards the end of the list (and their indices incremented
* by one).
* If the attribute values are unordered and already have <tt>attrVal</tt>,
* <tt>IllegalStateException</tt> is thrown.
*
* @param ix The index in the ordered list of attribute values to add the new value.
* {@code 0 <= ix <= size()}.
* @param attrVal The possibly null attribute value to add; if null, null is
* the value added.
* @exception IndexOutOfBoundsException If <tt>ix</tt> is outside the specified range.
* @exception IllegalStateException If the attribute values are unordered and
* <tt>attrVal</tt> is one of those values.
*/
void add(int ix, Object attrVal);
/**
* Sets an attribute value in the ordered list of attribute values.
* This method sets the value at the <tt>ix</tt> index of the list of
* attribute values to be <tt>attrVal</tt>. The old value is removed.
* If the attribute values are unordered,
* this method sets the value that happens to be at that index
* to <tt>attrVal</tt>, unless <tt>attrVal</tt> is already one of the values.
* In that case, <tt>IllegalStateException</tt> is thrown.
*
* @param ix The index of the value in the ordered list of attribute values.
* {@code 0 <= ix < size()}.
* @param attrVal The possibly null attribute value to use.
* If null, 'null' replaces the old value.
* @return The possibly null attribute value at index ix that was replaced.
* Null if the attribute value was null.
* @exception IndexOutOfBoundsException If <tt>ix</tt> is outside the specified range.
* @exception IllegalStateException If <tt>attrVal</tt> already exists and the
* attribute values are unordered.
*/
Object set(int ix, Object attrVal);
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability.
*/
static final long serialVersionUID = 8707690322213556804L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when an operation attempts
* to add an attribute that already exists.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirContext#modifyAttributes
* @since 1.3
*/
public class AttributeInUseException extends NamingException {
/**
* Constructs a new instance of AttributeInUseException with
* an explanation. All other fields are set to null.
*
* @param explanation Possibly null additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public AttributeInUseException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of AttributeInUseException.
* All fields are initialized to null.
*/
public AttributeInUseException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 4437710305529322564L;
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when an attempt is
* made to add, or remove, or modify an attribute, its identifier,
* or its values that conflicts with the attribute's (schema) definition
* or the attribute's state.
* It is thrown in response to DirContext.modifyAttributes().
* It contains a list of modifications that have not been performed, in the
* order that they were supplied to modifyAttributes().
* If the list is null, none of the modifications were performed successfully.
*<p>
* An AttributeModificationException instance is not synchronized
* against concurrent multithreaded access. Multiple threads trying
* to access and modify a single AttributeModification instance
* should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirContext#modifyAttributes
* @since 1.3
*/
/*
*<p>
* The serialized form of an AttributeModificationException object
* consists of the serialized fields of its NamingException
* superclass, followed by an array of ModificationItem objects.
*
*/
public class AttributeModificationException extends NamingException {
/**
* Contains the possibly null list of unexecuted modifications.
* @serial
*/
private ModificationItem[] unexecs = null;
/**
* Constructs a new instance of AttributeModificationException using
* an explanation. All other fields are set to null.
*
* @param explanation Possibly null additional detail about this exception.
* If null, this exception has no detail message.
* @see java.lang.Throwable#getMessage
*/
public AttributeModificationException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of AttributeModificationException.
* All fields are set to null.
*/
public AttributeModificationException() {
super();
}
/**
* Sets the unexecuted modification list to be e.
* Items in the list must appear in the same order in which they were
* originally supplied in DirContext.modifyAttributes().
* The first item in the list is the first one that was not executed.
* If this list is null, none of the operations originally submitted
* to modifyAttributes() were executed.
* @param e The possibly null list of unexecuted modifications.
* @see #getUnexecutedModifications
*/
public void setUnexecutedModifications(ModificationItem[] e) {
unexecs = e;
}
/**
* Retrieves the unexecuted modification list.
* Items in the list appear in the same order in which they were
* originally supplied in DirContext.modifyAttributes().
* The first item in the list is the first one that was not executed.
* If this list is null, none of the operations originally submitted
* to modifyAttributes() were executed.
* @return The possibly null unexecuted modification list.
* @see #setUnexecutedModifications
*/
public ModificationItem[] getUnexecutedModifications() {
return unexecs;
}
/**
* The string representation of this exception consists of
* information about where the error occurred, and
* the first unexecuted modification.
* This string is meant for debugging and not mean to be interpreted
* programmatically.
* @return The non-null string representation of this exception.
*/
public String toString() {
String orig = super.toString();
if (unexecs != null) {
orig += ("First unexecuted modification: " +
unexecs[0].toString());
}
return orig;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 8060676069678710186L;
}

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import java.util.Hashtable;
import java.util.Enumeration;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
/**
* This interface represents a collection of attributes.
*<p>
* In a directory, named objects can have associated with them
* attributes. The Attributes interface represents a collection of attributes.
* For example, you can request from the directory the attributes
* associated with an object. Those attributes are returned in
* an object that implements the Attributes interface.
*<p>
* Attributes in an object that implements the Attributes interface are
* unordered. The object can have zero or more attributes.
* Attributes is either case-sensitive or case-insensitive (case-ignore).
* This property is determined at the time the Attributes object is
* created. (see BasicAttributes constructor for example).
* In a case-insensitive Attributes, the case of its attribute identifiers
* is ignored when searching for an attribute, or adding attributes.
* In a case-sensitive Attributes, the case is significant.
*<p>
* Note that updates to Attributes (such as adding or removing an attribute)
* do not affect the corresponding representation in the directory.
* Updates to the directory can only be effected
* using operations in the DirContext interface.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirContext#getAttributes
* @see DirContext#modifyAttributes
* @see DirContext#bind
* @see DirContext#rebind
* @see DirContext#createSubcontext
* @see DirContext#search
* @see BasicAttributes
* @since 1.3
*/
public interface Attributes extends Cloneable, java.io.Serializable {
/**
* Determines whether the attribute set ignores the case of
* attribute identifiers when retrieving or adding attributes.
* @return true if case is ignored; false otherwise.
*/
boolean isCaseIgnored();
/**
* Retrieves the number of attributes in the attribute set.
*
* @return The nonnegative number of attributes in this attribute set.
*/
int size();
/**
* Retrieves the attribute with the given attribute id from the
* attribute set.
*
* @param attrID The non-null id of the attribute to retrieve.
* If this attribute set ignores the character
* case of its attribute ids, the case of attrID
* is ignored.
* @return The attribute identified by attrID; null if not found.
* @see #put
* @see #remove
*/
Attribute get(String attrID);
/**
* Retrieves an enumeration of the attributes in the attribute set.
* The effects of updates to this attribute set on this enumeration
* are undefined.
*
* @return A non-null enumeration of the attributes in this attribute set.
* Each element of the enumeration is of class <tt>Attribute</tt>.
* If attribute set has zero attributes, an empty enumeration
* is returned.
*/
NamingEnumeration<? extends Attribute> getAll();
/**
* Retrieves an enumeration of the ids of the attributes in the
* attribute set.
* The effects of updates to this attribute set on this enumeration
* are undefined.
*
* @return A non-null enumeration of the attributes' ids in
* this attribute set. Each element of the enumeration is
* of class String.
* If attribute set has zero attributes, an empty enumeration
* is returned.
*/
NamingEnumeration<String> getIDs();
/**
* Adds a new attribute to the attribute set.
*
* @param attrID non-null The id of the attribute to add.
* If the attribute set ignores the character
* case of its attribute ids, the case of attrID
* is ignored.
* @param val The possibly null value of the attribute to add.
* If null, the attribute does not have any values.
* @return The Attribute with attrID that was previous in this attribute set;
* null if no such attribute existed.
* @see #remove
*/
Attribute put(String attrID, Object val);
/**
* Adds a new attribute to the attribute set.
*
* @param attr The non-null attribute to add.
* If the attribute set ignores the character
* case of its attribute ids, the case of
* attr's identifier is ignored.
* @return The Attribute with the same ID as attr that was previous
* in this attribute set;
* null if no such attribute existed.
* @see #remove
*/
Attribute put(Attribute attr);
/**
* Removes the attribute with the attribute id 'attrID' from
* the attribute set. If the attribute does not exist, ignore.
*
* @param attrID The non-null id of the attribute to remove.
* If the attribute set ignores the character
* case of its attribute ids, the case of
* attrID is ignored.
* @return The Attribute with the same ID as attrID that was previous
* in the attribute set;
* null if no such attribute existed.
*/
Attribute remove(String attrID);
/**
* Makes a copy of the attribute set.
* The new set contains the same attributes as the original set:
* the attributes are not themselves cloned.
* Changes to the copy will not affect the original and vice versa.
*
* @return A non-null copy of this attribute set.
*/
Object clone();
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
// static final long serialVersionUID = -7247874645443605347L;
}

View File

@@ -0,0 +1,557 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.lang.reflect.Array;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.OperationNotSupportedException;
/**
* This class provides a basic implementation of the <tt>Attribute</tt> interface.
*<p>
* This implementation does not support the schema methods
* <tt>getAttributeDefinition()</tt> and <tt>getAttributeSyntaxDefinition()</tt>.
* They simply throw <tt>OperationNotSupportedException</tt>.
* Subclasses of <tt>BasicAttribute</tt> should override these methods if they
* support them.
*<p>
* The <tt>BasicAttribute</tt> class by default uses <tt>Object.equals()</tt> to
* determine equality of attribute values when testing for equality or
* when searching for values, <em>except</em> when the value is an array.
* For an array, each element of the array is checked using <tt>Object.equals()</tt>.
* Subclasses of <tt>BasicAttribute</tt> can make use of schema information
* when doing similar equality checks by overriding methods
* in which such use of schema is meaningful.
* Similarly, the <tt>BasicAttribute</tt> class by default returns the values passed to its
* constructor and/or manipulated using the add/remove methods.
* Subclasses of <tt>BasicAttribute</tt> can override <tt>get()</tt> and <tt>getAll()</tt>
* to get the values dynamically from the directory (or implement
* the <tt>Attribute</tt> interface directly instead of subclassing <tt>BasicAttribute</tt>).
*<p>
* Note that updates to <tt>BasicAttribute</tt> (such as adding or removing a value)
* does not affect the corresponding representation of the attribute
* in the directory. Updates to the directory can only be effected
* using operations in the <tt>DirContext</tt> interface.
*<p>
* A <tt>BasicAttribute</tt> instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify a
* <tt>BasicAttribute</tt> should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class BasicAttribute implements Attribute {
/**
* Holds the attribute's id. It is initialized by the public constructor and
* cannot be null unless methods in BasicAttribute that use attrID
* have been overridden.
* @serial
*/
protected String attrID;
/**
* Holds the attribute's values. Initialized by public constructors.
* Cannot be null unless methods in BasicAttribute that use
* values have been overridden.
*/
protected transient Vector<Object> values;
/**
* A flag for recording whether this attribute's values are ordered.
* @serial
*/
protected boolean ordered = false;
@SuppressWarnings("unchecked")
public Object clone() {
BasicAttribute attr;
try {
attr = (BasicAttribute)super.clone();
} catch (CloneNotSupportedException e) {
attr = new BasicAttribute(attrID, ordered);
}
attr.values = (Vector<Object>)values.clone();
return attr;
}
/**
* Determines whether obj is equal to this attribute.
* Two attributes are equal if their attribute-ids, syntaxes
* and values are equal.
* If the attribute values are unordered, the order that the values were added
* are irrelevant. If the attribute values are ordered, then the
* order the values must match.
* If obj is null or not an Attribute, false is returned.
*<p>
* By default <tt>Object.equals()</tt> is used when comparing the attribute
* id and its values except when a value is an array. For an array,
* each element of the array is checked using <tt>Object.equals()</tt>.
* A subclass may override this to make
* use of schema syntax information and matching rules,
* which define what it means for two attributes to be equal.
* How and whether a subclass makes
* use of the schema information is determined by the subclass.
* If a subclass overrides <tt>equals()</tt>, it should also override
* <tt>hashCode()</tt>
* such that two attributes that are equal have the same hash code.
*
* @param obj The possibly null object to check.
* @return true if obj is equal to this attribute; false otherwise.
* @see #hashCode
* @see #contains
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof Attribute)) {
Attribute target = (Attribute)obj;
// Check order first
if (isOrdered() != target.isOrdered()) {
return false;
}
int len;
if (attrID.equals(target.getID()) &&
(len=size()) == target.size()) {
try {
if (isOrdered()) {
// Go through both list of values
for (int i = 0; i < len; i++) {
if (!valueEquals(get(i), target.get(i))) {
return false;
}
}
} else {
// order is not relevant; check for existence
Enumeration<?> theirs = target.getAll();
while (theirs.hasMoreElements()) {
if (find(theirs.nextElement()) < 0)
return false;
}
}
} catch (NamingException e) {
return false;
}
return true;
}
}
return false;
}
/**
* Calculates the hash code of this attribute.
*<p>
* The hash code is computed by adding the hash code of
* the attribute's id and that of all of its values except for
* values that are arrays.
* For an array, the hash code of each element of the array is summed.
* If a subclass overrides <tt>hashCode()</tt>, it should override
* <tt>equals()</tt>
* as well so that two attributes that are equal have the same hash code.
*
* @return an int representing the hash code of this attribute.
* @see #equals
*/
public int hashCode() {
int hash = attrID.hashCode();
int num = values.size();
Object val;
for (int i = 0; i < num; i ++) {
val = values.elementAt(i);
if (val != null) {
if (val.getClass().isArray()) {
Object it;
int len = Array.getLength(val);
for (int j = 0 ; j < len ; j++) {
it = Array.get(val, j);
if (it != null) {
hash += it.hashCode();
}
}
} else {
hash += val.hashCode();
}
}
}
return hash;
}
/**
* Generates the string representation of this attribute.
* The string consists of the attribute's id and its values.
* This string is meant for debugging and not meant to be
* interpreted programmatically.
* @return The non-null string representation of this attribute.
*/
public String toString() {
StringBuffer answer = new StringBuffer(attrID + ": ");
if (values.size() == 0) {
answer.append("No values");
} else {
boolean start = true;
for (Enumeration<Object> e = values.elements(); e.hasMoreElements(); ) {
if (!start)
answer.append(", ");
answer.append(e.nextElement());
start = false;
}
}
return answer.toString();
}
/**
* Constructs a new instance of an unordered attribute with no value.
*
* @param id The attribute's id. It cannot be null.
*/
public BasicAttribute(String id) {
this(id, false);
}
/**
* Constructs a new instance of an unordered attribute with a single value.
*
* @param id The attribute's id. It cannot be null.
* @param value The attribute's value. If null, a null
* value is added to the attribute.
*/
public BasicAttribute(String id, Object value) {
this(id, value, false);
}
/**
* Constructs a new instance of a possibly ordered attribute with no value.
*
* @param id The attribute's id. It cannot be null.
* @param ordered true means the attribute's values will be ordered;
* false otherwise.
*/
public BasicAttribute(String id, boolean ordered) {
attrID = id;
values = new Vector<>();
this.ordered = ordered;
}
/**
* Constructs a new instance of a possibly ordered attribute with a
* single value.
*
* @param id The attribute's id. It cannot be null.
* @param value The attribute's value. If null, a null
* value is added to the attribute.
* @param ordered true means the attribute's values will be ordered;
* false otherwise.
*/
public BasicAttribute(String id, Object value, boolean ordered) {
this(id, ordered);
values.addElement(value);
}
/**
* Retrieves an enumeration of this attribute's values.
*<p>
* By default, the values returned are those passed to the
* constructor and/or manipulated using the add/replace/remove methods.
* A subclass may override this to retrieve the values dynamically
* from the directory.
*/
public NamingEnumeration<?> getAll() throws NamingException {
return new ValuesEnumImpl();
}
/**
* Retrieves one of this attribute's values.
*<p>
* By default, the value returned is one of those passed to the
* constructor and/or manipulated using the add/replace/remove methods.
* A subclass may override this to retrieve the value dynamically
* from the directory.
*/
public Object get() throws NamingException {
if (values.size() == 0) {
throw new
NoSuchElementException("Attribute " + getID() + " has no value");
} else {
return values.elementAt(0);
}
}
public int size() {
return values.size();
}
public String getID() {
return attrID;
}
/**
* Determines whether a value is in this attribute.
*<p>
* By default,
* <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
* with this attribute's values except when <tt>attrVal</tt> is an array.
* For an array, each element of the array is checked using
* <tt>Object.equals()</tt>.
* A subclass may use schema information to determine equality.
*/
public boolean contains(Object attrVal) {
return (find(attrVal) >= 0);
}
// For finding first element that has a null in JDK1.1 Vector.
// In the Java 2 platform, can just replace this with Vector.indexOf(target);
private int find(Object target) {
Class<?> cl;
if (target == null) {
int ct = values.size();
for (int i = 0 ; i < ct ; i++) {
if (values.elementAt(i) == null)
return i;
}
} else if ((cl=target.getClass()).isArray()) {
int ct = values.size();
Object it;
for (int i = 0 ; i < ct ; i++) {
it = values.elementAt(i);
if (it != null && cl == it.getClass()
&& arrayEquals(target, it))
return i;
}
} else {
return values.indexOf(target, 0);
}
return -1; // not found
}
/**
* Determines whether two attribute values are equal.
* Use arrayEquals for arrays and <tt>Object.equals()</tt> otherwise.
*/
private static boolean valueEquals(Object obj1, Object obj2) {
if (obj1 == obj2) {
return true; // object references are equal
}
if (obj1 == null) {
return false; // obj2 was not false
}
if (obj1.getClass().isArray() &&
obj2.getClass().isArray()) {
return arrayEquals(obj1, obj2);
}
return (obj1.equals(obj2));
}
/**
* Determines whether two arrays are equal by comparing each of their
* elements using <tt>Object.equals()</tt>.
*/
private static boolean arrayEquals(Object a1, Object a2) {
int len;
if ((len = Array.getLength(a1)) != Array.getLength(a2))
return false;
for (int j = 0; j < len; j++) {
Object i1 = Array.get(a1, j);
Object i2 = Array.get(a2, j);
if (i1 == null || i2 == null) {
if (i1 != i2)
return false;
} else if (!i1.equals(i2)) {
return false;
}
}
return true;
}
/**
* Adds a new value to this attribute.
*<p>
* By default, <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
* with this attribute's values except when <tt>attrVal</tt> is an array.
* For an array, each element of the array is checked using
* <tt>Object.equals()</tt>.
* A subclass may use schema information to determine equality.
*/
public boolean add(Object attrVal) {
if (isOrdered() || (find(attrVal) < 0)) {
values.addElement(attrVal);
return true;
} else {
return false;
}
}
/**
* Removes a specified value from this attribute.
*<p>
* By default, <tt>Object.equals()</tt> is used when comparing <tt>attrVal</tt>
* with this attribute's values except when <tt>attrVal</tt> is an array.
* For an array, each element of the array is checked using
* <tt>Object.equals()</tt>.
* A subclass may use schema information to determine equality.
*/
public boolean remove(Object attrval) {
// For the Java 2 platform, can just use "return removeElement(attrval);"
// Need to do the following to handle null case
int i = find(attrval);
if (i >= 0) {
values.removeElementAt(i);
return true;
}
return false;
}
public void clear() {
values.setSize(0);
}
// ---- ordering methods
public boolean isOrdered() {
return ordered;
}
public Object get(int ix) throws NamingException {
return values.elementAt(ix);
}
public Object remove(int ix) {
Object answer = values.elementAt(ix);
values.removeElementAt(ix);
return answer;
}
public void add(int ix, Object attrVal) {
if (!isOrdered() && contains(attrVal)) {
throw new IllegalStateException(
"Cannot add duplicate to unordered attribute");
}
values.insertElementAt(attrVal, ix);
}
public Object set(int ix, Object attrVal) {
if (!isOrdered() && contains(attrVal)) {
throw new IllegalStateException(
"Cannot add duplicate to unordered attribute");
}
Object answer = values.elementAt(ix);
values.setElementAt(attrVal, ix);
return answer;
}
// ----------------- Schema methods
/**
* Retrieves the syntax definition associated with this attribute.
*<p>
* This method by default throws OperationNotSupportedException. A subclass
* should override this method if it supports schema.
*/
public DirContext getAttributeSyntaxDefinition() throws NamingException {
throw new OperationNotSupportedException("attribute syntax");
}
/**
* Retrieves this attribute's schema definition.
*<p>
* This method by default throws OperationNotSupportedException. A subclass
* should override this method if it supports schema.
*/
public DirContext getAttributeDefinition() throws NamingException {
throw new OperationNotSupportedException("attribute definition");
}
// ---- serialization methods
/**
* Overridden to avoid exposing implementation details
* @serialData Default field (the attribute ID -- a String),
* followed by the number of values (an int), and the
* individual values.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject(); // write out the attrID
s.writeInt(values.size());
for (int i = 0; i < values.size(); i++) {
s.writeObject(values.elementAt(i));
}
}
/**
* Overridden to avoid exposing implementation details.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject(); // read in the attrID
int n = s.readInt(); // number of values
values = new Vector<>(Math.min(1024, n));
while (--n >= 0) {
values.addElement(s.readObject());
}
}
class ValuesEnumImpl implements NamingEnumeration<Object> {
Enumeration<Object> list;
ValuesEnumImpl() {
list = values.elements();
}
public boolean hasMoreElements() {
return list.hasMoreElements();
}
public Object nextElement() {
return(list.nextElement());
}
public Object next() throws NamingException {
return list.nextElement();
}
public boolean hasMore() throws NamingException {
return list.hasMoreElements();
}
public void close() throws NamingException {
list = null;
}
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability.
*/
private static final long serialVersionUID = 6743528196119291326L;
}

View File

@@ -0,0 +1,378 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Locale;
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
/**
* This class provides a basic implementation
* of the Attributes interface.
*<p>
* BasicAttributes is either case-sensitive or case-insensitive (case-ignore).
* This property is determined at the time the BasicAttributes constructor
* is called.
* In a case-insensitive BasicAttributes, the case of its attribute identifiers
* is ignored when searching for an attribute, or adding attributes.
* In a case-sensitive BasicAttributes, the case is significant.
*<p>
* When the BasicAttributes class needs to create an Attribute, it
* uses BasicAttribute. There is no other dependency on BasicAttribute.
*<p>
* Note that updates to BasicAttributes (such as adding or removing an attribute)
* does not affect the corresponding representation in the directory.
* Updates to the directory can only be effected
* using operations in the DirContext interface.
*<p>
* A BasicAttributes instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single BasicAttributes instance should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirContext#getAttributes
* @see DirContext#modifyAttributes
* @see DirContext#bind
* @see DirContext#rebind
* @see DirContext#createSubcontext
* @see DirContext#search
* @since 1.3
*/
public class BasicAttributes implements Attributes {
/**
* Indicates whether case of attribute ids is ignored.
* @serial
*/
private boolean ignoreCase = false;
// The 'key' in attrs is stored in the 'right case'.
// If ignoreCase is true, key is aways lowercase.
// If ignoreCase is false, key is stored as supplied by put().
// %%% Not declared "private" due to bug 4064984.
transient Hashtable<String,Attribute> attrs = new Hashtable<>(11);
/**
* Constructs a new instance of Attributes.
* The character case of attribute identifiers
* is significant when subsequently retrieving or adding attributes.
*/
public BasicAttributes() {
}
/**
* Constructs a new instance of Attributes.
* If <code>ignoreCase</code> is true, the character case of attribute
* identifiers is ignored; otherwise the case is significant.
* @param ignoreCase true means this attribute set will ignore
* the case of its attribute identifiers
* when retrieving or adding attributes;
* false means case is respected.
*/
public BasicAttributes(boolean ignoreCase) {
this.ignoreCase = ignoreCase;
}
/**
* Constructs a new instance of Attributes with one attribute.
* The attribute specified by attrID and val are added to the newly
* created attribute.
* The character case of attribute identifiers
* is significant when subsequently retrieving or adding attributes.
* @param attrID non-null The id of the attribute to add.
* @param val The value of the attribute to add. If null, a null
* value is added to the attribute.
*/
public BasicAttributes(String attrID, Object val) {
this();
this.put(new BasicAttribute(attrID, val));
}
/**
* Constructs a new instance of Attributes with one attribute.
* The attribute specified by attrID and val are added to the newly
* created attribute.
* If <code>ignoreCase</code> is true, the character case of attribute
* identifiers is ignored; otherwise the case is significant.
* @param attrID non-null The id of the attribute to add.
* If this attribute set ignores the character
* case of its attribute ids, the case of attrID
* is ignored.
* @param val The value of the attribute to add. If null, a null
* value is added to the attribute.
* @param ignoreCase true means this attribute set will ignore
* the case of its attribute identifiers
* when retrieving or adding attributes;
* false means case is respected.
*/
public BasicAttributes(String attrID, Object val, boolean ignoreCase) {
this(ignoreCase);
this.put(new BasicAttribute(attrID, val));
}
@SuppressWarnings("unchecked")
public Object clone() {
BasicAttributes attrset;
try {
attrset = (BasicAttributes)super.clone();
} catch (CloneNotSupportedException e) {
attrset = new BasicAttributes(ignoreCase);
}
attrset.attrs = (Hashtable<String,Attribute>)attrs.clone();
return attrset;
}
public boolean isCaseIgnored() {
return ignoreCase;
}
public int size() {
return attrs.size();
}
public Attribute get(String attrID) {
Attribute attr = attrs.get(
ignoreCase ? attrID.toLowerCase(Locale.ENGLISH) : attrID);
return (attr);
}
public NamingEnumeration<Attribute> getAll() {
return new AttrEnumImpl();
}
public NamingEnumeration<String> getIDs() {
return new IDEnumImpl();
}
public Attribute put(String attrID, Object val) {
return this.put(new BasicAttribute(attrID, val));
}
public Attribute put(Attribute attr) {
String id = attr.getID();
if (ignoreCase) {
id = id.toLowerCase(Locale.ENGLISH);
}
return attrs.put(id, attr);
}
public Attribute remove(String attrID) {
String id = (ignoreCase ? attrID.toLowerCase(Locale.ENGLISH) : attrID);
return attrs.remove(id);
}
/**
* Generates the string representation of this attribute set.
* The string consists of each attribute identifier and the contents
* of each attribute. The contents of this string is useful
* for debugging and is not meant to be interpreted programmatically.
*
* @return A non-null string listing the contents of this attribute set.
*/
public String toString() {
if (attrs.size() == 0) {
return("No attributes");
} else {
return attrs.toString();
}
}
/**
* Determines whether this <tt>BasicAttributes</tt> is equal to another
* <tt>Attributes</tt>
* Two <tt>Attributes</tt> are equal if they are both instances of
* <tt>Attributes</tt>,
* treat the case of attribute IDs the same way, and contain the
* same attributes. Each <tt>Attribute</tt> in this <tt>BasicAttributes</tt>
* is checked for equality using <tt>Object.equals()</tt>, which may have
* be overridden by implementations of <tt>Attribute</tt>).
* If a subclass overrides <tt>equals()</tt>,
* it should override <tt>hashCode()</tt>
* as well so that two <tt>Attributes</tt> instances that are equal
* have the same hash code.
* @param obj the possibly null object to compare against.
*
* @return true If obj is equal to this BasicAttributes.
* @see #hashCode
*/
public boolean equals(Object obj) {
if ((obj != null) && (obj instanceof Attributes)) {
Attributes target = (Attributes)obj;
// Check case first
if (ignoreCase != target.isCaseIgnored()) {
return false;
}
if (size() == target.size()) {
Attribute their, mine;
try {
NamingEnumeration<?> theirs = target.getAll();
while (theirs.hasMore()) {
their = (Attribute)theirs.next();
mine = get(their.getID());
if (!their.equals(mine)) {
return false;
}
}
} catch (NamingException e) {
return false;
}
return true;
}
}
return false;
}
/**
* Calculates the hash code of this BasicAttributes.
*<p>
* The hash code is computed by adding the hash code of
* the attributes of this object. If this BasicAttributes
* ignores case of its attribute IDs, one is added to the hash code.
* If a subclass overrides <tt>hashCode()</tt>,
* it should override <tt>equals()</tt>
* as well so that two <tt>Attributes</tt> instances that are equal
* have the same hash code.
*
* @return an int representing the hash code of this BasicAttributes instance.
* @see #equals
*/
public int hashCode() {
int hash = (ignoreCase ? 1 : 0);
try {
NamingEnumeration<?> all = getAll();
while (all.hasMore()) {
hash += all.next().hashCode();
}
} catch (NamingException e) {}
return hash;
}
/**
* Overridden to avoid exposing implementation details.
* @serialData Default field (ignoreCase flag -- a boolean), followed by
* the number of attributes in the set
* (an int), and then the individual Attribute objects.
*/
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject(); // write out the ignoreCase flag
s.writeInt(attrs.size());
Enumeration<Attribute> attrEnum = attrs.elements();
while (attrEnum.hasMoreElements()) {
s.writeObject(attrEnum.nextElement());
}
}
/**
* Overridden to avoid exposing implementation details.
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject(); // read in the ignoreCase flag
int n = s.readInt(); // number of attributes
attrs = (n >= 1)
? new Hashtable<>(1 + (int) (Math.min(768, n) / .75f))
: new Hashtable<>(2); // can't have initial size of 0 (grrr...)
while (--n >= 0) {
put((Attribute)s.readObject());
}
}
class AttrEnumImpl implements NamingEnumeration<Attribute> {
Enumeration<Attribute> elements;
public AttrEnumImpl() {
this.elements = attrs.elements();
}
public boolean hasMoreElements() {
return elements.hasMoreElements();
}
public Attribute nextElement() {
return elements.nextElement();
}
public boolean hasMore() throws NamingException {
return hasMoreElements();
}
public Attribute next() throws NamingException {
return nextElement();
}
public void close() throws NamingException {
elements = null;
}
}
class IDEnumImpl implements NamingEnumeration<String> {
Enumeration<Attribute> elements;
public IDEnumImpl() {
// Walking through the elements, rather than the keys, gives
// us attribute IDs that have not been converted to lowercase.
this.elements = attrs.elements();
}
public boolean hasMoreElements() {
return elements.hasMoreElements();
}
public String nextElement() {
Attribute attr = elements.nextElement();
return attr.getID();
}
public boolean hasMore() throws NamingException {
return hasMoreElements();
}
public String next() throws NamingException {
return nextElement();
}
public void close() throws NamingException {
elements = null;
}
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability.
*/
private static final long serialVersionUID = 4980164073184639448L;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import java.util.Hashtable;
import javax.naming.spi.NamingManager;
import javax.naming.*;
/**
* This class is the starting context for performing
* directory operations. The documentation in the class description
* of InitialContext (including those for synchronization) apply here.
*
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see javax.naming.InitialContext
* @since 1.3
*/
public class InitialDirContext extends InitialContext implements DirContext {
/**
* Constructs an initial DirContext with the option of not
* initializing it. This may be used by a constructor in
* a subclass when the value of the environment parameter
* is not yet known at the time the <tt>InitialDirContext</tt>
* constructor is called. The subclass's constructor will
* call this constructor, compute the value of the environment,
* and then call <tt>init()</tt> before returning.
*
* @param lazy
* true means do not initialize the initial DirContext; false
* is equivalent to calling <tt>new InitialDirContext()</tt>
* @throws NamingException if a naming exception is encountered
*
* @see InitialContext#init(Hashtable)
* @since 1.3
*/
protected InitialDirContext(boolean lazy) throws NamingException {
super(lazy);
}
/**
* Constructs an initial DirContext.
* No environment properties are supplied.
* Equivalent to <tt>new InitialDirContext(null)</tt>.
*
* @throws NamingException if a naming exception is encountered
*
* @see #InitialDirContext(Hashtable)
*/
public InitialDirContext() throws NamingException {
super();
}
/**
* Constructs an initial DirContext using the supplied environment.
* Environment properties are discussed in the
* <tt>javax.naming.InitialContext</tt> class description.
*
* <p> This constructor will not modify <tt>environment</tt>
* or save a reference to it, but may save a clone.
* Caller should not modify mutable keys and values in
* <tt>environment</tt> after it has been passed to the constructor.
*
* @param environment
* environment used to create the initial DirContext.
* Null indicates an empty environment.
*
* @throws NamingException if a naming exception is encountered
*/
public InitialDirContext(Hashtable<?,?> environment)
throws NamingException
{
super(environment);
}
private DirContext getURLOrDefaultInitDirCtx(String name)
throws NamingException {
Context answer = getURLOrDefaultInitCtx(name);
if (!(answer instanceof DirContext)) {
if (answer == null) {
throw new NoInitialContextException();
} else {
throw new NotContextException(
"Not an instance of DirContext");
}
}
return (DirContext)answer;
}
private DirContext getURLOrDefaultInitDirCtx(Name name)
throws NamingException {
Context answer = getURLOrDefaultInitCtx(name);
if (!(answer instanceof DirContext)) {
if (answer == null) {
throw new NoInitialContextException();
} else {
throw new NotContextException(
"Not an instance of DirContext");
}
}
return (DirContext)answer;
}
// DirContext methods
// Most Javadoc is deferred to the DirContext interface.
public Attributes getAttributes(String name)
throws NamingException {
return getAttributes(name, null);
}
public Attributes getAttributes(String name, String[] attrIds)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).getAttributes(name, attrIds);
}
public Attributes getAttributes(Name name)
throws NamingException {
return getAttributes(name, null);
}
public Attributes getAttributes(Name name, String[] attrIds)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).getAttributes(name, attrIds);
}
public void modifyAttributes(String name, int mod_op, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).modifyAttributes(name, mod_op, attrs);
}
public void modifyAttributes(Name name, int mod_op, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).modifyAttributes(name, mod_op, attrs);
}
public void modifyAttributes(String name, ModificationItem[] mods)
throws NamingException {
getURLOrDefaultInitDirCtx(name).modifyAttributes(name, mods);
}
public void modifyAttributes(Name name, ModificationItem[] mods)
throws NamingException {
getURLOrDefaultInitDirCtx(name).modifyAttributes(name, mods);
}
public void bind(String name, Object obj, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).bind(name, obj, attrs);
}
public void bind(Name name, Object obj, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).bind(name, obj, attrs);
}
public void rebind(String name, Object obj, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).rebind(name, obj, attrs);
}
public void rebind(Name name, Object obj, Attributes attrs)
throws NamingException {
getURLOrDefaultInitDirCtx(name).rebind(name, obj, attrs);
}
public DirContext createSubcontext(String name, Attributes attrs)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).createSubcontext(name, attrs);
}
public DirContext createSubcontext(Name name, Attributes attrs)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).createSubcontext(name, attrs);
}
public DirContext getSchema(String name) throws NamingException {
return getURLOrDefaultInitDirCtx(name).getSchema(name);
}
public DirContext getSchema(Name name) throws NamingException {
return getURLOrDefaultInitDirCtx(name).getSchema(name);
}
public DirContext getSchemaClassDefinition(String name)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).getSchemaClassDefinition(name);
}
public DirContext getSchemaClassDefinition(Name name)
throws NamingException {
return getURLOrDefaultInitDirCtx(name).getSchemaClassDefinition(name);
}
// -------------------- search operations
public NamingEnumeration<SearchResult>
search(String name, Attributes matchingAttributes)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, matchingAttributes);
}
public NamingEnumeration<SearchResult>
search(Name name, Attributes matchingAttributes)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, matchingAttributes);
}
public NamingEnumeration<SearchResult>
search(String name,
Attributes matchingAttributes,
String[] attributesToReturn)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name,
matchingAttributes,
attributesToReturn);
}
public NamingEnumeration<SearchResult>
search(Name name,
Attributes matchingAttributes,
String[] attributesToReturn)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name,
matchingAttributes,
attributesToReturn);
}
public NamingEnumeration<SearchResult>
search(String name,
String filter,
SearchControls cons)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, filter, cons);
}
public NamingEnumeration<SearchResult>
search(Name name,
String filter,
SearchControls cons)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, filter, cons);
}
public NamingEnumeration<SearchResult>
search(String name,
String filterExpr,
Object[] filterArgs,
SearchControls cons)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, filterExpr,
filterArgs, cons);
}
public NamingEnumeration<SearchResult>
search(Name name,
String filterExpr,
Object[] filterArgs,
SearchControls cons)
throws NamingException
{
return getURLOrDefaultInitDirCtx(name).search(name, filterExpr,
filterArgs, cons);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when an attempt is
* made to add to create an attribute with an invalid attribute identifier.
* The validity of an attribute identifier is directory-specific.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InvalidAttributeIdentifierException extends NamingException {
/**
* Constructs a new instance of InvalidAttributeIdentifierException using the
* explanation supplied. All other fields set to null.
* @param explanation Possibly null string containing additional detail about this exception.
* @see java.lang.Throwable#getMessage
*/
public InvalidAttributeIdentifierException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of InvalidAttributeIdentifierException.
* All fields are set to null.
*/
public InvalidAttributeIdentifierException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -9036920266322999923L;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This class is thrown when an attempt is
* made to add to an attribute a value that conflicts with the attribute's
* schema definition. This could happen, for example, if attempting
* to add an attribute with no value when the attribute is required
* to have at least one value, or if attempting to add more than
* one value to a single valued-attribute, or if attempting to
* add a value that conflicts with the syntax of the attribute.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InvalidAttributeValueException extends NamingException {
/**
* Constructs a new instance of InvalidAttributeValueException using
* an explanation. All other fields are set to null.
* @param explanation Additional detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public InvalidAttributeValueException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of InvalidAttributeValueException.
* All fields are set to null.
*/
public InvalidAttributeValueException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 8720050295499275011L;
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when an attempt is
* made to add or modify an attribute set that has been specified
* incompletely or incorrectly. This could happen, for example,
* when attempting to add or modify a binding, or to create a new
* subcontext without specifying all the mandatory attributes
* required for creation of the object. Another situation in
* which this exception is thrown is by specification of incompatible
* attributes within the same attribute set, or attributes in conflict
* with that specified by the object's schema.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InvalidAttributesException extends NamingException {
/**
* Constructs a new instance of InvalidAttributesException using an
* explanation. All other fields are set to null.
* @param explanation Additional detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public InvalidAttributesException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of InvalidAttributesException.
* All fields are set to null.
*/
public InvalidAttributesException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 2607612850539889765L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when the specification of
* the SearchControls for a search operation is invalid. For example, if the scope is
* set to a value other than OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE,
* this exception is thrown.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InvalidSearchControlsException extends NamingException {
/**
* Constructs a new instance of InvalidSearchControlsException.
* All fields are set to null.
*/
public InvalidSearchControlsException() {
super();
}
/**
* Constructs a new instance of InvalidSearchControlsException
* with an explanation. All other fields set to null.
* @param msg Detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public InvalidSearchControlsException(String msg) {
super(msg);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -5124108943352665777L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when the specification of
* a search filter is invalid. The expression of the filter may
* be invalid, or there may be a problem with one of the parameters
* passed to the filter.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class InvalidSearchFilterException extends NamingException {
/**
* Constructs a new instance of InvalidSearchFilterException.
* All fields are set to null.
*/
public InvalidSearchFilterException() {
super();
}
/**
* Constructs a new instance of InvalidSearchFilterException
* with an explanation. All other fields are set to null.
* @param msg Detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public InvalidSearchFilterException(String msg) {
super(msg);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 2902700940682875441L;
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
/**
* This class represents a modification item.
* It consists of a modification code and an attribute on which to operate.
*<p>
* A ModificationItem instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single ModificationItem instance should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
/*
*<p>
* The serialized form of a ModificationItem object consists of the
* modification op (and int) and the corresponding Attribute.
*/
public class ModificationItem implements java.io.Serializable {
/**
* Contains an integer identify the modification
* to be performed.
* @serial
*/
private int mod_op;
/**
* Contains the attribute identifying
* the attribute and/or its value to be applied for the modification.
* @serial
*/
private Attribute attr;
/**
* Creates a new instance of ModificationItem.
* @param mod_op Modification to apply. It must be one of:
* DirContext.ADD_ATTRIBUTE
* DirContext.REPLACE_ATTRIBUTE
* DirContext.REMOVE_ATTRIBUTE
* @param attr The non-null attribute to use for modification.
* @exception IllegalArgumentException If attr is null, or if mod_op is
* not one of the ones specified above.
*/
public ModificationItem(int mod_op, Attribute attr) {
switch (mod_op) {
case DirContext.ADD_ATTRIBUTE:
case DirContext.REPLACE_ATTRIBUTE:
case DirContext.REMOVE_ATTRIBUTE:
if (attr == null)
throw new IllegalArgumentException("Must specify non-null attribute for modification");
this.mod_op = mod_op;
this.attr = attr;
break;
default:
throw new IllegalArgumentException("Invalid modification code " + mod_op);
}
}
/**
* Retrieves the modification code of this modification item.
* @return The modification code. It is one of:
* DirContext.ADD_ATTRIBUTE
* DirContext.REPLACE_ATTRIBUTE
* DirContext.REMOVE_ATTRIBUTE
*/
public int getModificationOp() {
return mod_op;
}
/**
* Retrieves the attribute associated with this modification item.
* @return The non-null attribute to use for the modification.
*/
public Attribute getAttribute() {
return attr;
}
/**
* Generates the string representation of this modification item,
* which consists of the modification operation and its related attribute.
* The string representation is meant for debugging and not to be
* interpreted programmatically.
*
* @return The non-null string representation of this modification item.
*/
public String toString() {
switch (mod_op) {
case DirContext.ADD_ATTRIBUTE:
return ("Add attribute: " + attr.toString());
case DirContext.REPLACE_ATTRIBUTE:
return ("Replace attribute: " + attr.toString());
case DirContext.REMOVE_ATTRIBUTE:
return ("Remove attribute: " + attr.toString());
}
return ""; // should never happen
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 7573258562534746850L;
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when attempting to access
* an attribute that does not exist.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NoSuchAttributeException extends NamingException {
/**
* Constructs a new instance of NoSuchAttributeException using
* an explanation. All other fields are set to null.
* @param explanation Additional detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public NoSuchAttributeException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of NoSuchAttributeException.
* All fields are initialized to null.
*/
public NoSuchAttributeException() {
super();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = 4836415647935888137L;
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.NamingException;
/**
* This exception is thrown when a method
* in some ways violates the schema. An example of schema violation
* is modifying attributes of an object that violates the object's
* schema definition. Another example is renaming or moving an object
* to a part of the namespace that violates the namespace's
* schema definition.
* <p>
* Synchronization and serialization issues that apply to NamingException
* apply directly here.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see javax.naming.Context#bind
* @see DirContext#bind
* @see javax.naming.Context#rebind
* @see DirContext#rebind
* @see DirContext#createSubcontext
* @see javax.naming.Context#createSubcontext
* @see DirContext#modifyAttributes
* @since 1.3
*/
public class SchemaViolationException extends NamingException {
/**
* Constructs a new instance of SchemaViolationException.
* All fields are set to null.
*/
public SchemaViolationException() {
super();
}
/**
* Constructs a new instance of SchemaViolationException
* using the explanation supplied. All other fields are set to null.
* @param explanation Detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
public SchemaViolationException(String explanation) {
super(explanation);
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -3041762429525049663L;
}

View File

@@ -0,0 +1,336 @@
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
/**
* This class encapsulates
* factors that determine scope of search and what gets returned
* as a result of the search.
*<p>
* A SearchControls instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single SearchControls instance should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class SearchControls implements java.io.Serializable {
/**
* Search the named object.
*<p>
* The NamingEnumeration that results from search()
* using OBJECT_SCOPE will contain one or zero element.
* The enumeration contains one element if the named object satisfies
* the search filter specified in search().
* The element will have as its name the empty string because the names
* of elements in the NamingEnumeration are relative to the
* target context--in this case, the target context is the named object.
* It contains zero element if the named object does not satisfy
* the search filter specified in search().
* <p>
* The value of this constant is <tt>0</tt>.
*/
public final static int OBJECT_SCOPE = 0;
/**
* Search one level of the named context.
*<p>
* The NamingEnumeration that results from search()
* using ONELEVEL_SCOPE contains elements with
* objects in the named context that satisfy
* the search filter specified in search().
* The names of elements in the NamingEnumeration are atomic names
* relative to the named context.
* <p>
* The value of this constant is <tt>1</tt>.
*/
public final static int ONELEVEL_SCOPE = 1;
/**
* Search the entire subtree rooted at the named object.
*<p>
* If the named object is not a DirContext, search only the object.
* If the named object is a DirContext, search the subtree
* rooted at the named object, including the named object itself.
*<p>
* The search will not cross naming system boundaries.
*<p>
* The NamingEnumeration that results from search()
* using SUBTREE_SCOPE contains elements of objects
* from the subtree (including the named context)
* that satisfy the search filter specified in search().
* The names of elements in the NamingEnumeration are either
* relative to the named context or is a URL string.
* If the named context satisfies the search filter, it is
* included in the enumeration with the empty string as
* its name.
* <p>
* The value of this constant is <tt>2</tt>.
*/
public final static int SUBTREE_SCOPE = 2;
/**
* Contains the scope with which to apply the search. One of
* <tt>ONELEVEL_SCOPE</tt>, <tt>OBJECT_SCOPE</tt>, or
* <tt>SUBTREE_SCOPE</tt>.
* @serial
*/
private int searchScope;
/**
* Contains the milliseconds to wait before returning
* from search.
* @serial
*/
private int timeLimit;
/**
* Indicates whether JNDI links are dereferenced during
* search.
* @serial
*/
private boolean derefLink;
/**
* Indicates whether object is returned in <tt>SearchResult</tt>.
* @serial
*/
private boolean returnObj;
/**
* Contains the maximum number of SearchResults to return.
* @serial
*/
private long countLimit;
/**
* Contains the list of attributes to be returned in
* <tt>SearchResult</tt> for each matching entry of search. <tt>null</tt>
* indicates that all attributes are to be returned.
* @serial
*/
private String[] attributesToReturn;
/**
* Constructs a search constraints using defaults.
*<p>
* The defaults are:
* <ul>
* <li>search one level
* <li>no maximum return limit for search results
* <li>no time limit for search
* <li>return all attributes associated with objects that satisfy
* the search filter.
* <li>do not return named object (return only name and class)
* <li>do not dereference links during search
*</ul>
*/
public SearchControls() {
searchScope = ONELEVEL_SCOPE;
timeLimit = 0; // no limit
countLimit = 0; // no limit
derefLink = false;
returnObj = false;
attributesToReturn = null; // return all
}
/**
* Constructs a search constraints using arguments.
* @param scope The search scope. One of:
* OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE.
* @param timelim The number of milliseconds to wait before returning.
* If 0, wait indefinitely.
* @param deref If true, dereference links during search.
* @param countlim The maximum number of entries to return. If 0, return
* all entries that satisfy filter.
* @param retobj If true, return the object bound to the name of the
* entry; if false, do not return object.
* @param attrs The identifiers of the attributes to return along with
* the entry. If null, return all attributes. If empty
* return no attributes.
*/
public SearchControls(int scope,
long countlim,
int timelim,
String[] attrs,
boolean retobj,
boolean deref) {
searchScope = scope;
timeLimit = timelim; // no limit
derefLink = deref;
returnObj = retobj;
countLimit = countlim; // no limit
attributesToReturn = attrs; // return all
}
/**
* Retrieves the search scope of these SearchControls.
*<p>
* One of OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE.
*
* @return The search scope of this SearchControls.
* @see #setSearchScope
*/
public int getSearchScope() {
return searchScope;
}
/**
* Retrieves the time limit of these SearchControls in milliseconds.
*<p>
* If the value is 0, this means to wait indefinitely.
* @return The time limit of these SearchControls in milliseconds.
* @see #setTimeLimit
*/
public int getTimeLimit() {
return timeLimit;
}
/**
* Determines whether links will be dereferenced during the search.
*
* @return true if links will be dereferenced; false otherwise.
* @see #setDerefLinkFlag
*/
public boolean getDerefLinkFlag() {
return derefLink;
}
/**
* Determines whether objects will be returned as part of the result.
*
* @return true if objects will be returned; false otherwise.
* @see #setReturningObjFlag
*/
public boolean getReturningObjFlag() {
return returnObj;
}
/**
* Retrieves the maximum number of entries that will be returned
* as a result of the search.
*<p>
* 0 indicates that all entries will be returned.
* @return The maximum number of entries that will be returned.
* @see #setCountLimit
*/
public long getCountLimit() {
return countLimit;
}
/**
* Retrieves the attributes that will be returned as part of the search.
*<p>
* A value of null indicates that all attributes will be returned.
* An empty array indicates that no attributes are to be returned.
*
* @return An array of attribute ids identifying the attributes that
* will be returned. Can be null.
* @see #setReturningAttributes
*/
public String[] getReturningAttributes() {
return attributesToReturn;
}
/**
* Sets the search scope to one of:
* OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE.
* @param scope The search scope of this SearchControls.
* @see #getSearchScope
*/
public void setSearchScope(int scope) {
searchScope = scope;
}
/**
* Sets the time limit of these SearchControls in milliseconds.
*<p>
* If the value is 0, this means to wait indefinitely.
* @param ms The time limit of these SearchControls in milliseconds.
* @see #getTimeLimit
*/
public void setTimeLimit(int ms) {
timeLimit = ms;
}
/**
* Enables/disables link dereferencing during the search.
*
* @param on if true links will be dereferenced; if false, not followed.
* @see #getDerefLinkFlag
*/
public void setDerefLinkFlag(boolean on) {
derefLink = on;
}
/**
* Enables/disables returning objects returned as part of the result.
*<p>
* If disabled, only the name and class of the object is returned.
* If enabled, the object will be returned.
*
* @param on if true, objects will be returned; if false,
* objects will not be returned.
* @see #getReturningObjFlag
*/
public void setReturningObjFlag(boolean on) {
returnObj = on;
}
/**
* Sets the maximum number of entries to be returned
* as a result of the search.
*<p>
* 0 indicates no limit: all entries will be returned.
*
* @param limit The maximum number of entries that will be returned.
* @see #getCountLimit
*/
public void setCountLimit(long limit) {
countLimit = limit;
}
/**
* Specifies the attributes that will be returned as part of the search.
*<p>
* null indicates that all attributes will be returned.
* An empty array indicates no attributes are returned.
*
* @param attrs An array of attribute ids identifying the attributes that
* will be returned. Can be null.
* @see #getReturningAttributes
*/
public void setReturningAttributes(String[] attrs) {
attributesToReturn = attrs;
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability.
*/
private static final long serialVersionUID = -2480540967773454797L;
}

View File

@@ -0,0 +1,189 @@
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.directory;
import javax.naming.Binding;
/**
* This class represents an item in the NamingEnumeration returned as a
* result of the DirContext.search() methods.
*<p>
* A SearchResult instance is not synchronized against concurrent
* multithreaded access. Multiple threads trying to access and modify
* a single SearchResult instance should lock the object.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirContext#search
* @since 1.3
*/
public class SearchResult extends Binding {
/**
* Contains the attributes returned with the object.
* @serial
*/
private Attributes attrs;
/**
* Constructs a search result using the result's name, its bound object, and
* its attributes.
*<p>
* <tt>getClassName()</tt> will return the class name of <tt>obj</tt>
* (or null if <tt>obj</tt> is null) unless the class name has been
* explicitly set using <tt>setClassName()</tt>.
*
* @param name The non-null name of the search item. It is relative
* to the <em>target context</em> of the search (which is
* named by the first parameter of the <code>search()</code> method)
*
* @param obj The object bound to name. Can be null.
* @param attrs The attributes that were requested to be returned with
* this search item. Cannot be null.
* @see javax.naming.NameClassPair#setClassName
* @see javax.naming.NameClassPair#getClassName
*/
public SearchResult(String name, Object obj, Attributes attrs) {
super(name, obj);
this.attrs = attrs;
}
/**
* Constructs a search result using the result's name, its bound object, and
* its attributes, and whether the name is relative.
*<p>
* <tt>getClassName()</tt> will return the class name of <tt>obj</tt>
* (or null if <tt>obj</tt> is null) unless the class name has been
* explicitly set using <tt>setClassName()</tt>
*
* @param name The non-null name of the search item.
* @param obj The object bound to name. Can be null.
* @param attrs The attributes that were requested to be returned with
* this search item. Cannot be null.
* @param isRelative true if <code>name</code> is relative
* to the target context of the search (which is named by
* the first parameter of the <code>search()</code> method);
* false if <code>name</code> is a URL string.
* @see javax.naming.NameClassPair#setClassName
* @see javax.naming.NameClassPair#getClassName
*/
public SearchResult(String name, Object obj, Attributes attrs,
boolean isRelative) {
super(name, obj, isRelative);
this.attrs = attrs;
}
/**
* Constructs a search result using the result's name, its class name,
* its bound object, and its attributes.
*
* @param name The non-null name of the search item. It is relative
* to the <em>target context</em> of the search (which is
* named by the first parameter of the <code>search()</code> method)
*
* @param className The possibly null class name of the object
* bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
* returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also null,
* <tt>getClassName()</tt> will return null.
* @param obj The object bound to name. Can be null.
* @param attrs The attributes that were requested to be returned with
* this search item. Cannot be null.
* @see javax.naming.NameClassPair#setClassName
* @see javax.naming.NameClassPair#getClassName
*/
public SearchResult(String name, String className,
Object obj, Attributes attrs) {
super(name, className, obj);
this.attrs = attrs;
}
/**
* Constructs a search result using the result's name, its class name,
* its bound object, its attributes, and whether the name is relative.
*
* @param name The non-null name of the search item.
* @param className The possibly null class name of the object
* bound to <tt>name</tt>. If null, the class name of <tt>obj</tt> is
* returned by <tt>getClassName()</tt>. If <tt>obj</tt> is also null,
* <tt>getClassName()</tt> will return null.
* @param obj The object bound to name. Can be null.
* @param attrs The attributes that were requested to be returned with
* this search item. Cannot be null.
* @param isRelative true if <code>name</code> is relative
* to the target context of the search (which is named by
* the first parameter of the <code>search()</code> method);
* false if <code>name</code> is a URL string.
* @see javax.naming.NameClassPair#setClassName
* @see javax.naming.NameClassPair#getClassName
*/
public SearchResult(String name, String className, Object obj,
Attributes attrs, boolean isRelative) {
super(name, className, obj, isRelative);
this.attrs = attrs;
}
/**
* Retrieves the attributes in this search result.
*
* @return The non-null attributes in this search result. Can be empty.
* @see #setAttributes
*/
public Attributes getAttributes() {
return attrs;
}
/**
* Sets the attributes of this search result to <code>attrs</code>.
* @param attrs The non-null attributes to use. Can be empty.
* @see #getAttributes
*/
public void setAttributes(Attributes attrs) {
this.attrs = attrs;
// ??? check for null?
}
/**
* Generates the string representation of this SearchResult.
* The string representation consists of the string representation
* of the binding and the string representation of
* this search result's attributes, separated by ':'.
* The contents of this string is useful
* for debugging and is not meant to be interpreted programmatically.
*
* @return The string representation of this SearchResult. Cannot be null.
*/
public String toString() {
return super.toString() + ":" + getAttributes();
}
/**
* Use serialVersionUID from JNDI 1.1.1 for interoperability
*/
private static final long serialVersionUID = -9158063327699723172L;
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
import javax.naming.Name;
import javax.naming.Context;
import javax.naming.NamingException;
/**
* Contains methods for registering/deregistering listeners to be notified of
* events fired when objects named in a context changes.
*
*<h1>Target</h1>
* The name parameter in the <tt>addNamingListener()</tt> methods is referred
* to as the <em>target</em>. The target, along with the scope, identify
* the object(s) that the listener is interested in.
* It is possible to register interest in a target that does not exist, but
* there might be limitations in the extent to which this can be
* supported by the service provider and underlying protocol/service.
*<p>
* If a service only supports registration for existing
* targets, an attempt to register for a nonexistent target
* results in a <tt>NameNotFoundException</tt> being thrown as early as possible,
* preferably at the time <tt>addNamingListener()</tt> is called, or if that is
* not possible, the listener will receive the exception through the
* <tt>NamingExceptionEvent</tt>.
*<p>
* Also, for service providers that only support registration for existing
* targets, when the target that a listener has registered for is
* subsequently removed from the namespace, the listener is notified
* via a <tt>NamingExceptionEvent</tt> (containing a
*<tt>NameNotFoundException</tt>).
*<p>
* An application can use the method <tt>targetMustExist()</tt> to check
* whether a <tt>EventContext</tt> supports registration
* of nonexistent targets.
*
*<h1>Event Source</h1>
* The <tt>EventContext</tt> instance on which you invoke the
* registration methods is the <em>event source</em> of the events that are
* (potentially) generated.
* The source is <em>not necessarily</em> the object named by the target.
* Only when the target is the empty name is the object named by the target
* the source.
* In other words, the target,
* along with the scope parameter, are used to identify
* the object(s) that the listener is interested in, but the event source
* is the <tt>EventContext</tt> instance with which the listener
* has registered.
*<p>
* For example, suppose a listener makes the following registration:
*<blockquote><pre>
* NamespaceChangeListener listener = ...;
* src.addNamingListener("x", SUBTREE_SCOPE, listener);
*</pre></blockquote>
* When an object named "x/y" is subsequently deleted, the corresponding
* <tt>NamingEvent</tt> (<tt>evt</tt>) must contain:
*<blockquote><pre>
* evt.getEventContext() == src
* evt.getOldBinding().getName().equals("x/y")
*</pre></blockquote>
*<p>
* Furthermore, listener registration/deregistration is with
* the <tt>EventContext</tt>
* <em>instance</em>, and not with the corresponding object in the namespace.
* If the program intends at some point to remove a listener, then it needs to
* keep a reference to the <tt>EventContext</tt> instance on
* which it invoked <tt>addNamingListener()</tt> (just as
* it needs to keep a reference to the listener in order to remove it
* later). It cannot expect to do a <tt>lookup()</tt> and get another instance of
* a <tt>EventContext</tt> on which to perform the deregistration.
*<h1>Lifetime of Registration</h1>
* A registered listener becomes deregistered when:
*<ul>
*<li>It is removed using <tt>removeNamingListener()</tt>.
*<li>An exception is thrown while collecting information about the events.
* That is, when the listener receives a <tt>NamingExceptionEvent</tt>.
*<li><tt>Context.close()</tt> is invoked on the <tt>EventContext</tt>
* instance with which it has registered.
</ul>
* Until that point, a <tt>EventContext</tt> instance that has outstanding
* listeners will continue to exist and be maintained by the service provider.
*
*<h1>Listener Implementations</h1>
* The registration/deregistration methods accept an instance of
* <tt>NamingListener</tt>. There are subinterfaces of <tt>NamingListener</tt>
* for different of event types of <tt>NamingEvent</tt>.
* For example, the <tt>ObjectChangeListener</tt>
* interface is for the <tt>NamingEvent.OBJECT_CHANGED</tt> event type.
* To register interest in multiple event types, the listener implementation
* should implement multiple <tt>NamingListener</tt> subinterfaces and use a
* single invocation of <tt>addNamingListener()</tt>.
* In addition to reducing the number of method calls and possibly the code size
* of the listeners, this allows some service providers to optimize the
* registration.
*
*<h1>Threading Issues</h1>
*
* Like <tt>Context</tt> instances in general, instances of
* <tt>EventContext</tt> are not guaranteed to be thread-safe.
* Care must be taken when multiple threads are accessing the same
* <tt>EventContext</tt> concurrently.
* See the
* <a href=package-summary.html#THREADING>package description</a>
* for more information on threading issues.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public interface EventContext extends Context {
/**
* Constant for expressing interest in events concerning the object named
* by the target.
*<p>
* The value of this constant is <tt>0</tt>.
*/
public final static int OBJECT_SCOPE = 0;
/**
* Constant for expressing interest in events concerning objects
* in the context named by the target,
* excluding the context named by the target.
*<p>
* The value of this constant is <tt>1</tt>.
*/
public final static int ONELEVEL_SCOPE = 1;
/**
* Constant for expressing interest in events concerning objects
* in the subtree of the object named by the target, including the object
* named by the target.
*<p>
* The value of this constant is <tt>2</tt>.
*/
public final static int SUBTREE_SCOPE = 2;
/**
* Adds a listener for receiving naming events fired
* when the object(s) identified by a target and scope changes.
*
* The event source of those events is this context. See the
* class description for a discussion on event source and target.
* See the descriptions of the constants <tt>OBJECT_SCOPE</tt>,
* <tt>ONELEVEL_SCOPE</tt>, and <tt>SUBTREE_SCOPE</tt> to see how
* <tt>scope</tt> affects the registration.
*<p>
* <tt>target</tt> needs to name a context only when <tt>scope</tt> is
* <tt>ONELEVEL_SCOPE</tt>.
* <tt>target</tt> may name a non-context if <tt>scope</tt> is either
* <tt>OBJECT_SCOPE</tt> or <tt>SUBTREE_SCOPE</tt>. Using
* <tt>SUBTREE_SCOPE</tt> for a non-context might be useful,
* for example, if the caller does not know in advance whether <tt>target</tt>
* is a context and just wants to register interest in the (possibly
* degenerate subtree) rooted at <tt>target</tt>.
*<p>
* When the listener is notified of an event, the listener may
* in invoked in a thread other than the one in which
* <tt>addNamingListener()</tt> is executed.
* Care must be taken when multiple threads are accessing the same
* <tt>EventContext</tt> concurrently.
* See the
* <a href=package-summary.html#THREADING>package description</a>
* for more information on threading issues.
*
* @param target A nonnull name to be resolved relative to this context.
* @param scope One of <tt>OBJECT_SCOPE</tt>, <tt>ONELEVEL_SCOPE</tt>, or
* <tt>SUBTREE_SCOPE</tt>.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see #removeNamingListener
*/
void addNamingListener(Name target, int scope, NamingListener l)
throws NamingException;
/**
* Adds a listener for receiving naming events fired
* when the object named by the string target name and scope changes.
*
* See the overload that accepts a <tt>Name</tt> for details.
*
* @param target The nonnull string name of the object resolved relative
* to this context.
* @param scope One of <tt>OBJECT_SCOPE</tt>, <tt>ONELEVEL_SCOPE</tt>, or
* <tt>SUBTREE_SCOPE</tt>.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see #removeNamingListener
*/
void addNamingListener(String target, int scope, NamingListener l)
throws NamingException;
/**
* Removes a listener from receiving naming events fired
* by this <tt>EventContext</tt>.
* The listener may have registered more than once with this
* <tt>EventContext</tt>, perhaps with different target/scope arguments.
* After this method is invoked, the listener will no longer
* receive events with this <tt>EventContext</tt> instance
* as the event source (except for those events already in the process of
* being dispatched).
* If the listener was not, or is no longer, registered with
* this <tt>EventContext</tt> instance, this method does not do anything.
*
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* removing the listener.
* @see #addNamingListener
*/
void removeNamingListener(NamingListener l) throws NamingException;
/**
* Determines whether a listener can register interest in a target
* that does not exist.
*
* @return true if the target must exist; false if the target need not exist.
* @exception NamingException If the context's behavior in this regard cannot
* be determined.
*/
boolean targetMustExist() throws NamingException;
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
/**
* Contains methods for registering listeners to be notified
* of events fired when objects named in a directory context changes.
*<p>
* The methods in this interface support identification of objects by
* <A HREF="http://www.ietf.org/rfc/rfc2254.txt">RFC 2254</a>
* search filters.
*
*<P>Using the search filter, it is possible to register interest in objects
* that do not exist at the time of registration but later come into existence and
* satisfy the filter. However, there might be limitations in the extent
* to which this can be supported by the service provider and underlying
* protocol/service. If the caller submits a filter that cannot be
* supported in this way, <tt>addNamingListener()</tt> throws an
* <tt>InvalidSearchFilterException</tt>.
*<p>
* See <tt>EventContext</tt> for a description of event source
* and target, and information about listener registration/deregistration
* that are also applicable to methods in this interface.
* See the
* <a href=package-summary.html#THREADING>package description</a>
* for information on threading issues.
*<p>
* A <tt>SearchControls</tt> or array object
* passed as a parameter to any method is owned by the caller.
* The service provider will not modify the object or keep a reference to it.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public interface EventDirContext extends EventContext, DirContext {
/**
* Adds a listener for receiving naming events fired
* when objects identified by the search filter <tt>filter</tt> at
* the object named by target are modified.
* <p>
* The scope, returningObj flag, and returningAttributes flag from
* the search controls <tt>ctls</tt> are used to control the selection
* of objects that the listener is interested in,
* and determines what information is returned in the eventual
* <tt>NamingEvent</tt> object. Note that the requested
* information to be returned might not be present in the <tt>NamingEvent</tt>
* object if they are unavailable or could not be obtained by the
* service provider or service.
*
* @param target The nonnull name of the object resolved relative to this context.
* @param filter The nonnull string filter (see RFC2254).
* @param ctls The possibly null search controls. If null, the default
* search controls are used.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see EventContext#removeNamingListener
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, javax.naming.directory.SearchControls)
*/
void addNamingListener(Name target, String filter, SearchControls ctls,
NamingListener l) throws NamingException;
/**
* Adds a listener for receiving naming events fired when
* objects identified by the search filter <tt>filter</tt> at the
* object named by the string target name are modified.
* See the overload that accepts a <tt>Name</tt> for details of
* how this method behaves.
*
* @param target The nonnull string name of the object resolved relative to this context.
* @param filter The nonnull string filter (see RFC2254).
* @param ctls The possibly null search controls. If null, the default
* search controls is used.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see EventContext#removeNamingListener
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, javax.naming.directory.SearchControls)
*/
void addNamingListener(String target, String filter, SearchControls ctls,
NamingListener l) throws NamingException;
/**
* Adds a listener for receiving naming events fired
* when objects identified by the search filter <tt>filter</tt> and
* filter arguments at the object named by the target are modified.
* The scope, returningObj flag, and returningAttributes flag from
* the search controls <tt>ctls</tt> are used to control the selection
* of objects that the listener is interested in,
* and determines what information is returned in the eventual
* <tt>NamingEvent</tt> object. Note that the requested
* information to be returned might not be present in the <tt>NamingEvent</tt>
* object if they are unavailable or could not be obtained by the
* service provider or service.
*
* @param target The nonnull name of the object resolved relative to this context.
* @param filter The nonnull string filter (see RFC2254).
* @param filterArgs The possibly null array of arguments for the filter.
* @param ctls The possibly null search controls. If null, the default
* search controls are used.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see EventContext#removeNamingListener
* @see javax.naming.directory.DirContext#search(javax.naming.Name, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls)
*/
void addNamingListener(Name target, String filter, Object[] filterArgs,
SearchControls ctls, NamingListener l) throws NamingException;
/**
* Adds a listener for receiving naming events fired when
* objects identified by the search filter <tt>filter</tt>
* and filter arguments at the
* object named by the string target name are modified.
* See the overload that accepts a <tt>Name</tt> for details of
* how this method behaves.
*
* @param target The nonnull string name of the object resolved relative to this context.
* @param filter The nonnull string filter (see RFC2254).
* @param filterArgs The possibly null array of arguments for the filter.
* @param ctls The possibly null search controls. If null, the default
* search controls is used.
* @param l The nonnull listener.
* @exception NamingException If a problem was encountered while
* adding the listener.
* @see EventContext#removeNamingListener
* @see javax.naming.directory.DirContext#search(java.lang.String, java.lang.String, java.lang.Object[], javax.naming.directory.SearchControls) */
void addNamingListener(String target, String filter, Object[] filterArgs,
SearchControls ctls, NamingListener l) throws NamingException;
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
/**
* Specifies the methods that a listener interested in namespace changes
* must implement.
* Specifically, the listener is interested in <tt>NamingEvent</tt>s
* with event types of <tt>OBJECT_ADDED</TT>, <TT>OBJECT_RENAMED</TT>, or
* <TT>OBJECT_REMOVED</TT>.
*<p>
* Such a listener must:
*<ol>
*<li>Implement this interface and its methods.
*<li>Implement <tt>NamingListener.namingExceptionThrown()</tt> so that
* it will be notified of exceptions thrown while attempting to
* collect information about the events.
*<li>Register with the source using the source's <tt>addNamingListener()</tt>
* method.
*</ol>
* A listener that wants to be notified of <tt>OBJECT_CHANGED</tt> event types
* should also implement the <tt>ObjectChangeListener</tt>
* interface.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingEvent
* @see ObjectChangeListener
* @see EventContext
* @see EventDirContext
* @since 1.3
*/
public interface NamespaceChangeListener extends NamingListener {
/**
* Called when an object has been added.
*<p>
* The binding of the newly added object can be obtained using
* <tt>evt.getNewBinding()</tt>.
* @param evt The nonnull event.
* @see NamingEvent#OBJECT_ADDED
*/
void objectAdded(NamingEvent evt);
/**
* Called when an object has been removed.
*<p>
* The binding of the newly removed object can be obtained using
* <tt>evt.getOldBinding()</tt>.
* @param evt The nonnull event.
* @see NamingEvent#OBJECT_REMOVED
*/
void objectRemoved(NamingEvent evt);
/**
* Called when an object has been renamed.
*<p>
* The binding of the renamed object can be obtained using
* <tt>evt.getNewBinding()</tt>. Its old binding (before the rename)
* can be obtained using <tt>evt.getOldBinding()</tt>.
* One of these may be null if the old/new binding was outside the
* scope in which the listener has registered interest.
* @param evt The nonnull event.
* @see NamingEvent#OBJECT_RENAMED
*/
void objectRenamed(NamingEvent evt);
}

View File

@@ -0,0 +1,300 @@
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
import javax.naming.Binding;
/**
* This class represents an event fired by a naming/directory service.
*<p>
* The <tt>NamingEvent</tt>'s state consists of
* <ul>
* <li>The event source: the <tt>EventContext</tt> which fired this event.
* <li>The event type.
* <li>The new binding: information about the object after the change.
* <li>The old binding: information about the object before the change.
* <li>Change information: information about the change
* that triggered this event; usually service provider-specific or server-specific
* information.
* </ul>
* <p>
* Note that the event source is always the same <tt>EventContext</tt>
* <em>instance</em> that the listener has registered with.
* Furthermore, the names of the bindings in
* the <tt>NamingEvent</tt> are always relative to that instance.
* For example, suppose a listener makes the following registration:
*<blockquote><pre>
* NamespaceChangeListener listener = ...;
* src.addNamingListener("x", SUBTREE_SCOPE, listener);
*</pre></blockquote>
* When an object named "x/y" is subsequently deleted, the corresponding
* <tt>NamingEvent</tt> (<tt>evt</tt>) must contain:
*<blockquote><pre>
* evt.getEventContext() == src
* evt.getOldBinding().getName().equals("x/y")
*</pre></blockquote>
*
* Care must be taken when multiple threads are accessing the same
* <tt>EventContext</tt> concurrently.
* See the
* <a href=package-summary.html#THREADING>package description</a>
* for more information on threading issues.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingListener
* @see EventContext
* @since 1.3
*/
public class NamingEvent extends java.util.EventObject {
/**
* Naming event type for indicating that a new object has been added.
* The value of this constant is <tt>0</tt>.
*/
public static final int OBJECT_ADDED = 0;
/**
* Naming event type for indicating that an object has been removed.
* The value of this constant is <tt>1</tt>.
*/
public static final int OBJECT_REMOVED = 1;
/**
* Naming event type for indicating that an object has been renamed.
* Note that some services might fire multiple events for a single
* logical rename operation. For example, the rename operation might
* be implemented by adding a binding with the new name and removing
* the old binding.
*<p>
* The old/new binding in <tt>NamingEvent</tt> may be null if the old
* name or new name is outside of the scope for which the listener
* has registered.
*<p>
* When an interior node in the namespace tree has been renamed, the
* topmost node which is part of the listener's scope should used to generate
* a rename event. The extent to which this can be supported is
* provider-specific. For example, a service might generate rename
* notifications for all descendants of the changed interior node and the
* corresponding provider might not be able to prevent those
* notifications from being propagated to the listeners.
*<p>
* The value of this constant is <tt>2</tt>.
*/
public static final int OBJECT_RENAMED = 2;
/**
* Naming event type for indicating that an object has been changed.
* The changes might include the object's attributes, or the object itself.
* Note that some services might fire multiple events for a single
* modification. For example, the modification might
* be implemented by first removing the old binding and adding
* a new binding containing the same name but a different object.
*<p>
* The value of this constant is <tt>3</tt>.
*/
public static final int OBJECT_CHANGED = 3;
/**
* Contains information about the change that generated this event.
* @serial
*/
protected Object changeInfo;
/**
* Contains the type of this event.
* @see #OBJECT_ADDED
* @see #OBJECT_REMOVED
* @see #OBJECT_RENAMED
* @see #OBJECT_CHANGED
* @serial
*/
protected int type;
/**
* Contains information about the object before the change.
* @serial
*/
protected Binding oldBinding;
/**
* Contains information about the object after the change.
* @serial
*/
protected Binding newBinding;
/**
* Constructs an instance of <tt>NamingEvent</tt>.
*<p>
* The names in <tt>newBd</tt> and <tt>oldBd</tt> are to be resolved relative
* to the event source <tt>source</tt>.
*
* For an <tt>OBJECT_ADDED</tt> event type, <tt>newBd</tt> must not be null.
* For an <tt>OBJECT_REMOVED</tt> event type, <tt>oldBd</tt> must not be null.
* For an <tt>OBJECT_CHANGED</tt> event type, <tt>newBd</tt> and
* <tt>oldBd</tt> must not be null. For an <tt>OBJECT_RENAMED</tt> event type,
* one of <tt>newBd</tt> or <tt>oldBd</tt> may be null if the new or old
* binding is outside of the scope for which the listener has registered.
*
* @param source The non-null context that fired this event.
* @param type The type of the event.
* @param newBd A possibly null binding before the change. See method description.
* @param oldBd A possibly null binding after the change. See method description.
* @param changeInfo A possibly null object containing information about the change.
* @see #OBJECT_ADDED
* @see #OBJECT_REMOVED
* @see #OBJECT_RENAMED
* @see #OBJECT_CHANGED
*/
public NamingEvent(EventContext source, int type,
Binding newBd, Binding oldBd, Object changeInfo) {
super(source);
this.type = type;
oldBinding = oldBd;
newBinding = newBd;
this.changeInfo = changeInfo;
}
/**
* Returns the type of this event.
* @return The type of this event.
* @see #OBJECT_ADDED
* @see #OBJECT_REMOVED
* @see #OBJECT_RENAMED
* @see #OBJECT_CHANGED
*/
public int getType() {
return type;
}
/**
* Retrieves the event source that fired this event.
* This returns the same object as <tt>EventObject.getSource()</tt>.
*<p>
* If the result of this method is used to access the
* event source, for example, to look up the object or get its attributes,
* then it needs to be locked because implementations of <tt>Context</tt>
* are not guaranteed to be thread-safe
* (and <tt>EventContext</tt> is a subinterface of <tt>Context</tt>).
* See the
* <a href=package-summary.html#THREADING>package description</a>
* for more information on threading issues.
*
* @return The non-null context that fired this event.
*/
public EventContext getEventContext() {
return (EventContext)getSource();
}
/**
* Retrieves the binding of the object before the change.
*<p>
* The binding must be nonnull if the object existed before the change
* relative to the source context (<tt>getEventContext()</tt>).
* That is, it must be nonnull for <tt>OBJECT_REMOVED</tt> and
* <tt>OBJECT_CHANGED</tt>.
* For <tt>OBJECT_RENAMED</tt>, it is null if the object before the rename
* is outside of the scope for which the listener has registered interest;
* it is nonnull if the object is inside the scope before the rename.
*<p>
* The name in the binding is to be resolved relative
* to the event source <tt>getEventContext()</tt>.
* The object returned by <tt>Binding.getObject()</tt> may be null if
* such information is unavailable.
*
* @return The possibly null binding of the object before the change.
*/
public Binding getOldBinding() {
return oldBinding;
}
/**
* Retrieves the binding of the object after the change.
*<p>
* The binding must be nonnull if the object existed after the change
* relative to the source context (<tt>getEventContext()</tt>).
* That is, it must be nonnull for <tt>OBJECT_ADDED</tt> and
* <tt>OBJECT_CHANGED</tt>. For <tt>OBJECT_RENAMED</tt>,
* it is null if the object after the rename is outside the scope for
* which the listener registered interest; it is nonnull if the object
* is inside the scope after the rename.
*<p>
* The name in the binding is to be resolved relative
* to the event source <tt>getEventContext()</tt>.
* The object returned by <tt>Binding.getObject()</tt> may be null if
* such information is unavailable.
*
* @return The possibly null binding of the object after the change.
*/
public Binding getNewBinding() {
return newBinding;
}
/**
* Retrieves the change information for this event.
* The value of the change information is service-specific. For example,
* it could be an ID that identifies the change in a change log on the server.
*
* @return The possibly null change information of this event.
*/
public Object getChangeInfo() {
return changeInfo;
}
/**
* Invokes the appropriate listener method on this event.
* The default implementation of
* this method handles the following event types:
* <tt>OBJECT_ADDED</TT>, <TT>OBJECT_REMOVED</TT>,
* <TT>OBJECT_RENAMED</TT>, <TT>OBJECT_CHANGED</TT>.
*<p>
* The listener method is executed in the same thread
* as this method. See the
* <a href=package-summary.html#THREADING>package description</a>
* for more information on threading issues.
* @param listener The nonnull listener.
*/
public void dispatch(NamingListener listener) {
switch (type) {
case OBJECT_ADDED:
((NamespaceChangeListener)listener).objectAdded(this);
break;
case OBJECT_REMOVED:
((NamespaceChangeListener)listener).objectRemoved(this);
break;
case OBJECT_RENAMED:
((NamespaceChangeListener)listener).objectRenamed(this);
break;
case OBJECT_CHANGED:
((ObjectChangeListener)listener).objectChanged(this);
break;
}
}
private static final long serialVersionUID = -7126752885365133499L;
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
import javax.naming.NamingException;
/**
* This class represents an event fired when the procedures/processes
* used to collect information for notifying listeners of
* <tt>NamingEvent</tt>s threw a <tt>NamingException</tt>.
* This can happen, for example, if the server which the listener is using
* aborts subsequent to the <tt>addNamingListener()</tt> call.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingListener#namingExceptionThrown
* @see EventContext
* @since 1.3
*/
public class NamingExceptionEvent extends java.util.EventObject {
/**
* Contains the exception that was thrown
* @serial
*/
private NamingException exception;
/**
* Constructs an instance of <tt>NamingExceptionEvent</tt> using
* the context in which the <tt>NamingException</tt> was thrown and the exception
* that was thrown.
*
* @param source The non-null context in which the exception was thrown.
* @param exc The non-null <tt>NamingException</tt> that was thrown.
*
*/
public NamingExceptionEvent(EventContext source, NamingException exc) {
super(source);
exception = exc;
}
/**
* Retrieves the exception that was thrown.
* @return The exception that was thrown.
*/
public NamingException getException() {
return exception;
}
/**
* Retrieves the <tt>EventContext</tt> that fired this event.
* This returns the same object as <tt>EventObject.getSource()</tt>.
* @return The non-null <tt>EventContext</tt> that fired this event.
*/
public EventContext getEventContext() {
return (EventContext)getSource();
}
/**
* Invokes the <tt>namingExceptionThrown()</tt> method on
* a listener using this event.
* @param listener The non-null naming listener on which to invoke
* the method.
*/
public void dispatch(NamingListener listener) {
listener.namingExceptionThrown(this);
}
private static final long serialVersionUID = -4877678086134736336L;
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
/**
* This interface is the root of listener interfaces that
* handle <tt>NamingEvent</tt>s.
* It does not make sense for a listener to implement just this interface.
* A listener typically implements a subinterface of <tt>NamingListener</tt>,
* such as <tt>ObjectChangeListener</tt> or <tt>NamespaceChangeListener</tt>.
*<p>
* This interface contains a single method, <tt>namingExceptionThrown()</tt>,
* that must be implemented so that the listener can be notified of
* exceptions that are thrown (by the service provider) while gathering
* information about the events that they're interested in.
* When this method is invoked, the listener has been automatically deregistered
* from the <tt>EventContext</tt> with which it has registered.
*<p>
* For example, suppose a listener implements <tt>ObjectChangeListener</tt> and
* registers with a <tt>EventContext</tt>.
* Then, if the connection to the server is subsequently broken,
* the listener will receive a <tt>NamingExceptionEvent</tt> and may
* take some corrective action, such as notifying the user of the application.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingEvent
* @see NamingExceptionEvent
* @see EventContext
* @see EventDirContext
* @since 1.3
*/
public interface NamingListener extends java.util.EventListener {
/**
* Called when a naming exception is thrown while attempting
* to fire a <tt>NamingEvent</tt>.
*
* @param evt The nonnull event.
*/
void namingExceptionThrown(NamingExceptionEvent evt);
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.event;
/**
* Specifies the method that a listener of a <tt>NamingEvent</tt>
* with event type of <tt>OBJECT_CHANGED</tt> must implement.
*<p>
* An <tt>OBJECT_CHANGED</tt> event type is fired when (the contents of)
* an object has changed. This might mean that its attributes have been modified,
* added, or removed, and/or that the object itself has been replaced.
* How the object has changed can be determined by examining the
* <tt>NamingEvent</tt>'s old and new bindings.
*<p>
* A listener interested in <tt>OBJECT_CHANGED</tt> event types must:
*<ol>
*
*<li>Implement this interface and its method (<tt>objectChanged()</tt>)
*<li>Implement <tt>NamingListener.namingExceptionThrown()</tt> so that
* it will be notified of exceptions thrown while attempting to
* collect information about the events.
*<li>Register with the source using the source's <tt>addNamingListener()</tt>
* method.
*</ol>
* A listener that wants to be notified of namespace change events
* should also implement the <tt>NamespaceChangeListener</tt>
* interface.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingEvent
* @see NamespaceChangeListener
* @see EventContext
* @see EventDirContext
* @since 1.3
*/
public interface ObjectChangeListener extends NamingListener {
/**
* Called when an object has been changed.
*<p>
* The binding of the changed object can be obtained using
* <tt>evt.getNewBinding()</tt>. Its old binding (before the change)
* can be obtained using <tt>evt.getOldBinding()</tt>.
* @param evt The nonnull naming event.
* @see NamingEvent#OBJECT_CHANGED
*/
void objectChanged(NamingEvent evt);
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* This class provides a basic implementation of the <tt>Control</tt>
* interface. It represents an LDAPv3 Control as defined in
* <a href="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</a>.
*
* @since 1.5
* @author Vincent Ryan
*/
public class BasicControl implements Control {
/**
* The control's object identifier string.
*
* @serial
*/
protected String id;
/**
* The control's criticality.
*
* @serial
*/
protected boolean criticality = false; // default
/**
* The control's ASN.1 BER encoded value.
*
* @serial
*/
protected byte[] value = null;
private static final long serialVersionUID = -4233907508771791687L;
/**
* Constructs a non-critical control.
*
* @param id The control's object identifier string.
*
*/
public BasicControl(String id) {
this.id = id;
}
/**
* Constructs a control using the supplied arguments.
*
* @param id The control's object identifier string.
* @param criticality The control's criticality.
* @param value The control's ASN.1 BER encoded value.
* It is not cloned - any changes to value
* will affect the contents of the control.
* It may be null.
*/
public BasicControl(String id, boolean criticality, byte[] value) {
this.id = id;
this.criticality = criticality;
this.value = value;
}
/**
* Retrieves the control's object identifier string.
*
* @return The non-null object identifier string.
*/
public String getID() {
return id;
}
/**
* Determines the control's criticality.
*
* @return true if the control is critical; false otherwise.
*/
public boolean isCritical() {
return criticality;
}
/**
* Retrieves the control's ASN.1 BER encoded value.
* The result includes the BER tag and length for the control's value but
* does not include the control's object identifier and criticality setting.
*
* @return A possibly null byte array representing the control's
* ASN.1 BER encoded value. It is not cloned - any changes to the
* returned value will affect the contents of the control.
*/
public byte[] getEncodedValue() {
return value;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* This interface represents an LDAPv3 control as defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
*<p>
* The LDAPv3 protocol uses controls to send and receive additional data
* to affect the behavior of predefined operations.
* Controls can be sent along with any LDAP operation to the server.
* These are referred to as <em>request controls</em>. For example, a
* "sort" control can be sent with an LDAP search operation to
* request that the results be returned in a particular order.
* Solicited and unsolicited controls can also be returned with
* responses from the server. Such controls are referred to as
* <em>response controls</em>. For example, an LDAP server might
* define a special control to return change notifications.
*<p>
* This interface is used to represent both request and response controls.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see ControlFactory
* @since 1.3
*/
public interface Control extends java.io.Serializable {
/**
* Indicates a critical control.
* The value of this constant is <tt>true</tt>.
*/
public static final boolean CRITICAL = true;
/**
* Indicates a non-critical control.
* The value of this constant is <tt>false</tt>.
*/
public static final boolean NONCRITICAL = false;
/**
* Retrieves the object identifier assigned for the LDAP control.
*
* @return The non-null object identifier string.
*/
public String getID();
/**
* Determines the criticality of the LDAP control.
* A critical control must not be ignored by the server.
* In other words, if the server receives a critical control
* that it does not support, regardless of whether the control
* makes sense for the operation, the operation will not be performed
* and an <tt>OperationNotSupportedException</tt> will be thrown.
* @return true if this control is critical; false otherwise.
*/
public boolean isCritical();
/**
* Retrieves the ASN.1 BER encoded value of the LDAP control.
* The result is the raw BER bytes including the tag and length of
* the control's value. It does not include the controls OID or criticality.
*
* Null is returned if the value is absent.
*
* @return A possibly null byte array representing the ASN.1 BER encoded
* value of the LDAP control.
*/
public byte[] getEncodedValue();
// static final long serialVersionUID = -591027748900004825L;
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.NamingException;
import javax.naming.Context;
import java.util.Hashtable;
import com.sun.naming.internal.FactoryEnumeration;
import com.sun.naming.internal.ResourceManager;
/**
* This abstract class represents a factory for creating LDAPv3 controls.
* LDAPv3 controls are defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
*<p>
* When a service provider receives a response control, it uses control
* factories to return the specific/appropriate control class implementation.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see Control
* @since 1.3
*/
public abstract class ControlFactory {
/**
* Creates a new instance of a control factory.
*/
protected ControlFactory() {
}
/**
* Creates a control using this control factory.
*<p>
* The factory is used by the service provider to return controls
* that it reads from the LDAP protocol as specialized control classes.
* Without this mechanism, the provider would be returning
* controls that only contained data in BER encoded format.
*<p>
* Typically, <tt>ctl</tt> is a "basic" control containing
* BER encoded data. The factory is used to create a specialized
* control implementation, usually by decoding the BER encoded data,
* that provides methods to access that data in a type-safe and friendly
* manner.
* <p>
* For example, a factory might use the BER encoded data in
* basic control and return an instance of a VirtualListReplyControl.
*<p>
* If this factory cannot create a control using the argument supplied,
* it should return null.
* A factory should only throw an exception if it is sure that
* it is the only intended factory and that no other control factories
* should be tried. This might happen, for example, if the BER data
* in the control does not match what is expected of a control with
* the given OID. Since this method throws <tt>NamingException</tt>,
* any other internally generated exception that should be propagated
* must be wrapped inside a <tt>NamingException</tt>.
*
* @param ctl A non-null control.
*
* @return A possibly null Control.
* @exception NamingException If <tt>ctl</tt> contains invalid data that prevents it
* from being used to create a control. A factory should only throw
* an exception if it knows how to produce the control (identified by the OID)
* but is unable to because of, for example invalid BER data.
*/
public abstract Control getControlInstance(Control ctl) throws NamingException;
/**
* Creates a control using known control factories.
* <p>
* The following rule is used to create the control:
*<ul>
* <li> Use the control factories specified in
* the <tt>LdapContext.CONTROL_FACTORIES</tt> property of the
* environment, and of the provider resource file associated with
* <tt>ctx</tt>, in that order.
* The value of this property is a colon-separated list of factory
* class names that are tried in order, and the first one that succeeds
* in creating the control is the one used.
* If none of the factories can be loaded,
* return <code>ctl</code>.
* If an exception is encountered while creating the control, the
* exception is passed up to the caller.
*</ul>
* <p>
* Note that a control factory
* must be public and must have a public constructor that accepts no arguments.
* <p>
* @param ctl The non-null control object containing the OID and BER data.
* @param ctx The possibly null context in which the control is being created.
* If null, no such information is available.
* @param env The possibly null environment of the context. This is used
* to find the value of the <tt>LdapContext.CONTROL_FACTORIES</tt> property.
* @return A control object created using <code>ctl</code>; or
* <code>ctl</code> if a control object cannot be created using
* the algorithm described above.
* @exception NamingException if a naming exception was encountered
* while attempting to create the control object.
* If one of the factories accessed throws an
* exception, it is propagated up to the caller.
* If an error was encountered while loading
* and instantiating the factory and object classes, the exception
* is wrapped inside a <tt>NamingException</tt> and then rethrown.
*/
public static Control getControlInstance(Control ctl, Context ctx,
Hashtable<?,?> env)
throws NamingException {
// Get object factories list from environment properties or
// provider resource file.
FactoryEnumeration factories = ResourceManager.getFactories(
LdapContext.CONTROL_FACTORIES, env, ctx);
if (factories == null) {
return ctl;
}
// Try each factory until one succeeds
Control answer = null;
ControlFactory factory;
while (answer == null && factories.hasMore()) {
factory = (ControlFactory)factories.next();
answer = factory.getControlInstance(ctl);
}
return (answer != null)? answer : ctl;
}
}

View File

@@ -0,0 +1,148 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.NamingException;
/**
* This interface represents an LDAPv3 extended operation request as defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
* <pre>
* ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
* requestName [0] LDAPOID,
* requestValue [1] OCTET STRING OPTIONAL }
* </pre>
* It comprises an object identifier string and an optional ASN.1 BER
* encoded value.
*<p>
* The methods in this class are used by the service provider to construct
* the bits to send to the LDAP server. Applications typically only deal with
* the classes that implement this interface, supplying them with
* any information required for a particular extended operation request.
* It would then pass such a class as an argument to the
* <tt>LdapContext.extendedOperation()</tt> method for performing the
* LDAPv3 extended operation.
*<p>
* For example, suppose the LDAP server supported a 'get time' extended operation.
* It would supply GetTimeRequest and GetTimeResponse classes:
*<blockquote><pre>
* public class GetTimeRequest implements ExtendedRequest {
* public GetTimeRequest() {... };
* public ExtendedResponse createExtendedResponse(String id,
* byte[] berValue, int offset, int length)
* throws NamingException {
* return new GetTimeResponse(id, berValue, offset, length);
* }
* ...
* }
* public class GetTimeResponse implements ExtendedResponse {
* long time;
* public GetTimeResponse(String id, byte[] berValue, int offset,
* int length) throws NamingException {
* time = ... // decode berValue to get time
* }
* public java.util.Date getDate() { return new java.util.Date(time) };
* public long getTime() { return time };
* ...
* }
*</pre></blockquote>
* A program would use then these classes as follows:
*<blockquote><pre>
* GetTimeResponse resp =
* (GetTimeResponse) ectx.extendedOperation(new GetTimeRequest());
* long time = resp.getTime();
*</pre></blockquote>
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see ExtendedResponse
* @see LdapContext#extendedOperation
* @since 1.3
*/
public interface ExtendedRequest extends java.io.Serializable {
/**
* Retrieves the object identifier of the request.
*
* @return The non-null object identifier string representing the LDAP
* <tt>ExtendedRequest.requestName</tt> component.
*/
public String getID();
/**
* Retrieves the ASN.1 BER encoded value of the LDAP extended operation
* request. Null is returned if the value is absent.
*
* The result is the raw BER bytes including the tag and length of
* the request value. It does not include the request OID.
* This method is called by the service provider to get the bits to
* put into the extended operation to be sent to the LDAP server.
*
* @return A possibly null byte array representing the ASN.1 BER encoded
* contents of the LDAP <tt>ExtendedRequest.requestValue</tt>
* component.
* @exception IllegalStateException If the encoded value cannot be retrieved
* because the request contains insufficient or invalid data/state.
*/
public byte[] getEncodedValue();
/**
* Creates the response object that corresponds to this request.
*<p>
* After the service provider has sent the extended operation request
* to the LDAP server, it will receive a response from the server.
* If the operation failed, the provider will throw a NamingException.
* If the operation succeeded, the provider will invoke this method
* using the data that it got back in the response.
* It is the job of this method to return a class that implements
* the ExtendedResponse interface that is appropriate for the
* extended operation request.
*<p>
* For example, a Start TLS extended request class would need to know
* how to process a Start TLS extended response. It does this by creating
* a class that implements ExtendedResponse.
*
* @param id The possibly null object identifier of the response
* control.
* @param berValue The possibly null ASN.1 BER encoded value of the
* response control.
* This is the raw BER bytes including the tag and length of
* the response value. It does not include the response OID.
* @param offset The starting position in berValue of the bytes to use.
* @param length The number of bytes in berValue to use.
*
* @return A non-null object.
* @exception NamingException if cannot create extended response
* due to an error.
* @see ExtendedResponse
*/
public ExtendedResponse createExtendedResponse(String id,
byte[] berValue, int offset, int length) throws NamingException;
// static final long serialVersionUID = -7560110759229059814L;
}

View File

@@ -0,0 +1,99 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* This interface represents an LDAP extended operation response as defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
* <pre>
* ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
* COMPONENTS OF LDAPResult,
* responseName [10] LDAPOID OPTIONAL,
* response [11] OCTET STRING OPTIONAL }
* </pre>
* It comprises an optional object identifier and an optional ASN.1 BER
* encoded value.
*
*<p>
* The methods in this class can be used by the application to get low
* level information about the extended operation response. However, typically,
* the application will be using methods specific to the class that
* implements this interface. Such a class should have decoded the BER buffer
* in the response and should provide methods that allow the user to
* access that data in the response in a type-safe and friendly manner.
*<p>
* For example, suppose the LDAP server supported a 'get time' extended operation.
* It would supply GetTimeRequest and GetTimeResponse classes.
* The GetTimeResponse class might look like:
*<blockquote><pre>
* public class GetTimeResponse implements ExtendedResponse {
* public java.util.Date getDate() {...};
* public long getTime() {...};
* ....
* }
*</pre></blockquote>
* A program would use then these classes as follows:
*<blockquote><pre>
* GetTimeResponse resp =
* (GetTimeResponse) ectx.extendedOperation(new GetTimeRequest());
* java.util.Date now = resp.getDate();
*</pre></blockquote>
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see ExtendedRequest
* @since 1.3
*/
public interface ExtendedResponse extends java.io.Serializable {
/**
* Retrieves the object identifier of the response.
* The LDAP protocol specifies that the response object identifier is optional.
* If the server does not send it, the response will contain no ID (i.e. null).
*
* @return A possibly null object identifier string representing the LDAP
* <tt>ExtendedResponse.responseName</tt> component.
*/
public String getID();
/**
* Retrieves the ASN.1 BER encoded value of the LDAP extended operation
* response. Null is returned if the value is absent from the response
* sent by the LDAP server.
* The result is the raw BER bytes including the tag and length of
* the response value. It does not include the response OID.
*
* @return A possibly null byte array representing the ASN.1 BER encoded
* contents of the LDAP <tt>ExtendedResponse.response</tt>
* component.
*/
public byte[] getEncodedValue();
//static final long serialVersionUID = -3320509678029180273L;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.NamingException;
/**
* This interface is for returning controls with objects returned
* in NamingEnumerations.
* For example, suppose a server sends back controls with the results
* of a search operation, the service provider would return a NamingEnumeration of
* objects that are both SearchResult and implement HasControls.
*<blockquote><pre>
* NamingEnumeration elts = ectx.search((Name)name, filter, sctls);
* while (elts.hasMore()) {
* Object entry = elts.next();
*
* // Get search result
* SearchResult res = (SearchResult)entry;
* // do something with it
*
* // Get entry controls
* if (entry instanceof HasControls) {
* Control[] entryCtls = ((HasControls)entry).getControls();
* // do something with controls
* }
* }
*</pre></blockquote>
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
* @since 1.3
*
*/
public interface HasControls {
/**
* Retrieves an array of <tt>Control</tt>s from the object that
* implements this interface. It is null if there are no controls.
*
* @return A possibly null array of <tt>Control</tt> objects.
* @throws NamingException If cannot return controls due to an error.
*/
public Control[] getControls() throws NamingException;
}

View File

@@ -0,0 +1,212 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.*;
import javax.naming.directory.*;
import java.util.Hashtable;
/**
* This class is the starting context for performing
* LDAPv3-style extended operations and controls.
*<p>
* See <tt>javax.naming.InitialContext</tt> and
* <tt>javax.naming.InitialDirContext</tt> for details on synchronization,
* and the policy for how an initial context is created.
*
* <h1>Request Controls</h1>
* When you create an initial context (<tt>InitialLdapContext</tt>),
* you can specify a list of request controls.
* These controls will be used as the request controls for any
* implicit LDAP "bind" operation performed by the context or contexts
* derived from the context. These are called <em>connection request controls</em>.
* Use <tt>getConnectControls()</tt> to get a context's connection request
* controls.
*<p>
* The request controls supplied to the initial context constructor
* are <em>not</em> used as the context request controls
* for subsequent context operations such as searches and lookups.
* Context request controls are set and updated by using
* <tt>setRequestControls()</tt>.
*<p>
* As shown, there can be two different sets of request controls
* associated with a context: connection request controls and context
* request controls.
* This is required for those applications needing to send critical
* controls that might not be applicable to both the context operation and
* any implicit LDAP "bind" operation.
* A typical user program would do the following:
*<blockquote><pre>
* InitialLdapContext lctx = new InitialLdapContext(env, critConnCtls);
* lctx.setRequestControls(critModCtls);
* lctx.modifyAttributes(name, mods);
* Controls[] respCtls = lctx.getResponseControls();
*</pre></blockquote>
* It specifies first the critical controls for creating the initial context
* (<tt>critConnCtls</tt>), and then sets the context's request controls
* (<tt>critModCtls</tt>) for the context operation. If for some reason
* <tt>lctx</tt> needs to reconnect to the server, it will use
* <tt>critConnCtls</tt>. See the <tt>LdapContext</tt> interface for
* more discussion about request controls.
*<p>
* Service provider implementors should read the "Service Provider" section
* in the <tt>LdapContext</tt> class description for implementation details.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see LdapContext
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
* @see javax.naming.spi.NamingManager#setInitialContextFactoryBuilder
* @since 1.3
*/
public class InitialLdapContext extends InitialDirContext implements LdapContext {
private static final String
BIND_CONTROLS_PROPERTY = "java.naming.ldap.control.connect";
/**
* Constructs an initial context using no environment properties or
* connection request controls.
* Equivalent to <tt>new InitialLdapContext(null, null)</tt>.
*
* @throws NamingException if a naming exception is encountered
*/
public InitialLdapContext() throws NamingException {
super(null);
}
/**
* Constructs an initial context
* using environment properties and connection request controls.
* See <tt>javax.naming.InitialContext</tt> for a discussion of
* environment properties.
*
* <p> This constructor will not modify its parameters or
* save references to them, but may save a clone or copy.
* Caller should not modify mutable keys and values in
* <tt>environment</tt> after it has been passed to the constructor.
*
* <p> <tt>connCtls</tt> is used as the underlying context instance's
* connection request controls. See the class description
* for details.
*
* @param environment
* environment used to create the initial DirContext.
* Null indicates an empty environment.
* @param connCtls
* connection request controls for the initial context.
* If null, no connection request controls are used.
*
* @throws NamingException if a naming exception is encountered
*
* @see #reconnect
* @see LdapContext#reconnect
*/
@SuppressWarnings("unchecked")
public InitialLdapContext(Hashtable<?,?> environment,
Control[] connCtls)
throws NamingException {
super(true); // don't initialize yet
// Clone environment since caller owns it.
Hashtable<Object,Object> env = (environment == null)
? new Hashtable<>(11)
: (Hashtable<Object,Object>)environment.clone();
// Put connect controls into environment. Copy them first since
// caller owns the array.
if (connCtls != null) {
Control[] copy = new Control[connCtls.length];
System.arraycopy(connCtls, 0, copy, 0, connCtls.length);
env.put(BIND_CONTROLS_PROPERTY, copy);
}
// set version to LDAPv3
env.put("java.naming.ldap.version", "3");
// Initialize with updated environment
init(env);
}
/**
* Retrieves the initial LDAP context.
*
* @return The non-null cached initial context.
* @exception NotContextException If the initial context is not an
* instance of <tt>LdapContext</tt>.
* @exception NamingException If a naming exception was encountered.
*/
private LdapContext getDefaultLdapInitCtx() throws NamingException{
Context answer = getDefaultInitCtx();
if (!(answer instanceof LdapContext)) {
if (answer == null) {
throw new NoInitialContextException();
} else {
throw new NotContextException(
"Not an instance of LdapContext");
}
}
return (LdapContext)answer;
}
// LdapContext methods
// Most Javadoc is deferred to the LdapContext interface.
public ExtendedResponse extendedOperation(ExtendedRequest request)
throws NamingException {
return getDefaultLdapInitCtx().extendedOperation(request);
}
public LdapContext newInstance(Control[] reqCtls)
throws NamingException {
return getDefaultLdapInitCtx().newInstance(reqCtls);
}
public void reconnect(Control[] connCtls) throws NamingException {
getDefaultLdapInitCtx().reconnect(connCtls);
}
public Control[] getConnectControls() throws NamingException {
return getDefaultLdapInitCtx().getConnectControls();
}
public void setRequestControls(Control[] requestControls)
throws NamingException {
getDefaultLdapInitCtx().setRequestControls(requestControls);
}
public Control[] getRequestControls() throws NamingException {
return getDefaultLdapInitCtx().getRequestControls();
}
public Control[] getResponseControls() throws NamingException {
return getDefaultLdapInitCtx().getResponseControls();
}
}

View File

@@ -0,0 +1,347 @@
/*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import java.util.Hashtable;
/**
* This interface represents a context in which you can perform
* operations with LDAPv3-style controls and perform LDAPv3-style
* extended operations.
*
* For applications that do not require such controls or extended
* operations, the more generic <tt>javax.naming.directory.DirContext</tt>
* should be used instead.
*
* <h3>Usage Details About Controls</h3>
*
* This interface provides support for LDAP v3 controls.
* At a high level, this support allows a user
* program to set request controls for LDAP operations that are executed
* in the course of the user program's invocation of
* <tt>Context</tt>/<tt>DirContext</tt>
* methods, and read response controls resulting from LDAP operations.
* At the implementation level, there are some details that developers of
* both the user program and service providers need to understand in order
* to correctly use request and response controls.
*
* <h3>Request Controls</h3>
* <p>
* There are two types of request controls:
* <ul>
* <li>Request controls that affect how a connection is created
* <li>Request controls that affect context methods
* </ul>
*
* The former is used whenever a connection needs to be established or
* re-established with an LDAP server. The latter is used when all other
* LDAP operations are sent to the LDAP server. The reason why a
* distinction between these two types of request controls is necessary
* is because JNDI is a high-level API that does not deal directly with
* connections. It is the job of service providers to do any necessary
* connection management. Consequently, a single
* connection may be shared by multiple context instances, and a service provider
* is free to use its own algorithms to conserve connection and network
* usage. Thus, when a method is invoked on the context instance, the service
* provider might need to do some connection management in addition to
* performing the corresponding LDAP operations. For connection management,
* it uses the <em>connection request controls</em>, while for the normal
* LDAP operations, it uses the <em>context request controls</em>.
*<p>Unless explicitly qualified, the term "request controls" refers to
* context request controls.
*
* <h4>Context Request Controls</h4>
* There are two ways in which a context instance gets its request controls:
* <ol>
* <li><tt>ldapContext.newInstance(<strong>reqCtls</strong>)</tt>
* <li><tt>ldapContext.setRequestControls(<strong>reqCtls</strong>)</tt>
* </ol>
* where <tt>ldapContext</tt> is an instance of <tt>LdapContext</tt>.
* Specifying <tt>null</tt> or an empty array for <tt>reqCtls</tt>
* means no request controls.
* <tt>newInstance()</tt> creates a new instance of a context using
* <tt>reqCtls</tt>, while <tt>setRequestControls()</tt>
* updates an existing context instance's request controls to <tt>reqCtls</tt>.
* <p>
* Unlike environment properties, request controls of a context instance
* <em>are not inherited</em> by context instances that are derived from
* it. Derived context instances have <tt>null</tt> as their context
* request controls. You must set the request controls of a derived context
* instance explicitly using <tt>setRequestControls()</tt>.
* <p>
* A context instance's request controls are retrieved using
* the method <tt>getRequestControls()</tt>.
*
* <h4>Connection Request Controls</h4>
* There are three ways in which connection request controls are set:
* <ol>
* <li><tt>
* new InitialLdapContext(env, <strong>connCtls</strong>)</tt>
* <li><tt>refException.getReferralContext(env, <strong>connCtls</strong>)</tt>
* <li><tt>ldapContext.reconnect(<strong>connCtls</strong>);</tt>
* </ol>
* where <tt>refException</tt> is an instance of
* <tt>LdapReferralException</tt>, and <tt>ldapContext</tt> is an
* instance of <tt>LdapContext</tt>.
* Specifying <tt>null</tt> or an empty array for <tt>connCtls</tt>
* means no connection request controls.
* <p>
* Like environment properties, connection request controls of a context
* <em>are inherited</em> by contexts that are derived from it.
* Typically, you initialize the connection request controls using the
* <tt>InitialLdapContext</tt> constructor or
* <tt>LdapReferralContext.getReferralContext()</tt>. These connection
* request controls are inherited by contexts that share the same
* connection--that is, contexts derived from the initial or referral
* contexts.
* <p>
* Use <tt>reconnect()</tt> to change the connection request controls of
* a context.
* Invoking <tt>ldapContext.reconnect()</tt> affects only the
* connection used by <tt>ldapContext</tt> and any new contexts instances that are
* derived form <tt>ldapContext</tt>. Contexts that previously shared the
* connection with <tt>ldapContext</tt> remain unchanged. That is, a context's
* connection request controls must be explicitly changed and is not
* affected by changes to another context's connection request
* controls.
* <p>
* A context instance's connection request controls are retrieved using
* the method <tt>getConnectControls()</tt>.
*
* <h4>Service Provider Requirements</h4>
*
* A service provider supports connection and context request controls
* in the following ways. Context request controls must be associated on
* a per context instance basis while connection request controls must be
* associated on a per connection instance basis. The service provider
* must look for the connection request controls in the environment
* property "java.naming.ldap.control.connect" and pass this environment
* property on to context instances that it creates.
*
* <h3>Response Controls</h3>
*
* The method <tt>LdapContext.getResponseControls()</tt> is used to
* retrieve the response controls generated by LDAP operations executed
* as the result of invoking a <tt>Context</tt>/<tt>DirContext</tt>
* operation. The result is all of the responses controls generated
* by the underlying LDAP operations, including any implicit reconnection.
* To get only the reconnection response controls,
* use <tt>reconnect()</tt> followed by <tt>getResponseControls()</tt>.
*
* <h3>Parameters</h3>
*
* A <tt>Control[]</tt> array
* passed as a parameter to any method is owned by the caller.
* The service provider will not modify the array or keep a reference to it,
* although it may keep references to the individual <tt>Control</tt> objects
* in the array.
* A <tt>Control[]</tt> array returned by any method is immutable, and may
* not subsequently be modified by either the caller or the service provider.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see InitialLdapContext
* @see LdapReferralException#getReferralContext(java.util.Hashtable,javax.naming.ldap.Control[])
* @since 1.3
*/
public interface LdapContext extends DirContext {
/**
* Performs an extended operation.
*
* This method is used to support LDAPv3 extended operations.
* @param request The non-null request to be performed.
* @return The possibly null response of the operation. null means
* the operation did not generate any response.
* @throws NamingException If an error occurred while performing the
* extended operation.
*/
public ExtendedResponse extendedOperation(ExtendedRequest request)
throws NamingException;
/**
* Creates a new instance of this context initialized using request controls.
*
* This method is a convenience method for creating a new instance
* of this context for the purposes of multithreaded access.
* For example, if multiple threads want to use different context
* request controls,
* each thread may use this method to get its own copy of this context
* and set/get context request controls without having to synchronize with other
* threads.
*<p>
* The new context has the same environment properties and connection
* request controls as this context. See the class description for details.
* Implementations might also allow this context and the new context
* to share the same network connection or other resources if doing
* so does not impede the independence of either context.
*
* @param requestControls The possibly null request controls
* to use for the new context.
* If null, the context is initialized with no request controls.
*
* @return A non-null <tt>LdapContext</tt> instance.
* @exception NamingException If an error occurred while creating
* the new instance.
* @see InitialLdapContext
*/
public LdapContext newInstance(Control[] requestControls)
throws NamingException;
/**
* Reconnects to the LDAP server using the supplied controls and
* this context's environment.
*<p>
* This method is a way to explicitly initiate an LDAP "bind" operation.
* For example, you can use this method to set request controls for
* the LDAP "bind" operation, or to explicitly connect to the server
* to get response controls returned by the LDAP "bind" operation.
*<p>
* This method sets this context's <tt>connCtls</tt>
* to be its new connection request controls. This context's
* context request controls are not affected.
* After this method has been invoked, any subsequent
* implicit reconnections will be done using <tt>connCtls</tt>.
* <tt>connCtls</tt> are also used as
* connection request controls for new context instances derived from this
* context.
* These connection request controls are not
* affected by <tt>setRequestControls()</tt>.
*<p>
* Service provider implementors should read the "Service Provider" section
* in the class description for implementation details.
* @param connCtls The possibly null controls to use. If null, no
* controls are used.
* @exception NamingException If an error occurred while reconnecting.
* @see #getConnectControls
* @see #newInstance
*/
public void reconnect(Control[] connCtls) throws NamingException;
/**
* Retrieves the connection request controls in effect for this context.
* The controls are owned by the JNDI implementation and are
* immutable. Neither the array nor the controls may be modified by the
* caller.
*
* @return A possibly-null array of controls. null means no connect controls
* have been set for this context.
* @exception NamingException If an error occurred while getting the request
* controls.
*/
public Control[] getConnectControls() throws NamingException;
/**
* Sets the request controls for methods subsequently
* invoked on this context.
* The request controls are owned by the JNDI implementation and are
* immutable. Neither the array nor the controls may be modified by the
* caller.
* <p>
* This removes any previous request controls and adds
* <tt>requestControls</tt>
* for use by subsequent methods invoked on this context.
* This method does not affect this context's connection request controls.
*<p>
* Note that <tt>requestControls</tt> will be in effect until the next
* invocation of <tt>setRequestControls()</tt>. You need to explicitly
* invoke <tt>setRequestControls()</tt> with <tt>null</tt> or an empty
* array to clear the controls if you don't want them to affect the
* context methods any more.
* To check what request controls are in effect for this context, use
* <tt>getRequestControls()</tt>.
* @param requestControls The possibly null controls to use. If null, no
* controls are used.
* @exception NamingException If an error occurred while setting the
* request controls.
* @see #getRequestControls
*/
public void setRequestControls(Control[] requestControls)
throws NamingException;
/**
* Retrieves the request controls in effect for this context.
* The request controls are owned by the JNDI implementation and are
* immutable. Neither the array nor the controls may be modified by the
* caller.
*
* @return A possibly-null array of controls. null means no request controls
* have been set for this context.
* @exception NamingException If an error occurred while getting the request
* controls.
* @see #setRequestControls
*/
public Control[] getRequestControls() throws NamingException;
/**
* Retrieves the response controls produced as a result of the last
* method invoked on this context.
* The response controls are owned by the JNDI implementation and are
* immutable. Neither the array nor the controls may be modified by the
* caller.
*<p>
* These response controls might have been generated by a successful or
* failed operation.
*<p>
* When a context method that may return response controls is invoked,
* response controls from the previous method invocation are cleared.
* <tt>getResponseControls()</tt> returns all of the response controls
* generated by LDAP operations used by the context method in the order
* received from the LDAP server.
* Invoking <tt>getResponseControls()</tt> does not
* clear the response controls. You can call it many times (and get
* back the same controls) until the next context method that may return
* controls is invoked.
*<p>
* @return A possibly null array of controls. If null, the previous
* method invoked on this context did not produce any controls.
* @exception NamingException If an error occurred while getting the response
* controls.
*/
public Control[] getResponseControls() throws NamingException;
/**
* Constant that holds the name of the environment property
* for specifying the list of control factories to use. The value
* of the property should be a colon-separated list of the fully
* qualified class names of factory classes that will create a control
* given another control. See
* <tt>ControlFactory.getControlInstance()</tt> for details.
* This property may be specified in the environment, an applet
* parameter, a system property, or one or more resource files.
*<p>
* The value of this constant is "java.naming.factory.control".
*
* @see ControlFactory
* @see javax.naming.Context#addToEnvironment
* @see javax.naming.Context#removeFromEnvironment
*/
static final String CONTROL_FACTORIES = "java.naming.factory.control";
}

View File

@@ -0,0 +1,787 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.Name;
import javax.naming.InvalidNameException;
import java.util.Enumeration;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
import java.util.Collections;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
/**
* This class represents a distinguished name as specified by
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
* A distinguished name, or DN, is composed of an ordered list of
* components called <em>relative distinguished name</em>s, or RDNs.
* Details of a DN's syntax are described in RFC 2253.
*<p>
* This class resolves a few ambiguities found in RFC 2253
* as follows:
* <ul>
* <li> RFC 2253 leaves the term "whitespace" undefined. The
* ASCII space character 0x20 (" ") is used in its place.
* <li> Whitespace is allowed on either side of ',', ';', '=', and '+'.
* Such whitespace is accepted but not generated by this code,
* and is ignored when comparing names.
* <li> AttributeValue strings containing '=' or non-leading '#'
* characters (unescaped) are accepted.
* </ul>
*<p>
* String names passed to <code>LdapName</code> or returned by it
* use the full Unicode character set. They may also contain
* characters encoded into UTF-8 with each octet represented by a
* three-character substring such as "\\B4".
* They may not, however, contain characters encoded into UTF-8 with
* each octet represented by a single character in the string: the
* meaning would be ambiguous.
*<p>
* <code>LdapName</code> will properly parse all valid names, but
* does not attempt to detect all possible violations when parsing
* invalid names. It is "generous" in accepting invalid names.
* The "validity" of a name is determined ultimately when it
* is supplied to an LDAP server, which may accept or
* reject the name based on factors such as its schema information
* and interoperability considerations.
*<p>
* When names are tested for equality, attribute types, both binary
* and string values, are case-insensitive.
* String values with different but equivalent usage of quoting,
* escaping, or UTF8-hex-encoding are considered equal. The order of
* components in multi-valued RDNs (such as "ou=Sales+cn=Bob") is not
* significant.
* <p>
* The components of a LDAP name, that is, RDNs, are numbered. The
* indexes of a LDAP name with n RDNs range from 0 to n-1.
* This range may be written as [0,n).
* The right most RDN is at index 0, and the left most RDN is at
* index n-1. For example, the distinguished name:
* "CN=Steve Kille, O=Isode Limited, C=GB" is numbered in the following
* sequence ranging from 0 to 2: {C=GB, O=Isode Limited, CN=Steve Kille}. An
* empty LDAP name is represented by an empty RDN list.
*<p>
* Concurrent multithreaded read-only access of an instance of
* <tt>LdapName</tt> need not be synchronized.
*<p>
* Unless otherwise noted, the behavior of passing a null argument
* to a constructor or method in this class will cause a
* NullPointerException to be thrown.
*
* @author Scott Seligman
* @since 1.5
*/
public class LdapName implements Name {
private transient List<Rdn> rdns; // parsed name components
private transient String unparsed; // if non-null, the DN in unparsed form
private static final long serialVersionUID = -1595520034788997356L;
/**
* Constructs an LDAP name from the given distinguished name.
*
* @param name This is a non-null distinguished name formatted
* according to the rules defined in
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
*
* @throws InvalidNameException if a syntax violation is detected.
* @see Rdn#escapeValue(Object value)
*/
public LdapName(String name) throws InvalidNameException {
unparsed = name;
parse();
}
/**
* Constructs an LDAP name given its parsed RDN components.
* <p>
* The indexing of RDNs in the list follows the numbering of
* RDNs described in the class description.
*
* @param rdns The non-null list of <tt>Rdn</tt>s forming this LDAP name.
*/
public LdapName(List<Rdn> rdns) {
// if (rdns instanceof ArrayList<Rdn>) {
// this.rdns = rdns.clone();
// } else if (rdns instanceof List<Rdn>) {
// this.rdns = new ArrayList<Rdn>(rdns);
// } else {
// throw IllegalArgumentException(
// "Invalid entries, list entries must be of type Rdn");
// }
this.rdns = new ArrayList<>(rdns.size());
for (int i = 0; i < rdns.size(); i++) {
Object obj = rdns.get(i);
if (!(obj instanceof Rdn)) {
throw new IllegalArgumentException("Entry:" + obj +
" not a valid type;list entries must be of type Rdn");
}
this.rdns.add((Rdn)obj);
}
}
/*
* Constructs an LDAP name given its parsed components (the elements
* of "rdns" in the range [beg,end)) and, optionally
* (if "name" is not null), the unparsed DN.
*
*/
private LdapName(String name, List<Rdn> rdns, int beg, int end) {
unparsed = name;
// this.rdns = rdns.subList(beg, end);
List<Rdn> sList = rdns.subList(beg, end);
this.rdns = new ArrayList<>(sList);
}
/**
* Retrieves the number of components in this LDAP name.
* @return The non-negative number of components in this LDAP name.
*/
public int size() {
return rdns.size();
}
/**
* Determines whether this LDAP name is empty.
* An empty name is one with zero components.
* @return true if this LDAP name is empty, false otherwise.
*/
public boolean isEmpty() {
return rdns.isEmpty();
}
/**
* Retrieves the components of this name as an enumeration
* of strings. The effect of updates to this name on this enumeration
* is undefined. If the name has zero components, an empty (non-null)
* enumeration is returned.
* The order of the components returned by the enumeration is same as
* the order in which the components are numbered as described in the
* class description.
*
* @return A non-null enumeration of the components of this LDAP name.
* Each element of the enumeration is of class String.
*/
public Enumeration<String> getAll() {
final Iterator<Rdn> iter = rdns.iterator();
return new Enumeration<String>() {
public boolean hasMoreElements() {
return iter.hasNext();
}
public String nextElement() {
return iter.next().toString();
}
};
}
/**
* Retrieves a component of this LDAP name as a string.
* @param posn The 0-based index of the component to retrieve.
* Must be in the range [0,size()).
* @return The non-null component at index posn.
* @exception IndexOutOfBoundsException if posn is outside the
* specified range.
*/
public String get(int posn) {
return rdns.get(posn).toString();
}
/**
* Retrieves an RDN of this LDAP name as an Rdn.
* @param posn The 0-based index of the RDN to retrieve.
* Must be in the range [0,size()).
* @return The non-null RDN at index posn.
* @exception IndexOutOfBoundsException if posn is outside the
* specified range.
*/
public Rdn getRdn(int posn) {
return rdns.get(posn);
}
/**
* Creates a name whose components consist of a prefix of the
* components of this LDAP name.
* Subsequent changes to this name will not affect the name
* that is returned and vice versa.
* @param posn The 0-based index of the component at which to stop.
* Must be in the range [0,size()].
* @return An instance of <tt>LdapName</tt> consisting of the
* components at indexes in the range [0,posn).
* If posn is zero, an empty LDAP name is returned.
* @exception IndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getPrefix(int posn) {
try {
return new LdapName(null, rdns, 0, posn);
} catch (IllegalArgumentException e) {
throw new IndexOutOfBoundsException(
"Posn: " + posn + ", Size: "+ rdns.size());
}
}
/**
* Creates a name whose components consist of a suffix of the
* components in this LDAP name.
* Subsequent changes to this name do not affect the name that is
* returned and vice versa.
*
* @param posn The 0-based index of the component at which to start.
* Must be in the range [0,size()].
* @return An instance of <tt>LdapName</tt> consisting of the
* components at indexes in the range [posn,size()).
* If posn is equal to size(), an empty LDAP name is
* returned.
* @exception IndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name getSuffix(int posn) {
try {
return new LdapName(null, rdns, posn, rdns.size());
} catch (IllegalArgumentException e) {
throw new IndexOutOfBoundsException(
"Posn: " + posn + ", Size: "+ rdns.size());
}
}
/**
* Determines whether this LDAP name starts with a specified LDAP name
* prefix.
* A name <tt>n</tt> is a prefix if it is equal to
* <tt>getPrefix(n.size())</tt>--in other words this LDAP
* name starts with 'n'. If n is null or not a RFC2253 formatted name
* as described in the class description, false is returned.
*
* @param n The LDAP name to check.
* @return true if <tt>n</tt> is a prefix of this LDAP name,
* false otherwise.
* @see #getPrefix(int posn)
*/
public boolean startsWith(Name n) {
if (n == null) {
return false;
}
int len1 = rdns.size();
int len2 = n.size();
return (len1 >= len2 &&
matches(0, len2, n));
}
/**
* Determines whether the specified RDN sequence forms a prefix of this
* LDAP name. Returns true if this LdapName is at least as long as rdns,
* and for every position p in the range [0, rdns.size()) the component
* getRdn(p) matches rdns.get(p). Returns false otherwise. If rdns is
* null, false is returned.
*
* @param rdns The sequence of <tt>Rdn</tt>s to check.
* @return true if <tt>rdns</tt> form a prefix of this LDAP name,
* false otherwise.
*/
public boolean startsWith(List<Rdn> rdns) {
if (rdns == null) {
return false;
}
int len1 = this.rdns.size();
int len2 = rdns.size();
return (len1 >= len2 &&
doesListMatch(0, len2, rdns));
}
/**
* Determines whether this LDAP name ends with a specified
* LDAP name suffix.
* A name <tt>n</tt> is a suffix if it is equal to
* <tt>getSuffix(size()-n.size())</tt>--in other words this LDAP
* name ends with 'n'. If n is null or not a RFC2253 formatted name
* as described in the class description, false is returned.
*
* @param n The LDAP name to check.
* @return true if <tt>n</tt> is a suffix of this name, false otherwise.
* @see #getSuffix(int posn)
*/
public boolean endsWith(Name n) {
if (n == null) {
return false;
}
int len1 = rdns.size();
int len2 = n.size();
return (len1 >= len2 &&
matches(len1 - len2, len1, n));
}
/**
* Determines whether the specified RDN sequence forms a suffix of this
* LDAP name. Returns true if this LdapName is at least as long as rdns,
* and for every position p in the range [size() - rdns.size(), size())
* the component getRdn(p) matches rdns.get(p). Returns false otherwise.
* If rdns is null, false is returned.
*
* @param rdns The sequence of <tt>Rdn</tt>s to check.
* @return true if <tt>rdns</tt> form a suffix of this LDAP name,
* false otherwise.
*/
public boolean endsWith(List<Rdn> rdns) {
if (rdns == null) {
return false;
}
int len1 = this.rdns.size();
int len2 = rdns.size();
return (len1 >= len2 &&
doesListMatch(len1 - len2, len1, rdns));
}
private boolean doesListMatch(int beg, int end, List<Rdn> rdns) {
for (int i = beg; i < end; i++) {
if (!this.rdns.get(i).equals(rdns.get(i - beg))) {
return false;
}
}
return true;
}
/*
* Helper method for startsWith() and endsWith().
* Returns true if components [beg,end) match the components of "n".
* If "n" is not an LdapName, each of its components is parsed as
* the string form of an RDN.
* The following must hold: end - beg == n.size().
*/
private boolean matches(int beg, int end, Name n) {
if (n instanceof LdapName) {
LdapName ln = (LdapName) n;
return doesListMatch(beg, end, ln.rdns);
} else {
for (int i = beg; i < end; i++) {
Rdn rdn;
String rdnString = n.get(i - beg);
try {
rdn = (new Rfc2253Parser(rdnString)).parseRdn();
} catch (InvalidNameException e) {
return false;
}
if (!rdn.equals(rdns.get(i))) {
return false;
}
}
}
return true;
}
/**
* Adds the components of a name -- in order -- to the end of this name.
*
* @param suffix The non-null components to add.
* @return The updated name (not a new instance).
*
* @throws InvalidNameException if <tt>suffix</tt> is not a valid LDAP
* name, or if the addition of the components would violate the
* syntax rules of this LDAP name.
*/
public Name addAll(Name suffix) throws InvalidNameException {
return addAll(size(), suffix);
}
/**
* Adds the RDNs of a name -- in order -- to the end of this name.
*
* @param suffixRdns The non-null suffix <tt>Rdn</tt>s to add.
* @return The updated name (not a new instance).
*/
public Name addAll(List<Rdn> suffixRdns) {
return addAll(size(), suffixRdns);
}
/**
* Adds the components of a name -- in order -- at a specified position
* within this name. Components of this LDAP name at or after the
* index (if any) of the first new component are shifted up
* (away from index 0) to accommodate the new components.
*
* @param suffix The non-null components to add.
* @param posn The index at which to add the new component.
* Must be in the range [0,size()].
*
* @return The updated name (not a new instance).
*
* @throws InvalidNameException if <tt>suffix</tt> is not a valid LDAP
* name, or if the addition of the components would violate the
* syntax rules of this LDAP name.
* @throws IndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name addAll(int posn, Name suffix)
throws InvalidNameException {
unparsed = null; // no longer valid
if (suffix instanceof LdapName) {
LdapName s = (LdapName) suffix;
rdns.addAll(posn, s.rdns);
} else {
Enumeration<String> comps = suffix.getAll();
while (comps.hasMoreElements()) {
rdns.add(posn++,
(new Rfc2253Parser(comps.nextElement()).
parseRdn()));
}
}
return this;
}
/**
* Adds the RDNs of a name -- in order -- at a specified position
* within this name. RDNs of this LDAP name at or after the
* index (if any) of the first new RDN are shifted up (away from index 0) to
* accommodate the new RDNs.
*
* @param suffixRdns The non-null suffix <tt>Rdn</tt>s to add.
* @param posn The index at which to add the suffix RDNs.
* Must be in the range [0,size()].
*
* @return The updated name (not a new instance).
* @throws IndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name addAll(int posn, List<Rdn> suffixRdns) {
unparsed = null;
for (int i = 0; i < suffixRdns.size(); i++) {
Object obj = suffixRdns.get(i);
if (!(obj instanceof Rdn)) {
throw new IllegalArgumentException("Entry:" + obj +
" not a valid type;suffix list entries must be of type Rdn");
}
rdns.add(i + posn, (Rdn)obj);
}
return this;
}
/**
* Adds a single component to the end of this LDAP name.
*
* @param comp The non-null component to add.
* @return The updated LdapName, not a new instance.
* Cannot be null.
* @exception InvalidNameException If adding comp at end of the name
* would violate the name's syntax.
*/
public Name add(String comp) throws InvalidNameException {
return add(size(), comp);
}
/**
* Adds a single RDN to the end of this LDAP name.
*
* @param comp The non-null RDN to add.
*
* @return The updated LdapName, not a new instance.
* Cannot be null.
*/
public Name add(Rdn comp) {
return add(size(), comp);
}
/**
* Adds a single component at a specified position within this
* LDAP name.
* Components of this LDAP name at or after the index (if any) of the new
* component are shifted up by one (away from index 0) to accommodate
* the new component.
*
* @param comp The non-null component to add.
* @param posn The index at which to add the new component.
* Must be in the range [0,size()].
* @return The updated LdapName, not a new instance.
* Cannot be null.
* @exception IndexOutOfBoundsException
* If posn is outside the specified range.
* @exception InvalidNameException If adding comp at the
* specified position would violate the name's syntax.
*/
public Name add(int posn, String comp) throws InvalidNameException {
Rdn rdn = (new Rfc2253Parser(comp)).parseRdn();
rdns.add(posn, rdn);
unparsed = null; // no longer valid
return this;
}
/**
* Adds a single RDN at a specified position within this
* LDAP name.
* RDNs of this LDAP name at or after the index (if any) of the new
* RDN are shifted up by one (away from index 0) to accommodate
* the new RDN.
*
* @param comp The non-null RDN to add.
* @param posn The index at which to add the new RDN.
* Must be in the range [0,size()].
* @return The updated LdapName, not a new instance.
* Cannot be null.
* @exception IndexOutOfBoundsException
* If posn is outside the specified range.
*/
public Name add(int posn, Rdn comp) {
if (comp == null) {
throw new NullPointerException("Cannot set comp to null");
}
rdns.add(posn, comp);
unparsed = null; // no longer valid
return this;
}
/**
* Removes a component from this LDAP name.
* The component of this name at the specified position is removed.
* Components with indexes greater than this position (if any)
* are shifted down (toward index 0) by one.
*
* @param posn The index of the component to remove.
* Must be in the range [0,size()).
* @return The component removed (a String).
*
* @throws IndexOutOfBoundsException
* if posn is outside the specified range.
* @throws InvalidNameException if deleting the component
* would violate the syntax rules of the name.
*/
public Object remove(int posn) throws InvalidNameException {
unparsed = null; // no longer valid
return rdns.remove(posn).toString();
}
/**
* Retrieves the list of relative distinguished names.
* The contents of the list are unmodifiable.
* The indexing of RDNs in the returned list follows the numbering of
* RDNs as described in the class description.
* If the name has zero components, an empty list is returned.
*
* @return The name as a list of RDNs which are instances of
* the class {@link Rdn Rdn}.
*/
public List<Rdn> getRdns() {
return Collections.unmodifiableList(rdns);
}
/**
* Generates a new copy of this name.
* Subsequent changes to the components of this name will not
* affect the new copy, and vice versa.
*
* @return A copy of the this LDAP name.
*/
public Object clone() {
return new LdapName(unparsed, rdns, 0, rdns.size());
}
/**
* Returns a string representation of this LDAP name in a format
* defined by <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
* and described in the class description. If the name has zero
* components an empty string is returned.
*
* @return The string representation of the LdapName.
*/
public String toString() {
if (unparsed != null) {
return unparsed;
}
StringBuilder builder = new StringBuilder();
int size = rdns.size();
if ((size - 1) >= 0) {
builder.append(rdns.get(size - 1));
}
for (int next = size - 2; next >= 0; next--) {
builder.append(',');
builder.append(rdns.get(next));
}
unparsed = builder.toString();
return unparsed;
}
/**
* Determines whether two LDAP names are equal.
* If obj is null or not an LDAP name, false is returned.
* <p>
* Two LDAP names are equal if each RDN in one is equal
* to the corresponding RDN in the other. This implies
* both have the same number of RDNs, and each RDN's
* equals() test against the corresponding RDN in the other
* name returns true. See {@link Rdn#equals(Object obj)}
* for a definition of RDN equality.
*
* @param obj The possibly null object to compare against.
* @return true if obj is equal to this LDAP name,
* false otherwise.
* @see #hashCode
*/
public boolean equals(Object obj) {
// check possible shortcuts
if (obj == this) {
return true;
}
if (!(obj instanceof LdapName)) {
return false;
}
LdapName that = (LdapName) obj;
if (rdns.size() != that.rdns.size()) {
return false;
}
if (unparsed != null && unparsed.equalsIgnoreCase(
that.unparsed)) {
return true;
}
// Compare RDNs one by one for equality
for (int i = 0; i < rdns.size(); i++) {
// Compare a single pair of RDNs.
Rdn rdn1 = rdns.get(i);
Rdn rdn2 = that.rdns.get(i);
if (!rdn1.equals(rdn2)) {
return false;
}
}
return true;
}
/**
* Compares this LdapName with the specified Object for order.
* Returns a negative integer, zero, or a positive integer as this
* Name is less than, equal to, or greater than the given Object.
* <p>
* If obj is null or not an instance of LdapName, ClassCastException
* is thrown.
* <p>
* Ordering of LDAP names follows the lexicographical rules for
* string comparison, with the extension that this applies to all
* the RDNs in the LDAP name. All the RDNs are lined up in their
* specified order and compared lexicographically.
* See {@link Rdn#compareTo(Object obj) Rdn.compareTo(Object obj)}
* for RDN comparison rules.
* <p>
* If this LDAP name is lexicographically lesser than obj,
* a negative number is returned.
* If this LDAP name is lexicographically greater than obj,
* a positive number is returned.
* @param obj The non-null LdapName instance to compare against.
*
* @return A negative integer, zero, or a positive integer as this Name
* is less than, equal to, or greater than the given obj.
* @exception ClassCastException if obj is null or not a LdapName.
*/
public int compareTo(Object obj) {
if (!(obj instanceof LdapName)) {
throw new ClassCastException("The obj is not a LdapName");
}
// check possible shortcuts
if (obj == this) {
return 0;
}
LdapName that = (LdapName) obj;
if (unparsed != null && unparsed.equalsIgnoreCase(
that.unparsed)) {
return 0;
}
// Compare RDNs one by one, lexicographically.
int minSize = Math.min(rdns.size(), that.rdns.size());
for (int i = 0; i < minSize; i++) {
// Compare a single pair of RDNs.
Rdn rdn1 = rdns.get(i);
Rdn rdn2 = that.rdns.get(i);
int diff = rdn1.compareTo(rdn2);
if (diff != 0) {
return diff;
}
}
return (rdns.size() - that.rdns.size()); // longer DN wins
}
/**
* Computes the hash code of this LDAP name.
* The hash code is the sum of the hash codes of individual RDNs
* of this name.
*
* @return An int representing the hash code of this name.
* @see #equals
*/
public int hashCode() {
// Sum up the hash codes of the components.
int hash = 0;
// For each RDN...
for (int i = 0; i < rdns.size(); i++) {
Rdn rdn = rdns.get(i);
hash += rdn.hashCode();
}
return hash;
}
/**
* Serializes only the unparsed DN, for compactness and to avoid
* any implementation dependency.
*
* @serialData The DN string
*/
private void writeObject(ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
s.writeObject(toString());
}
private void readObject(ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
unparsed = (String)s.readObject();
try {
parse();
} catch (InvalidNameException e) {
// shouldn't happen
throw new java.io.StreamCorruptedException(
"Invalid name: " + unparsed);
}
}
private void parse() throws InvalidNameException {
// rdns = (ArrayList<Rdn>) (new RFC2253Parser(unparsed)).getDN();
rdns = new Rfc2253Parser(unparsed).parseDn();
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.ReferralException;
import javax.naming.Context;
import javax.naming.NamingException;
import java.util.Hashtable;
/**
* This abstract class is used to represent an LDAP referral exception.
* It extends the base <tt>ReferralException</tt> by providing a
* <tt>getReferralContext()</tt> method that accepts request controls.
* LdapReferralException is an abstract class. Concrete implementations of it
* determine its synchronization and serialization properties.
*<p>
* A <tt>Control[]</tt> array passed as a parameter to
* the <tt>getReferralContext()</tt> method is owned by the caller.
* The service provider will not modify the array or keep a reference to it,
* although it may keep references to the individual <tt>Control</tt> objects
* in the array.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
* @since 1.3
*/
public abstract class LdapReferralException extends ReferralException {
/**
* Constructs a new instance of LdapReferralException using the
* explanation supplied. All other fields are set to null.
*
* @param explanation Additional detail about this exception. Can be null.
* @see java.lang.Throwable#getMessage
*/
protected LdapReferralException(String explanation) {
super(explanation);
}
/**
* Constructs a new instance of LdapReferralException.
* All fields are set to null.
*/
protected LdapReferralException() {
super();
}
/**
* Retrieves the context at which to continue the method using the
* context's environment and no controls.
* The referral context is created using the environment properties of
* the context that threw the <tt>ReferralException</tt> and no controls.
*<p>
* This method is equivalent to
*<blockquote><pre>
* getReferralContext(ctx.getEnvironment(), null);
*</pre></blockquote>
* where <tt>ctx</tt> is the context that threw the <tt>ReferralException.</tt>
*<p>
* It is overridden in this class for documentation purposes only.
* See <tt>ReferralException</tt> for how to use this method.
*
* @return The non-null context at which to continue the method.
* @exception NamingException If a naming exception was encountered.
* Call either <tt>retryReferral()</tt> or <tt>skipReferral()</tt>
* to continue processing referrals.
*/
public abstract Context getReferralContext() throws NamingException;
/**
* Retrieves the context at which to continue the method using
* environment properties and no controls.
* The referral context is created using <tt>env</tt> as its environment
* properties and no controls.
*<p>
* This method is equivalent to
*<blockquote><pre>
* getReferralContext(env, null);
*</pre></blockquote>
*<p>
* It is overridden in this class for documentation purposes only.
* See <tt>ReferralException</tt> for how to use this method.
*
* @param env The possibly null environment to use when retrieving the
* referral context. If null, no environment properties will be used.
*
* @return The non-null context at which to continue the method.
* @exception NamingException If a naming exception was encountered.
* Call either <tt>retryReferral()</tt> or <tt>skipReferral()</tt>
* to continue processing referrals.
*/
public abstract Context
getReferralContext(Hashtable<?,?> env)
throws NamingException;
/**
* Retrieves the context at which to continue the method using
* request controls and environment properties.
* Regardless of whether a referral is encountered directly during a
* context operation, or indirectly, for example, during a search
* enumeration, the referral exception should provide a context
* at which to continue the operation.
* To continue the operation, the client program should re-invoke
* the method using the same arguments as the original invocation.
*<p>
* <tt>reqCtls</tt> is used when creating the connection to the referred
* server. These controls will be used as the connection request controls for
* the context and context instances
* derived from the context.
* <tt>reqCtls</tt> will also be the context's request controls for
* subsequent context operations. See the <tt>LdapContext</tt> class
* description for details.
*<p>
* This method should be used instead of the other two overloaded forms
* when the caller needs to supply request controls for creating
* the referral context. It might need to do this, for example, when
* it needs to supply special controls relating to authentication.
*<p>
* Service provider implementors should read the "Service Provider" section
* in the <tt>LdapContext</tt> class description for implementation details.
*
* @param reqCtls The possibly null request controls to use for the new context.
* If null or the empty array means use no request controls.
* @param env The possibly null environment properties to use when
* for the new context. If null, the context is initialized with no environment
* properties.
* @return The non-null context at which to continue the method.
* @exception NamingException If a naming exception was encountered.
* Call either <tt>retryReferral()</tt> or <tt>skipReferral()</tt>
* to continue processing referrals.
*/
public abstract Context
getReferralContext(Hashtable<?,?> env,
Control[] reqCtls)
throws NamingException;
private static final long serialVersionUID = -1668992791764950804L;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* Requests that referral and other special LDAP objects be manipulated
* as normal LDAP objects. It enables the requestor to interrogate or
* update such objects.
*<p>
* This class implements the LDAPv3 Request Control for ManageDsaIT
* as defined in
* <a href="http://www.ietf.org/rfc/rfc3296.txt">RFC 3296</a>.
*
* The control has no control value.
*
* @since 1.5
* @author Vincent Ryan
*/
final public class ManageReferralControl extends BasicControl {
/**
* The ManageReferral control's assigned object identifier
* is 2.16.840.1.113730.3.4.2.
*/
public static final String OID = "2.16.840.1.113730.3.4.2";
private static final long serialVersionUID = 3017756160149982566L;
/**
* Constructs a critical ManageReferral control.
*/
public ManageReferralControl() {
super(OID, true, null);
}
/**
* Constructs a ManageReferral control.
*
* @param criticality The control's criticality setting.
*/
public ManageReferralControl(boolean criticality) {
super(OID, criticality, null);
}
}

View File

@@ -0,0 +1,198 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import com.sun.jndi.ldap.Ber;
import com.sun.jndi.ldap.BerEncoder;
/**
* Requests that the results of a search operation be returned by the LDAP
* server in batches of a specified size.
* The requestor controls the rate at which batches are returned by the rate
* at which it invokes search operations.
* <p>
* The following code sample shows how the class may be used:
* <pre>{@code
*
* // Open an LDAP association
* LdapContext ctx = new InitialLdapContext();
*
* // Activate paged results
* int pageSize = 20; // 20 entries per page
* byte[] cookie = null;
* int total;
* ctx.setRequestControls(new Control[]{
* new PagedResultsControl(pageSize, Control.CRITICAL) });
*
* do {
* // Perform the search
* NamingEnumeration results =
* ctx.search("", "(objectclass=*)", new SearchControls());
*
* // Iterate over a batch of search results
* while (results != null && results.hasMore()) {
* // Display an entry
* SearchResult entry = (SearchResult)results.next();
* System.out.println(entry.getName());
* System.out.println(entry.getAttributes());
*
* // Handle the entry's response controls (if any)
* if (entry instanceof HasControls) {
* // ((HasControls)entry).getControls();
* }
* }
* // Examine the paged results control response
* Control[] controls = ctx.getResponseControls();
* if (controls != null) {
* for (int i = 0; i < controls.length; i++) {
* if (controls[i] instanceof PagedResultsResponseControl) {
* PagedResultsResponseControl prrc =
* (PagedResultsResponseControl)controls[i];
* total = prrc.getResultSize();
* cookie = prrc.getCookie();
* } else {
* // Handle other response controls (if any)
* }
* }
* }
*
* // Re-activate paged results
* ctx.setRequestControls(new Control[]{
* new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
* } while (cookie != null);
*
* // Close the LDAP association
* ctx.close();
* ...
*
* } </pre>
* <p>
* This class implements the LDAPv3 Control for paged-results as defined in
* <a href="http://www.ietf.org/rfc/rfc2696.txt">RFC 2696</a>.
*
* The control's value has the following ASN.1 definition:
* <pre>{@code
*
* realSearchControlValue ::= SEQUENCE {
* size INTEGER (0..maxInt),
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
* }
*
* }</pre>
*
* @since 1.5
* @see PagedResultsResponseControl
* @author Vincent Ryan
*/
final public class PagedResultsControl extends BasicControl {
/**
* The paged-results control's assigned object identifier
* is 1.2.840.113556.1.4.319.
*/
public static final String OID = "1.2.840.113556.1.4.319";
private static final byte[] EMPTY_COOKIE = new byte[0];
private static final long serialVersionUID = 6684806685736844298L;
/**
* Constructs a control to set the number of entries to be returned per
* page of results.
*
* @param pageSize The number of entries to return in a page.
* @param criticality If true then the server must honor the control
* and return search results as indicated by
* pageSize or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public PagedResultsControl(int pageSize, boolean criticality)
throws IOException {
super(OID, criticality, null);
value = setEncodedValue(pageSize, EMPTY_COOKIE);
}
/**
* Constructs a control to set the number of entries to be returned per
* page of results. The cookie is provided by the server and may be
* obtained from the paged-results response control.
* <p>
* A sequence of paged-results can be abandoned by setting the pageSize
* to zero and setting the cookie to the last cookie received from the
* server.
*
* @param pageSize The number of entries to return in a page.
* @param cookie A possibly null server-generated cookie.
* @param criticality If true then the server must honor the control
* and return search results as indicated by
* pageSize or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public PagedResultsControl(int pageSize, byte[] cookie,
boolean criticality) throws IOException {
super(OID, criticality, null);
if (cookie == null) {
cookie = EMPTY_COOKIE;
}
value = setEncodedValue(pageSize, cookie);
}
/*
* Encodes the paged-results control's value using ASN.1 BER.
* The result includes the BER tag and length for the control's value but
* does not include the control's object identifier and criticality setting.
*
* @param pageSize The number of entries to return in a page.
* @param cookie A non-null server-generated cookie.
* @return A possibly null byte array representing the ASN.1 BER encoded
* value of the LDAP paged-results control.
* @exception IOException If a BER encoding error occurs.
*/
private byte[] setEncodedValue(int pageSize, byte[] cookie)
throws IOException {
// build the ASN.1 encoding
BerEncoder ber = new BerEncoder(10 + cookie.length);
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
ber.encodeInt(pageSize);
ber.encodeOctetString(cookie, Ber.ASN_OCTET_STR);
ber.endSeq();
return ber.getTrimmedBuf();
}
}

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import com.sun.jndi.ldap.Ber;
import com.sun.jndi.ldap.BerDecoder;
/**
* Indicates the end of a batch of search results.
* Contains an estimate of the total number of entries in the result set
* and an opaque cookie. The cookie must be supplied to the next search
* operation in order to get the next batch of results.
* <p>
* The code sample in {@link PagedResultsControl} shows how this class may
* be used.
* <p>
* This class implements the LDAPv3 Response Control for
* paged-results as defined in
* <a href="http://www.ietf.org/rfc/rfc2696">RFC 2696</a>.
*
* The control's value has the following ASN.1 definition:
* <pre>
*
* realSearchControlValue ::= SEQUENCE {
* size INTEGER (0..maxInt),
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
* }
*
* </pre>
*
* @since 1.5
* @see PagedResultsControl
* @author Vincent Ryan
*/
final public class PagedResultsResponseControl extends BasicControl {
/**
* The paged-results response control's assigned object identifier
* is 1.2.840.113556.1.4.319.
*/
public static final String OID = "1.2.840.113556.1.4.319";
private static final long serialVersionUID = -8819778744844514666L;
/**
* An estimate of the number of entries in the search result.
*
* @serial
*/
private int resultSize;
/**
* A server-generated cookie.
*
* @serial
*/
private byte[] cookie;
/**
* Constructs a paged-results response control.
*
* @param id The control's object identifier string.
* @param criticality The control's criticality.
* @param value The control's ASN.1 BER encoded value.
* It is not cloned - any changes to value
* will affect the contents of the control.
* @exception IOException If an error was encountered while decoding
* the control's value.
*/
public PagedResultsResponseControl(String id, boolean criticality,
byte[] value) throws IOException {
super(id, criticality, value);
// decode value
BerDecoder ber = new BerDecoder(value, 0, value.length);
ber.parseSeq(null);
resultSize = ber.parseInt();
cookie = ber.parseOctetString(Ber.ASN_OCTET_STR, null);
}
/**
* Retrieves (an estimate of) the number of entries in the search result.
*
* @return The number of entries in the search result, or zero if unknown.
*/
public int getResultSize() {
return resultSize;
}
/**
* Retrieves the server-generated cookie. Null is returned when there are
* no more entries for the server to return.
*
* @return A possibly null server-generated cookie. It is not cloned - any
* changes to the cookie will update the control's state and thus
* are not recommended.
*/
public byte[] getCookie() {
if (cookie.length == 0) {
return null;
} else {
return cookie;
}
}
}

View File

@@ -0,0 +1,759 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Collections;
import javax.naming.InvalidNameException;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;
/**
* This class represents a relative distinguished name, or RDN, which is a
* component of a distinguished name as specified by
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
* An example of an RDN is "OU=Sales+CN=J.Smith". In this example,
* the RDN consist of multiple attribute type/value pairs. The
* RDN is parsed as described in the class description for
* {@link javax.naming.ldap.LdapName <tt>LdapName</tt>}.
* <p>
* The Rdn class represents an RDN as attribute type/value mappings,
* which can be viewed using
* {@link javax.naming.directory.Attributes Attributes}.
* In addition, it contains convenience methods that allow easy retrieval
* of type and value when the Rdn consist of a single type/value pair,
* which is how it appears in a typical usage.
* It also contains helper methods that allow escaping of the unformatted
* attribute value and unescaping of the value formatted according to the
* escaping syntax defined in RFC2253. For methods that take or return
* attribute value as an Object, the value is either a String
* (in unescaped form) or a byte array.
* <p>
* <code>Rdn</code> will properly parse all valid RDNs, but
* does not attempt to detect all possible violations when parsing
* invalid RDNs. It is "generous" in accepting invalid RDNs.
* The "validity" of a name is determined ultimately when it
* is supplied to an LDAP server, which may accept or
* reject the name based on factors such as its schema information
* and interoperability considerations.
*
* <p>
* The following code example shows how to construct an Rdn using the
* constructor that takes type and value as arguments:
* <pre>
* Rdn rdn = new Rdn("cn", "Juicy, Fruit");
* System.out.println(rdn.toString());
* </pre>
* The last line will print <tt>cn=Juicy\, Fruit</tt>. The
* {@link #unescapeValue(String) <tt>unescapeValue()</tt>} method can be
* used to unescape the escaped comma resulting in the original
* value <tt>"Juicy, Fruit"</tt>. The {@link #escapeValue(Object)
* <tt>escapeValue()</tt>} method adds the escape back preceding the comma.
* <p>
* This class can be instantiated by a string representation
* of the RDN defined in RFC 2253 as shown in the following code example:
* <pre>
* Rdn rdn = new Rdn("cn=Juicy\\, Fruit");
* System.out.println(rdn.toString());
* </pre>
* The last line will print <tt>cn=Juicy\, Fruit</tt>.
* <p>
* Concurrent multithreaded read-only access of an instance of
* <tt>Rdn</tt> need not be synchronized.
* <p>
* Unless otherwise noted, the behavior of passing a null argument
* to a constructor or method in this class will cause NullPointerException
* to be thrown.
*
* @since 1.5
*/
public class Rdn implements Serializable, Comparable<Object> {
private transient ArrayList<RdnEntry> entries;
// The common case.
private static final int DEFAULT_SIZE = 1;
private static final long serialVersionUID = -5994465067210009656L;
/**
* Constructs an Rdn from the given attribute set. See
* {@link javax.naming.directory.Attributes Attributes}.
* <p>
* The string attribute values are not interpreted as
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
* formatted RDN strings. That is, the values are used
* literally (not parsed) and assumed to be unescaped.
*
* @param attrSet The non-null and non-empty attributes containing
* type/value mappings.
* @throws InvalidNameException If contents of <tt>attrSet</tt> cannot
* be used to construct a valid RDN.
*/
public Rdn(Attributes attrSet) throws InvalidNameException {
if (attrSet.size() == 0) {
throw new InvalidNameException("Attributes cannot be empty");
}
entries = new ArrayList<>(attrSet.size());
NamingEnumeration<? extends Attribute> attrs = attrSet.getAll();
try {
for (int nEntries = 0; attrs.hasMore(); nEntries++) {
RdnEntry entry = new RdnEntry();
Attribute attr = attrs.next();
entry.type = attr.getID();
entry.value = attr.get();
entries.add(nEntries, entry);
}
} catch (NamingException e) {
InvalidNameException e2 = new InvalidNameException(
e.getMessage());
e2.initCause(e);
throw e2;
}
sort(); // arrange entries for comparison
}
/**
* Constructs an Rdn from the given string.
* This constructor takes a string formatted according to the rules
* defined in <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
* and described in the class description for
* {@link javax.naming.ldap.LdapName}.
*
* @param rdnString The non-null and non-empty RFC2253 formatted string.
* @throws InvalidNameException If a syntax error occurs during
* parsing of the rdnString.
*/
public Rdn(String rdnString) throws InvalidNameException {
entries = new ArrayList<>(DEFAULT_SIZE);
(new Rfc2253Parser(rdnString)).parseRdn(this);
}
/**
* Constructs an Rdn from the given <tt>rdn</tt>.
* The contents of the <tt>rdn</tt> are simply copied into the newly
* created Rdn.
* @param rdn The non-null Rdn to be copied.
*/
public Rdn(Rdn rdn) {
entries = new ArrayList<>(rdn.entries.size());
entries.addAll(rdn.entries);
}
/**
* Constructs an Rdn from the given attribute type and
* value.
* The string attribute values are not interpreted as
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
* formatted RDN strings. That is, the values are used
* literally (not parsed) and assumed to be unescaped.
*
* @param type The non-null and non-empty string attribute type.
* @param value The non-null and non-empty attribute value.
* @throws InvalidNameException If type/value cannot be used to
* construct a valid RDN.
* @see #toString()
*/
public Rdn(String type, Object value) throws InvalidNameException {
if (value == null) {
throw new NullPointerException("Cannot set value to null");
}
if (type.equals("") || isEmptyValue(value)) {
throw new InvalidNameException(
"type or value cannot be empty, type:" + type +
" value:" + value);
}
entries = new ArrayList<>(DEFAULT_SIZE);
put(type, value);
}
private boolean isEmptyValue(Object val) {
return ((val instanceof String) && val.equals("")) ||
((val instanceof byte[]) && (((byte[]) val).length == 0));
}
// An empty constructor used by the parser
Rdn() {
entries = new ArrayList<>(DEFAULT_SIZE);
}
/*
* Adds the given attribute type and value to this Rdn.
* The string attribute values are not interpreted as
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
* formatted RDN strings. That is the values are used
* literally (not parsed) and assumed to be unescaped.
*
* @param type The non-null and non-empty string attribute type.
* @param value The non-null and non-empty attribute value.
* @return The updated Rdn, not a new one. Cannot be null.
* @see #toString()
*/
Rdn put(String type, Object value) {
// create new Entry
RdnEntry newEntry = new RdnEntry();
newEntry.type = type;
if (value instanceof byte[]) { // clone the byte array
newEntry.value = ((byte[]) value).clone();
} else {
newEntry.value = value;
}
entries.add(newEntry);
return this;
}
void sort() {
if (entries.size() > 1) {
Collections.sort(entries);
}
}
/**
* Retrieves one of this Rdn's value.
* This is a convenience method for obtaining the value,
* when the RDN contains a single type and value mapping,
* which is the common RDN usage.
* <p>
* For a multi-valued RDN, this method returns value corresponding
* to the type returned by {@link #getType() getType()} method.
*
* @return The non-null attribute value.
*/
public Object getValue() {
return entries.get(0).getValue();
}
/**
* Retrieves one of this Rdn's type.
* This is a convenience method for obtaining the type,
* when the RDN contains a single type and value mapping,
* which is the common RDN usage.
* <p>
* For a multi-valued RDN, the type/value pairs have
* no specific order defined on them. In that case, this method
* returns type of one of the type/value pairs.
* The {@link #getValue() getValue()} method returns the
* value corresponding to the type returned by this method.
*
* @return The non-null attribute type.
*/
public String getType() {
return entries.get(0).getType();
}
/**
* Returns this Rdn as a string represented in a format defined by
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> and described
* in the class description for {@link javax.naming.ldap.LdapName LdapName}.
*
* @return The string representation of the Rdn.
*/
public String toString() {
StringBuilder builder = new StringBuilder();
int size = entries.size();
if (size > 0) {
builder.append(entries.get(0));
}
for (int next = 1; next < size; next++) {
builder.append('+');
builder.append(entries.get(next));
}
return builder.toString();
}
/**
* Compares this Rdn with the specified Object for order.
* Returns a negative integer, zero, or a positive integer as this
* Rdn is less than, equal to, or greater than the given Object.
* <p>
* If obj is null or not an instance of Rdn, ClassCastException
* is thrown.
* <p>
* The attribute type and value pairs of the RDNs are lined up
* against each other and compared lexicographically. The order of
* components in multi-valued Rdns (such as "ou=Sales+cn=Bob") is not
* significant.
*
* @param obj The non-null object to compare against.
* @return A negative integer, zero, or a positive integer as this Rdn
* is less than, equal to, or greater than the given Object.
* @exception ClassCastException if obj is null or not a Rdn.
*/
public int compareTo(Object obj) {
if (!(obj instanceof Rdn)) {
throw new ClassCastException("The obj is not a Rdn");
}
if (obj == this) {
return 0;
}
Rdn that = (Rdn) obj;
int minSize = Math.min(entries.size(), that.entries.size());
for (int i = 0; i < minSize; i++) {
// Compare a single pair of type/value pairs.
int diff = entries.get(i).compareTo(that.entries.get(i));
if (diff != 0) {
return diff;
}
}
return (entries.size() - that.entries.size()); // longer RDN wins
}
/**
* Compares the specified Object with this Rdn for equality.
* Returns true if the given object is also a Rdn and the two Rdns
* represent the same attribute type and value mappings. The order of
* components in multi-valued Rdns (such as "ou=Sales+cn=Bob") is not
* significant.
* <p>
* Type and value equality matching is done as below:
* <ul>
* <li> The types are compared for equality with their case ignored.
* <li> String values with different but equivalent usage of quoting,
* escaping, or UTF8-hex-encoding are considered equal.
* The case of the values is ignored during the comparison.
* </ul>
* <p>
* If obj is null or not an instance of Rdn, false is returned.
* <p>
* @param obj object to be compared for equality with this Rdn.
* @return true if the specified object is equal to this Rdn.
* @see #hashCode()
*/
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Rdn)) {
return false;
}
Rdn that = (Rdn) obj;
if (entries.size() != that.size()) {
return false;
}
for (int i = 0; i < entries.size(); i++) {
if (!entries.get(i).equals(that.entries.get(i))) {
return false;
}
}
return true;
}
/**
* Returns the hash code of this RDN. Two RDNs that are
* equal (according to the equals method) will have the same
* hash code.
*
* @return An int representing the hash code of this Rdn.
* @see #equals
*/
public int hashCode() {
// Sum up the hash codes of the components.
int hash = 0;
// For each type/value pair...
for (int i = 0; i < entries.size(); i++) {
hash += entries.get(i).hashCode();
}
return hash;
}
/**
* Retrieves the {@link javax.naming.directory.Attributes Attributes}
* view of the type/value mappings contained in this Rdn.
*
* @return The non-null attributes containing the type/value
* mappings of this Rdn.
*/
public Attributes toAttributes() {
Attributes attrs = new BasicAttributes(true);
for (int i = 0; i < entries.size(); i++) {
RdnEntry entry = entries.get(i);
Attribute attr = attrs.put(entry.getType(), entry.getValue());
if (attr != null) {
attr.add(entry.getValue());
attrs.put(attr);
}
}
return attrs;
}
private static class RdnEntry implements Comparable<RdnEntry> {
private String type;
private Object value;
// If non-null, a cannonical representation of the value suitable
// for comparison using String.compareTo()
private String comparable = null;
String getType() {
return type;
}
Object getValue() {
return value;
}
public int compareTo(RdnEntry that) {
int diff = type.compareToIgnoreCase(that.type);
if (diff != 0) {
return diff;
}
if (value.equals(that.value)) { // try shortcut
return 0;
}
return getValueComparable().compareTo(
that.getValueComparable());
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof RdnEntry)) {
return false;
}
// Any change here must be reflected in hashCode()
RdnEntry that = (RdnEntry) obj;
return (type.equalsIgnoreCase(that.type)) &&
(getValueComparable().equals(
that.getValueComparable()));
}
public int hashCode() {
return (type.toUpperCase(Locale.ENGLISH).hashCode() +
getValueComparable().hashCode());
}
public String toString() {
return type + "=" + escapeValue(value);
}
private String getValueComparable() {
if (comparable != null) {
return comparable; // return cached result
}
// cache result
if (value instanceof byte[]) {
comparable = escapeBinaryValue((byte[]) value);
} else {
comparable = ((String) value).toUpperCase(Locale.ENGLISH);
}
return comparable;
}
}
/**
* Retrieves the number of attribute type/value pairs in this Rdn.
* @return The non-negative number of type/value pairs in this Rdn.
*/
public int size() {
return entries.size();
}
/**
* Given the value of an attribute, returns a string escaped according
* to the rules specified in
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
* <p>
* For example, if the val is "Sue, Grabbit and Runn", the escaped
* value returned by this method is "Sue\, Grabbit and Runn".
* <p>
* A string value is represented as a String and binary value
* as a byte array.
*
* @param val The non-null object to be escaped.
* @return Escaped string value.
* @throws ClassCastException if val is is not a String or byte array.
*/
public static String escapeValue(Object val) {
return (val instanceof byte[])
? escapeBinaryValue((byte[])val)
: escapeStringValue((String)val);
}
/*
* Given the value of a string-valued attribute, returns a
* string suitable for inclusion in a DN. This is accomplished by
* using backslash (\) to escape the following characters:
* leading and trailing whitespace
* , = + < > # ; " \
*/
private static final String escapees = ",=+<>#;\"\\";
private static String escapeStringValue(String val) {
char[] chars = val.toCharArray();
StringBuilder builder = new StringBuilder(2 * val.length());
// Find leading and trailing whitespace.
int lead; // index of first char that is not leading whitespace
for (lead = 0; lead < chars.length; lead++) {
if (!isWhitespace(chars[lead])) {
break;
}
}
int trail; // index of last char that is not trailing whitespace
for (trail = chars.length - 1; trail >= 0; trail--) {
if (!isWhitespace(chars[trail])) {
break;
}
}
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if ((i < lead) || (i > trail) || (escapees.indexOf(c) >= 0)) {
builder.append('\\');
}
builder.append(c);
}
return builder.toString();
}
/*
* Given the value of a binary attribute, returns a string
* suitable for inclusion in a DN (such as "#CEB1DF80").
* TBD: This method should actually generate the ber encoding
* of the binary value
*/
private static String escapeBinaryValue(byte[] val) {
StringBuilder builder = new StringBuilder(1 + 2 * val.length);
builder.append("#");
for (int i = 0; i < val.length; i++) {
byte b = val[i];
builder.append(Character.forDigit(0xF & (b >>> 4), 16));
builder.append(Character.forDigit(0xF & b, 16));
}
return builder.toString();
}
/**
* Given an attribute value string formated according to the rules
* specified in
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>,
* returns the unformated value. Escapes and quotes are
* stripped away, and hex-encoded UTF-8 is converted to equivalent
* UTF-16 characters. Returns a string value as a String, and a
* binary value as a byte array.
* <p>
* Legal and illegal values are defined in RFC 2253.
* This method is generous in accepting the values and does not
* catch all illegal values.
* Therefore, passing in an illegal value might not necessarily
* trigger an <tt>IllegalArgumentException</tt>.
*
* @param val The non-null string to be unescaped.
* @return Unescaped value.
* @throws IllegalArgumentException When an Illegal value
* is provided.
*/
public static Object unescapeValue(String val) {
char[] chars = val.toCharArray();
int beg = 0;
int end = chars.length;
// Trim off leading and trailing whitespace.
while ((beg < end) && isWhitespace(chars[beg])) {
++beg;
}
while ((beg < end) && isWhitespace(chars[end - 1])) {
--end;
}
// Add back the trailing whitespace with a preceding '\'
// (escaped or unescaped) that was taken off in the above
// loop. Whether or not to retain this whitespace is decided below.
if (end != chars.length &&
(beg < end) &&
chars[end - 1] == '\\') {
end++;
}
if (beg >= end) {
return "";
}
if (chars[beg] == '#') {
// Value is binary (eg: "#CEB1DF80").
return decodeHexPairs(chars, ++beg, end);
}
// Trim off quotes.
if ((chars[beg] == '\"') && (chars[end - 1] == '\"')) {
++beg;
--end;
}
StringBuilder builder = new StringBuilder(end - beg);
int esc = -1; // index of the last escaped character
for (int i = beg; i < end; i++) {
if ((chars[i] == '\\') && (i + 1 < end)) {
if (!Character.isLetterOrDigit(chars[i + 1])) {
++i; // skip backslash
builder.append(chars[i]); // snarf escaped char
esc = i;
} else {
// Convert hex-encoded UTF-8 to 16-bit chars.
byte[] utf8 = getUtf8Octets(chars, i, end);
if (utf8.length > 0) {
try {
builder.append(new String(utf8, "UTF8"));
} catch (java.io.UnsupportedEncodingException e) {
// shouldn't happen
}
i += utf8.length * 3 - 1;
} else { // no utf8 bytes available, invalid DN
// '/' has no meaning, throw exception
throw new IllegalArgumentException(
"Not a valid attribute string value:" +
val + ",improper usage of backslash");
}
}
} else {
builder.append(chars[i]); // snarf unescaped char
}
}
// Get rid of the unescaped trailing whitespace with the
// preceding '\' character that was previously added back.
int len = builder.length();
if (isWhitespace(builder.charAt(len - 1)) && esc != (end - 1)) {
builder.setLength(len - 1);
}
return builder.toString();
}
/*
* Given an array of chars (with starting and ending indexes into it)
* representing bytes encoded as hex-pairs (such as "CEB1DF80"),
* returns a byte array containing the decoded bytes.
*/
private static byte[] decodeHexPairs(char[] chars, int beg, int end) {
byte[] bytes = new byte[(end - beg) / 2];
for (int i = 0; beg + 1 < end; i++) {
int hi = Character.digit(chars[beg], 16);
int lo = Character.digit(chars[beg + 1], 16);
if (hi < 0 || lo < 0) {
break;
}
bytes[i] = (byte)((hi<<4) + lo);
beg += 2;
}
if (beg != end) {
throw new IllegalArgumentException(
"Illegal attribute value: " + new String(chars));
}
return bytes;
}
/*
* Given an array of chars (with starting and ending indexes into it),
* finds the largest prefix consisting of hex-encoded UTF-8 octets,
* and returns a byte array containing the corresponding UTF-8 octets.
*
* Hex-encoded UTF-8 octets look like this:
* \03\B1\DF\80
*/
private static byte[] getUtf8Octets(char[] chars, int beg, int end) {
byte[] utf8 = new byte[(end - beg) / 3]; // allow enough room
int len = 0; // index of first unused byte in utf8
while ((beg + 2 < end) &&
(chars[beg++] == '\\')) {
int hi = Character.digit(chars[beg++], 16);
int lo = Character.digit(chars[beg++], 16);
if (hi < 0 || lo < 0) {
break;
}
utf8[len++] = (byte)((hi<<4) + lo);
}
if (len == utf8.length) {
return utf8;
} else {
byte[] res = new byte[len];
System.arraycopy(utf8, 0, res, 0, len);
return res;
}
}
/*
* Best guess as to what RFC 2253 means by "whitespace".
*/
private static boolean isWhitespace(char c) {
return (c == ' ' || c == '\r');
}
/**
* Serializes only the unparsed RDN, for compactness and to avoid
* any implementation dependency.
*
* @serialData The RDN string
*/
private void writeObject(ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
s.writeObject(toString());
}
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
entries = new ArrayList<>(DEFAULT_SIZE);
String unparsed = (String) s.readObject();
try {
(new Rfc2253Parser(unparsed)).parseRdn(this);
} catch (InvalidNameException e) {
// shouldn't happen
throw new java.io.StreamCorruptedException(
"Invalid name: " + unparsed);
}
}
}

View File

@@ -0,0 +1,253 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.util.List;
import java.util.ArrayList;
import javax.naming.InvalidNameException;
/*
* RFC2253Parser implements a recursive descent parser for a single DN.
*/
final class Rfc2253Parser {
private final String name; // DN being parsed
private final char[] chars; // characters in LDAP name being parsed
private final int len; // length of "chars"
private int cur = 0; // index of first unconsumed char in "chars"
/*
* Given an LDAP DN in string form, returns a parser for it.
*/
Rfc2253Parser(String name) {
this.name = name;
len = name.length();
chars = name.toCharArray();
}
/*
* Parses the DN, returning a List of its RDNs.
*/
// public List<Rdn> getDN() throws InvalidNameException {
List<Rdn> parseDn() throws InvalidNameException {
cur = 0;
// ArrayList<Rdn> rdns =
// new ArrayList<Rdn>(len / 3 + 10); // leave room for growth
ArrayList<Rdn> rdns =
new ArrayList<>(len / 3 + 10); // leave room for growth
if (len == 0) {
return rdns;
}
rdns.add(doParse(new Rdn()));
while (cur < len) {
if (chars[cur] == ',' || chars[cur] == ';') {
++cur;
rdns.add(0, doParse(new Rdn()));
} else {
throw new InvalidNameException("Invalid name: " + name);
}
}
return rdns;
}
/*
* Parses the DN, if it is known to contain a single RDN.
*/
Rdn parseRdn() throws InvalidNameException {
return parseRdn(new Rdn());
}
/*
* Parses the DN, if it is known to contain a single RDN.
*/
Rdn parseRdn(Rdn rdn) throws InvalidNameException {
rdn = doParse(rdn);
if (cur < len) {
throw new InvalidNameException("Invalid RDN: " + name);
}
return rdn;
}
/*
* Parses the next RDN and returns it. Throws an exception if
* none is found. Leading and trailing whitespace is consumed.
*/
private Rdn doParse(Rdn rdn) throws InvalidNameException {
while (cur < len) {
consumeWhitespace();
String attrType = parseAttrType();
consumeWhitespace();
if (cur >= len || chars[cur] != '=') {
throw new InvalidNameException("Invalid name: " + name);
}
++cur; // consume '='
consumeWhitespace();
String value = parseAttrValue();
consumeWhitespace();
rdn.put(attrType, Rdn.unescapeValue(value));
if (cur >= len || chars[cur] != '+') {
break;
}
++cur; // consume '+'
}
rdn.sort();
return rdn;
}
/*
* Returns the attribute type that begins at the next unconsumed
* char. No leading whitespace is expected.
* This routine is more generous than RFC 2253. It accepts
* attribute types composed of any nonempty combination of Unicode
* letters, Unicode digits, '.', '-', and internal space characters.
*/
private String parseAttrType() throws InvalidNameException {
final int beg = cur;
while (cur < len) {
char c = chars[cur];
if (Character.isLetterOrDigit(c) ||
c == '.' ||
c == '-' ||
c == ' ') {
++cur;
} else {
break;
}
}
// Back out any trailing spaces.
while ((cur > beg) && (chars[cur - 1] == ' ')) {
--cur;
}
if (beg == cur) {
throw new InvalidNameException("Invalid name: " + name);
}
return new String(chars, beg, cur - beg);
}
/*
* Returns the attribute value that begins at the next unconsumed
* char. No leading whitespace is expected.
*/
private String parseAttrValue() throws InvalidNameException {
if (cur < len && chars[cur] == '#') {
return parseBinaryAttrValue();
} else if (cur < len && chars[cur] == '"') {
return parseQuotedAttrValue();
} else {
return parseStringAttrValue();
}
}
private String parseBinaryAttrValue() throws InvalidNameException {
final int beg = cur;
++cur; // consume '#'
while ((cur < len) &&
Character.isLetterOrDigit(chars[cur])) {
++cur;
}
return new String(chars, beg, cur - beg);
}
private String parseQuotedAttrValue() throws InvalidNameException {
final int beg = cur;
++cur; // consume '"'
while ((cur < len) && chars[cur] != '"') {
if (chars[cur] == '\\') {
++cur; // consume backslash, then what follows
}
++cur;
}
if (cur >= len) { // no closing quote
throw new InvalidNameException("Invalid name: " + name);
}
++cur; // consume closing quote
return new String(chars, beg, cur - beg);
}
private String parseStringAttrValue() throws InvalidNameException {
final int beg = cur;
int esc = -1; // index of the most recently escaped character
while ((cur < len) && !atTerminator()) {
if (chars[cur] == '\\') {
++cur; // consume backslash, then what follows
esc = cur;
}
++cur;
}
if (cur > len) { // 'twas backslash followed by nothing
throw new InvalidNameException("Invalid name: " + name);
}
// Trim off (unescaped) trailing whitespace.
int end;
for (end = cur; end > beg; end--) {
if (!isWhitespace(chars[end - 1]) || (esc == end - 1)) {
break;
}
}
return new String(chars, beg, end - beg);
}
private void consumeWhitespace() {
while ((cur < len) && isWhitespace(chars[cur])) {
++cur;
}
}
/*
* Returns true if next unconsumed character is one that terminates
* a string attribute value.
*/
private boolean atTerminator() {
return (cur < len &&
(chars[cur] == ',' ||
chars[cur] == ';' ||
chars[cur] == '+'));
}
/*
* Best guess as to what RFC 2253 means by "whitespace".
*/
private static boolean isWhitespace(char c) {
return (c == ' ' || c == '\r');
}
}

View File

@@ -0,0 +1,222 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import com.sun.jndi.ldap.Ber;
import com.sun.jndi.ldap.BerEncoder;
/**
* Requests that the results of a search operation be sorted by the LDAP server
* before being returned.
* The sort criteria are specified using an ordered list of one or more sort
* keys, with associated sort parameters.
* Search results are sorted at the LDAP server according to the parameters
* supplied in the sort control and then returned to the requestor. If sorting
* is not supported at the server (and the sort control is marked as critical)
* then the search operation is not performed and an error is returned.
* <p>
* The following code sample shows how the class may be used:
* <pre>{@code
*
* // Open an LDAP association
* LdapContext ctx = new InitialLdapContext();
*
* // Activate sorting
* String sortKey = "cn";
* ctx.setRequestControls(new Control[]{
* new SortControl(sortKey, Control.CRITICAL) });
*
* // Perform a search
* NamingEnumeration results =
* ctx.search("", "(objectclass=*)", new SearchControls());
*
* // Iterate over search results
* while (results != null && results.hasMore()) {
* // Display an entry
* SearchResult entry = (SearchResult)results.next();
* System.out.println(entry.getName());
* System.out.println(entry.getAttributes());
*
* // Handle the entry's response controls (if any)
* if (entry instanceof HasControls) {
* // ((HasControls)entry).getControls();
* }
* }
* // Examine the sort control response
* Control[] controls = ctx.getResponseControls();
* if (controls != null) {
* for (int i = 0; i < controls.length; i++) {
* if (controls[i] instanceof SortResponseControl) {
* SortResponseControl src = (SortResponseControl)controls[i];
* if (! src.isSorted()) {
* throw src.getException();
* }
* } else {
* // Handle other response controls (if any)
* }
* }
* }
*
* // Close the LDAP association
* ctx.close();
* ...
*
* }</pre>
* <p>
* This class implements the LDAPv3 Request Control for server-side sorting
* as defined in
* <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>.
*
* The control's value has the following ASN.1 definition:
* <pre>
*
* SortKeyList ::= SEQUENCE OF SEQUENCE {
* attributeType AttributeDescription,
* orderingRule [0] MatchingRuleId OPTIONAL,
* reverseOrder [1] BOOLEAN DEFAULT FALSE }
*
* </pre>
*
* @since 1.5
* @see SortKey
* @see SortResponseControl
* @author Vincent Ryan
*/
final public class SortControl extends BasicControl {
/**
* The server-side sort control's assigned object identifier
* is 1.2.840.113556.1.4.473.
*/
public static final String OID = "1.2.840.113556.1.4.473";
private static final long serialVersionUID = -1965961680233330744L;
/**
* Constructs a control to sort on a single attribute in ascending order.
* Sorting will be performed using the ordering matching rule defined
* for use with the specified attribute.
*
* @param sortBy An attribute ID to sort by.
* @param criticality If true then the server must honor the control
* and return the search results sorted as
* requested or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public SortControl(String sortBy, boolean criticality) throws IOException {
super(OID, criticality, null);
super.value = setEncodedValue(new SortKey[]{ new SortKey(sortBy) });
}
/**
* Constructs a control to sort on a list of attributes in ascending order.
* Sorting will be performed using the ordering matching rule defined
* for use with each of the specified attributes.
*
* @param sortBy A non-null list of attribute IDs to sort by.
* The list is in order of highest to lowest sort key
* precedence.
* @param criticality If true then the server must honor the control
* and return the search results sorted as
* requested or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public SortControl(String[] sortBy, boolean criticality)
throws IOException {
super(OID, criticality, null);
SortKey[] sortKeys = new SortKey[sortBy.length];
for (int i = 0; i < sortBy.length; i++) {
sortKeys[i] = new SortKey(sortBy[i]);
}
super.value = setEncodedValue(sortKeys);
}
/**
* Constructs a control to sort on a list of sort keys.
* Each sort key specifies the sort order and ordering matching rule to use.
*
* @param sortBy A non-null list of keys to sort by.
* The list is in order of highest to lowest sort key
* precedence.
* @param criticality If true then the server must honor the control
* and return the search results sorted as
* requested or refuse to perform the search.
* If false, then the server need not honor the
* control.
* @exception IOException If an error was encountered while encoding the
* supplied arguments into a control.
*/
public SortControl(SortKey[] sortBy, boolean criticality)
throws IOException {
super(OID, criticality, null);
super.value = setEncodedValue(sortBy);
}
/*
* Encodes the sort control's value using ASN.1 BER.
* The result includes the BER tag and length for the control's value but
* does not include the control's object identifer and criticality setting.
*
* @param sortKeys A non-null list of keys to sort by.
* @return A possibly null byte array representing the ASN.1 BER encoded
* value of the sort control.
* @exception IOException If a BER encoding error occurs.
*/
private byte[] setEncodedValue(SortKey[] sortKeys) throws IOException {
// build the ASN.1 BER encoding
BerEncoder ber = new BerEncoder(30 * sortKeys.length + 10);
String matchingRule;
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
for (int i = 0; i < sortKeys.length; i++) {
ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
ber.encodeString(sortKeys[i].getAttributeID(), true); // v3
if ((matchingRule = sortKeys[i].getMatchingRuleID()) != null) {
ber.encodeString(matchingRule, (Ber.ASN_CONTEXT | 0), true);
}
if (! sortKeys[i].isAscending()) {
ber.encodeBoolean(true, (Ber.ASN_CONTEXT | 1));
}
ber.endSeq();
}
ber.endSeq();
return ber.getTrimmedBuf();
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* A sort key and its associated sort parameters.
* This class implements a sort key which is used by the LDAPv3
* Control for server-side sorting of search results as defined in
* <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>.
*
* @since 1.5
* @see SortControl
* @author Vincent Ryan
*/
public class SortKey {
/*
* The ID of the attribute to sort by.
*/
private String attrID;
/*
* The sort order. Ascending order, by default.
*/
private boolean reverseOrder = false;
/*
* The ID of the matching rule to use for ordering attribute values.
*/
private String matchingRuleID = null;
/**
* Creates the default sort key for an attribute. Entries will be sorted
* according to the specified attribute in ascending order using the
* ordering matching rule defined for use with that attribute.
*
* @param attrID The non-null ID of the attribute to be used as a sort
* key.
*/
public SortKey(String attrID) {
this.attrID = attrID;
}
/**
* Creates a sort key for an attribute. Entries will be sorted according to
* the specified attribute in the specified sort order and using the
* specified matching rule, if supplied.
*
* @param attrID The non-null ID of the attribute to be used as
* a sort key.
* @param ascendingOrder If true then entries are arranged in ascending
* order. Otherwise there are arranged in
* descending order.
* @param matchingRuleID The possibly null ID of the matching rule to
* use to order the attribute values. If not
* specified then the ordering matching rule
* defined for the sort key attribute is used.
*/
public SortKey(String attrID, boolean ascendingOrder,
String matchingRuleID) {
this.attrID = attrID;
reverseOrder = (! ascendingOrder);
this.matchingRuleID = matchingRuleID;
}
/**
* Retrieves the attribute ID of the sort key.
*
* @return The non-null Attribute ID of the sort key.
*/
public String getAttributeID() {
return attrID;
}
/**
* Determines the sort order.
*
* @return true if the sort order is ascending, false if descending.
*/
public boolean isAscending() {
return (! reverseOrder);
}
/**
* Retrieves the matching rule ID used to order the attribute values.
*
* @return The possibly null matching rule ID. If null then the
* ordering matching rule defined for the sort key attribute
* is used.
*/
public String getMatchingRuleID() {
return matchingRuleID;
}
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import javax.naming.*;
import javax.naming.directory.*;
import com.sun.jndi.ldap.Ber;
import com.sun.jndi.ldap.BerDecoder;
import com.sun.jndi.ldap.LdapCtx;
/**
* Indicates whether the requested sort of search results was successful or not.
* When the result code indicates success then the results have been sorted as
* requested. Otherwise the sort was unsuccessful and additional details
* regarding the cause of the error may have been provided by the server.
* <p>
* The code sample in {@link SortControl} shows how this class may be used.
* <p>
* This class implements the LDAPv3 Response Control for server-side sorting
* as defined in
* <a href="http://www.ietf.org/rfc/rfc2891.txt">RFC 2891</a>.
*
* The control's value has the following ASN.1 definition:
* <pre>
*
* SortResult ::= SEQUENCE {
* sortResult ENUMERATED {
* success (0), -- results are sorted
* operationsError (1), -- server internal failure
* timeLimitExceeded (3), -- timelimit reached before
* -- sorting was completed
* strongAuthRequired (8), -- refused to return sorted
* -- results via insecure
* -- protocol
* adminLimitExceeded (11), -- too many matching entries
* -- for the server to sort
* noSuchAttribute (16), -- unrecognized attribute
* -- type in sort key
* inappropriateMatching (18), -- unrecognized or inappro-
* -- priate matching rule in
* -- sort key
* insufficientAccessRights (50), -- refused to return sorted
* -- results to this client
* busy (51), -- too busy to process
* unwillingToPerform (53), -- unable to sort
* other (80)
* },
* attributeType [0] AttributeType OPTIONAL }
*
* </pre>
*
* @since 1.5
* @see SortControl
* @author Vincent Ryan
*/
final public class SortResponseControl extends BasicControl {
/**
* The server-side sort response control's assigned object identifier
* is 1.2.840.113556.1.4.474.
*/
public static final String OID = "1.2.840.113556.1.4.474";
private static final long serialVersionUID = 5142939176006310877L;
/**
* The sort result code.
*
* @serial
*/
private int resultCode = 0;
/**
* The ID of the attribute that caused the sort to fail.
*
* @serial
*/
private String badAttrId = null;
/**
* Constructs a control to indicate the outcome of a sort request.
*
* @param id The control's object identifier string.
* @param criticality The control's criticality.
* @param value The control's ASN.1 BER encoded value.
* It is not cloned - any changes to value
* will affect the contents of the control.
* @exception IOException if an error is encountered
* while decoding the control's value.
*/
public SortResponseControl(String id, boolean criticality, byte[] value)
throws IOException {
super(id, criticality, value);
// decode value
BerDecoder ber = new BerDecoder(value, 0, value.length);
ber.parseSeq(null);
resultCode = ber.parseEnumeration();
if ((ber.bytesLeft() > 0) && (ber.peekByte() == Ber.ASN_CONTEXT)) {
badAttrId = ber.parseStringWithTag(Ber.ASN_CONTEXT, true, null);
}
}
/**
* Determines if the search results have been successfully sorted.
* If an error occurred during sorting a NamingException is thrown.
*
* @return true if the search results have been sorted.
*/
public boolean isSorted() {
return (resultCode == 0); // a result code of zero indicates success
}
/**
* Retrieves the LDAP result code of the sort operation.
*
* @return The result code. A zero value indicates success.
*/
public int getResultCode() {
return resultCode;
}
/**
* Retrieves the ID of the attribute that caused the sort to fail.
* Returns null if no ID was returned by the server.
*
* @return The possibly null ID of the bad attribute.
*/
public String getAttributeID() {
return badAttrId;
}
/**
* Retrieves the NamingException appropriate for the result code.
*
* @return A NamingException or null if the result code indicates
* success.
*/
public NamingException getException() {
return LdapCtx.mapErrorCode(resultCode, null);
}
}

View File

@@ -0,0 +1,249 @@
/*
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.util.Iterator;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.naming.ConfigurationException;
import javax.naming.NamingException;
import com.sun.naming.internal.VersionHelper;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
/**
* This class implements the LDAPv3 Extended Request for StartTLS as
* defined in
* <a href="http://www.ietf.org/rfc/rfc2830.txt">Lightweight Directory
* Access Protocol (v3): Extension for Transport Layer Security</a>
*
* The object identifier for StartTLS is 1.3.6.1.4.1.1466.20037
* and no extended request value is defined.
*<p>
* <tt>StartTlsRequest</tt>/<tt>StartTlsResponse</tt> are used to establish
* a TLS connection over the existing LDAP connection associated with
* the JNDI context on which <tt>extendedOperation()</tt> is invoked.
* Typically, a JNDI program uses these classes as follows.
* <blockquote><pre>
* import javax.naming.ldap.*;
*
* // Open an LDAP association
* LdapContext ctx = new InitialLdapContext();
*
* // Perform a StartTLS extended operation
* StartTlsResponse tls =
* (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
*
* // Open a TLS connection (over the existing LDAP association) and get details
* // of the negotiated TLS session: cipher suite, peer certificate, etc.
* SSLSession session = tls.negotiate();
*
* // ... use ctx to perform protected LDAP operations
*
* // Close the TLS connection (revert back to the underlying LDAP association)
* tls.close();
*
* // ... use ctx to perform unprotected LDAP operations
*
* // Close the LDAP association
* ctx.close;
* </pre></blockquote>
*
* @since 1.4
* @see StartTlsResponse
* @author Vincent Ryan
*/
public class StartTlsRequest implements ExtendedRequest {
// Constant
/**
* The StartTLS extended request's assigned object identifier
* is 1.3.6.1.4.1.1466.20037.
*/
public static final String OID = "1.3.6.1.4.1.1466.20037";
// Constructors
/**
* Constructs a StartTLS extended request.
*/
public StartTlsRequest() {
}
// ExtendedRequest methods
/**
* Retrieves the StartTLS request's object identifier string.
*
* @return The object identifier string, "1.3.6.1.4.1.1466.20037".
*/
public String getID() {
return OID;
}
/**
* Retrieves the StartTLS request's ASN.1 BER encoded value.
* Since the request has no defined value, null is always
* returned.
*
* @return The null value.
*/
public byte[] getEncodedValue() {
return null;
}
/**
* Creates an extended response object that corresponds to the
* LDAP StartTLS extended request.
* <p>
* The result must be a concrete subclass of StartTlsResponse
* and must have a public zero-argument constructor.
* <p>
* This method locates the implementation class by locating
* configuration files that have the name:
* <blockquote><tt>
* META-INF/services/javax.naming.ldap.StartTlsResponse
* </tt></blockquote>
* The configuration files and their corresponding implementation classes must
* be accessible to the calling thread's context class loader.
* <p>
* Each configuration file should contain a list of fully-qualified class
* names, one per line. Space and tab characters surrounding each name, as
* well as blank lines, are ignored. The comment character is <tt>'#'</tt>
* (<tt>0x23</tt>); on each line all characters following the first comment
* character are ignored. The file must be encoded in UTF-8.
* <p>
* This method will return an instance of the first implementation
* class that it is able to load and instantiate successfully from
* the list of class names collected from the configuration files.
* This method uses the calling thread's context classloader to find the
* configuration files and to load the implementation class.
* <p>
* If no class can be found in this way, this method will use
* an implementation-specific way to locate an implementation.
* If none is found, a NamingException is thrown.
*
* @param id The object identifier of the extended response.
* Its value must be "1.3.6.1.4.1.1466.20037" or null.
* Both values are equivalent.
* @param berValue The possibly null ASN.1 BER encoded value of the
* extended response. This is the raw BER bytes
* including the tag and length of the response value.
* It does not include the response OID.
* Its value is ignored because a Start TLS response
* is not expected to contain any response value.
* @param offset The starting position in berValue of the bytes to use.
* Its value is ignored because a Start TLS response
* is not expected to contain any response value.
* @param length The number of bytes in berValue to use.
* Its value is ignored because a Start TLS response
* is not expected to contain any response value.
* @return The StartTLS extended response object.
* @exception NamingException If a naming exception was encountered
* while creating the StartTLS extended response object.
*/
public ExtendedResponse createExtendedResponse(String id, byte[] berValue,
int offset, int length) throws NamingException {
// Confirm that the object identifier is correct
if ((id != null) && (!id.equals(OID))) {
throw new ConfigurationException(
"Start TLS received the following response instead of " +
OID + ": " + id);
}
StartTlsResponse resp = null;
ServiceLoader<StartTlsResponse> sl = ServiceLoader.load(
StartTlsResponse.class, getContextClassLoader());
Iterator<StartTlsResponse> iter = sl.iterator();
while (resp == null && privilegedHasNext(iter)) {
resp = iter.next();
}
if (resp != null) {
return resp;
}
try {
VersionHelper helper = VersionHelper.getVersionHelper();
Class<?> clas = helper.loadClass(
"com.sun.jndi.ldap.ext.StartTlsResponseImpl");
resp = (StartTlsResponse) clas.newInstance();
} catch (IllegalAccessException e) {
throw wrapException(e);
} catch (InstantiationException e) {
throw wrapException(e);
} catch (ClassNotFoundException e) {
throw wrapException(e);
}
return resp;
}
/*
* Wrap an exception, thrown while attempting to load the StartTlsResponse
* class, in a configuration exception.
*/
private ConfigurationException wrapException(Exception e) {
ConfigurationException ce = new ConfigurationException(
"Cannot load implementation of javax.naming.ldap.StartTlsResponse");
ce.setRootCause(e);
return ce;
}
/*
* Acquire the class loader associated with this thread.
*/
private final ClassLoader getContextClassLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
}
);
}
private final static boolean privilegedHasNext(final Iterator<StartTlsResponse> iter) {
Boolean answer = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
public Boolean run() {
return Boolean.valueOf(iter.hasNext());
}
});
return answer.booleanValue();
}
private static final long serialVersionUID = 4441679576360753397L;
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import java.io.IOException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.HostnameVerifier;
/**
* This class implements the LDAPv3 Extended Response for StartTLS as
* defined in
* <a href="http://www.ietf.org/rfc/rfc2830.txt">Lightweight Directory
* Access Protocol (v3): Extension for Transport Layer Security</a>
*
* The object identifier for StartTLS is 1.3.6.1.4.1.1466.20037
* and no extended response value is defined.
*
*<p>
* The Start TLS extended request and response are used to establish
* a TLS connection over the existing LDAP connection associated with
* the JNDI context on which <tt>extendedOperation()</tt> is invoked.
* Typically, a JNDI program uses the StartTLS extended request and response
* classes as follows.
* <blockquote><pre>
* import javax.naming.ldap.*;
*
* // Open an LDAP association
* LdapContext ctx = new InitialLdapContext();
*
* // Perform a StartTLS extended operation
* StartTlsResponse tls =
* (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
*
* // Open a TLS connection (over the existing LDAP association) and get details
* // of the negotiated TLS session: cipher suite, peer certificate, ...
* SSLSession session = tls.negotiate();
*
* // ... use ctx to perform protected LDAP operations
*
* // Close the TLS connection (revert back to the underlying LDAP association)
* tls.close();
*
* // ... use ctx to perform unprotected LDAP operations
*
* // Close the LDAP association
* ctx.close;
* </pre></blockquote>
*
* @since 1.4
* @see StartTlsRequest
* @author Vincent Ryan
*/
public abstract class StartTlsResponse implements ExtendedResponse {
// Constant
/**
* The StartTLS extended response's assigned object identifier
* is 1.3.6.1.4.1.1466.20037.
*/
public static final String OID = "1.3.6.1.4.1.1466.20037";
// Called by subclass
/**
* Constructs a StartTLS extended response.
* A concrete subclass must have a public no-arg constructor.
*/
protected StartTlsResponse() {
}
// ExtendedResponse methods
/**
* Retrieves the StartTLS response's object identifier string.
*
* @return The object identifier string, "1.3.6.1.4.1.1466.20037".
*/
public String getID() {
return OID;
}
/**
* Retrieves the StartTLS response's ASN.1 BER encoded value.
* Since the response has no defined value, null is always
* returned.
*
* @return The null value.
*/
public byte[] getEncodedValue() {
return null;
}
// StartTls-specific methods
/**
* Overrides the default list of cipher suites enabled for use on the
* TLS connection. The cipher suites must have already been listed by
* <tt>SSLSocketFactory.getSupportedCipherSuites()</tt> as being supported.
* Even if a suite has been enabled, it still might not be used because
* the peer does not support it, or because the requisite certificates
* (and private keys) are not available.
*
* @param suites The non-null list of names of all the cipher suites to
* enable.
* @see #negotiate
*/
public abstract void setEnabledCipherSuites(String[] suites);
/**
* Sets the hostname verifier used by <tt>negotiate()</tt>
* after the TLS handshake has completed and the default hostname
* verification has failed.
* <tt>setHostnameVerifier()</tt> must be called before
* <tt>negotiate()</tt> is invoked for it to have effect.
* If called after
* <tt>negotiate()</tt>, this method does not do anything.
*
* @param verifier The non-null hostname verifier callback.
* @see #negotiate
*/
public abstract void setHostnameVerifier(HostnameVerifier verifier);
/**
* Negotiates a TLS session using the default SSL socket factory.
* <p>
* This method is equivalent to <tt>negotiate(null)</tt>.
*
* @return The negotiated SSL session
* @throws IOException If an IO error was encountered while establishing
* the TLS session.
* @see #setEnabledCipherSuites
* @see #setHostnameVerifier
*/
public abstract SSLSession negotiate() throws IOException;
/**
* Negotiates a TLS session using an SSL socket factory.
* <p>
* Creates an SSL socket using the supplied SSL socket factory and
* attaches it to the existing connection. Performs the TLS handshake
* and returns the negotiated session information.
* <p>
* If cipher suites have been set via <tt>setEnabledCipherSuites</tt>
* then they are enabled before the TLS handshake begins.
* <p>
* Hostname verification is performed after the TLS handshake completes.
* The default hostname verification performs a match of the server's
* hostname against the hostname information found in the server's certificate.
* If this verification fails and no callback has been set via
* <tt>setHostnameVerifier</tt> then the negotiation fails.
* If this verification fails and a callback has been set via
* <tt>setHostnameVerifier</tt>, then the callback is used to determine whether
* the negotiation succeeds.
* <p>
* If an error occurs then the SSL socket is closed and an IOException
* is thrown. The underlying connection remains intact.
*
* @param factory The possibly null SSL socket factory to use.
* If null, the default SSL socket factory is used.
* @return The negotiated SSL session
* @throws IOException If an IO error was encountered while establishing
* the TLS session.
* @see #setEnabledCipherSuites
* @see #setHostnameVerifier
*/
public abstract SSLSession negotiate(SSLSocketFactory factory)
throws IOException;
/**
* Closes the TLS connection gracefully and reverts back to the underlying
* connection.
*
* @throws IOException If an IO error was encountered while closing the
* TLS connection
*/
public abstract void close() throws IOException;
private static final long serialVersionUID = 8372842182579276418L;
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.NamingException;
/**
* This interface represents an unsolicited notification as defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
* An unsolicited notification is sent by the LDAP server to the LDAP
* client without any provocation from the client.
* Its format is that of an extended response (<tt>ExtendedResponse</tt>).
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see ExtendedResponse
* @see UnsolicitedNotificationEvent
* @see UnsolicitedNotificationListener
* @since 1.3
*/
public interface UnsolicitedNotification extends ExtendedResponse, HasControls {
/**
* Retrieves the referral(s) sent by the server.
*
* @return A possibly null array of referrals, each of which is represented
* by a URL string. If null, no referral was sent by the server.
*/
public String[] getReferrals();
/**
* Retrieves the exception as constructed using information
* sent by the server.
* @return A possibly null exception as constructed using information
* sent by the server. If null, a "success" status was indicated by
* the server.
*/
public NamingException getException();
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
/**
* This class represents an event fired in response to an unsolicited
* notification sent by the LDAP server.
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see UnsolicitedNotification
* @see UnsolicitedNotificationListener
* @see javax.naming.event.EventContext#addNamingListener
* @see javax.naming.event.EventDirContext#addNamingListener
* @see javax.naming.event.EventContext#removeNamingListener
* @since 1.3
*/
public class UnsolicitedNotificationEvent extends java.util.EventObject {
/**
* The notification that caused this event to be fired.
* @serial
*/
private UnsolicitedNotification notice;
/**
* Constructs a new instance of <tt>UnsolicitedNotificationEvent</tt>.
*
* @param src The non-null source that fired the event.
* @param notice The non-null unsolicited notification.
*/
public UnsolicitedNotificationEvent(Object src,
UnsolicitedNotification notice) {
super(src);
this.notice = notice;
}
/**
* Returns the unsolicited notification.
* @return The non-null unsolicited notification that caused this
* event to be fired.
*/
public UnsolicitedNotification getNotification() {
return notice;
}
/**
* Invokes the <tt>notificationReceived()</tt> method on
* a listener using this event.
* @param listener The non-null listener on which to invoke
* <tt>notificationReceived</tt>.
*/
public void dispatch(UnsolicitedNotificationListener listener) {
listener.notificationReceived(this);
}
private static final long serialVersionUID = -2382603380799883705L;
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.ldap;
import javax.naming.event.NamingListener;
/**
* This interface is for handling <tt>UnsolicitedNotificationEvent</tt>.
* "Unsolicited notification" is defined in
* <A HREF="http://www.ietf.org/rfc/rfc2251.txt">RFC 2251</A>.
* It allows the server to send unsolicited notifications to the client.
* A <tt>UnsolicitedNotificationListener</tt> must:
*<ol>
* <li>Implement this interface and its method
* <li>Implement <tt>NamingListener.namingExceptionThrown()</tt> so
* that it will be notified of exceptions thrown while attempting to
* collect unsolicited notification events.
* <li>Register with the context using one of the <tt>addNamingListener()</tt>
* methods from <tt>EventContext</tt> or <tt>EventDirContext</tt>.
* Only the <tt>NamingListener</tt> argument of these methods are applicable;
* the rest are ignored for a <tt>UnsolicitedNotificationListener</tt>.
* (These arguments might be applicable to the listener if it implements
* other listener interfaces).
*</ol>
*
* @author Rosanna Lee
* @author Scott Seligman
* @author Vincent Ryan
*
* @see UnsolicitedNotificationEvent
* @see UnsolicitedNotification
* @see javax.naming.event.EventContext#addNamingListener
* @see javax.naming.event.EventDirContext#addNamingListener
* @see javax.naming.event.EventContext#removeNamingListener
* @since 1.3
*/
public interface UnsolicitedNotificationListener extends NamingListener {
/**
* Called when an unsolicited notification has been received.
*
* @param evt The non-null UnsolicitedNotificationEvent
*/
void notificationReceived(UnsolicitedNotificationEvent evt);
}

View File

@@ -0,0 +1,246 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.*;
/**
* This class is for dealing with federations/continuations.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
class ContinuationContext implements Context, Resolver {
protected CannotProceedException cpe;
protected Hashtable<?,?> env;
protected Context contCtx = null;
protected ContinuationContext(CannotProceedException cpe,
Hashtable<?,?> env) {
this.cpe = cpe;
this.env = env;
}
protected Context getTargetContext() throws NamingException {
if (contCtx == null) {
if (cpe.getResolvedObj() == null)
throw (NamingException)cpe.fillInStackTrace();
contCtx = NamingManager.getContext(cpe.getResolvedObj(),
cpe.getAltName(),
cpe.getAltNameCtx(),
env);
if (contCtx == null)
throw (NamingException)cpe.fillInStackTrace();
}
return contCtx;
}
public Object lookup(Name name) throws NamingException {
Context ctx = getTargetContext();
return ctx.lookup(name);
}
public Object lookup(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.lookup(name);
}
public void bind(Name name, Object newObj) throws NamingException {
Context ctx = getTargetContext();
ctx.bind(name, newObj);
}
public void bind(String name, Object newObj) throws NamingException {
Context ctx = getTargetContext();
ctx.bind(name, newObj);
}
public void rebind(Name name, Object newObj) throws NamingException {
Context ctx = getTargetContext();
ctx.rebind(name, newObj);
}
public void rebind(String name, Object newObj) throws NamingException {
Context ctx = getTargetContext();
ctx.rebind(name, newObj);
}
public void unbind(Name name) throws NamingException {
Context ctx = getTargetContext();
ctx.unbind(name);
}
public void unbind(String name) throws NamingException {
Context ctx = getTargetContext();
ctx.unbind(name);
}
public void rename(Name name, Name newName) throws NamingException {
Context ctx = getTargetContext();
ctx.rename(name, newName);
}
public void rename(String name, String newName) throws NamingException {
Context ctx = getTargetContext();
ctx.rename(name, newName);
}
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
Context ctx = getTargetContext();
return ctx.list(name);
}
public NamingEnumeration<NameClassPair> list(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.list(name);
}
public NamingEnumeration<Binding> listBindings(Name name)
throws NamingException
{
Context ctx = getTargetContext();
return ctx.listBindings(name);
}
public NamingEnumeration<Binding> listBindings(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.listBindings(name);
}
public void destroySubcontext(Name name) throws NamingException {
Context ctx = getTargetContext();
ctx.destroySubcontext(name);
}
public void destroySubcontext(String name) throws NamingException {
Context ctx = getTargetContext();
ctx.destroySubcontext(name);
}
public Context createSubcontext(Name name) throws NamingException {
Context ctx = getTargetContext();
return ctx.createSubcontext(name);
}
public Context createSubcontext(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.createSubcontext(name);
}
public Object lookupLink(Name name) throws NamingException {
Context ctx = getTargetContext();
return ctx.lookupLink(name);
}
public Object lookupLink(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.lookupLink(name);
}
public NameParser getNameParser(Name name) throws NamingException {
Context ctx = getTargetContext();
return ctx.getNameParser(name);
}
public NameParser getNameParser(String name) throws NamingException {
Context ctx = getTargetContext();
return ctx.getNameParser(name);
}
public Name composeName(Name name, Name prefix)
throws NamingException
{
Context ctx = getTargetContext();
return ctx.composeName(name, prefix);
}
public String composeName(String name, String prefix)
throws NamingException {
Context ctx = getTargetContext();
return ctx.composeName(name, prefix);
}
public Object addToEnvironment(String propName, Object value)
throws NamingException {
Context ctx = getTargetContext();
return ctx.addToEnvironment(propName, value);
}
public Object removeFromEnvironment(String propName)
throws NamingException {
Context ctx = getTargetContext();
return ctx.removeFromEnvironment(propName);
}
public Hashtable<?,?> getEnvironment() throws NamingException {
Context ctx = getTargetContext();
return ctx.getEnvironment();
}
public String getNameInNamespace() throws NamingException {
Context ctx = getTargetContext();
return ctx.getNameInNamespace();
}
public ResolveResult
resolveToClass(Name name, Class<? extends Context> contextType)
throws NamingException
{
if (cpe.getResolvedObj() == null)
throw (NamingException)cpe.fillInStackTrace();
Resolver res = NamingManager.getResolver(cpe.getResolvedObj(),
cpe.getAltName(),
cpe.getAltNameCtx(),
env);
if (res == null)
throw (NamingException)cpe.fillInStackTrace();
return res.resolveToClass(name, contextType);
}
public ResolveResult
resolveToClass(String name, Class<? extends Context> contextType)
throws NamingException
{
if (cpe.getResolvedObj() == null)
throw (NamingException)cpe.fillInStackTrace();
Resolver res = NamingManager.getResolver(cpe.getResolvedObj(),
cpe.getAltName(),
cpe.getAltNameCtx(),
env);
if (res == null)
throw (NamingException)cpe.fillInStackTrace();
return res.resolveToClass(name, contextType);
}
public void close() throws NamingException {
cpe = null;
env = null;
if (contCtx != null) {
contCtx.close();
contCtx = null;
}
}
}

View File

@@ -0,0 +1,334 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.CompositeName;
import javax.naming.NamingException;
import javax.naming.CannotProceedException;
import javax.naming.OperationNotSupportedException;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.directory.ModificationItem;
/**
* This class is the continuation context for invoking DirContext methods.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
class ContinuationDirContext extends ContinuationContext implements DirContext {
ContinuationDirContext(CannotProceedException cpe, Hashtable<?,?> env) {
super(cpe, env);
}
protected DirContextNamePair getTargetContext(Name name)
throws NamingException {
if (cpe.getResolvedObj() == null)
throw (NamingException)cpe.fillInStackTrace();
Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
cpe.getAltName(),
cpe.getAltNameCtx(),
env);
if (ctx == null)
throw (NamingException)cpe.fillInStackTrace();
if (ctx instanceof DirContext)
return new DirContextNamePair((DirContext)ctx, name);
if (ctx instanceof Resolver) {
Resolver res = (Resolver)ctx;
ResolveResult rr = res.resolveToClass(name, DirContext.class);
// Reached a DirContext; return result.
DirContext dctx = (DirContext)rr.getResolvedObj();
return (new DirContextNamePair(dctx, rr.getRemainingName()));
}
// Resolve all the way using lookup(). This may allow the operation
// to succeed if it doesn't require the penultimate context.
Object ultimate = ctx.lookup(name);
if (ultimate instanceof DirContext) {
return (new DirContextNamePair((DirContext)ultimate,
new CompositeName()));
}
throw (NamingException)cpe.fillInStackTrace();
}
protected DirContextStringPair getTargetContext(String name)
throws NamingException {
if (cpe.getResolvedObj() == null)
throw (NamingException)cpe.fillInStackTrace();
Context ctx = NamingManager.getContext(cpe.getResolvedObj(),
cpe.getAltName(),
cpe.getAltNameCtx(),
env);
if (ctx instanceof DirContext)
return new DirContextStringPair((DirContext)ctx, name);
if (ctx instanceof Resolver) {
Resolver res = (Resolver)ctx;
ResolveResult rr = res.resolveToClass(name, DirContext.class);
// Reached a DirContext; return result.
DirContext dctx = (DirContext)rr.getResolvedObj();
Name tmp = rr.getRemainingName();
String remains = (tmp != null) ? tmp.toString() : "";
return (new DirContextStringPair(dctx, remains));
}
// Resolve all the way using lookup(). This may allow the operation
// to succeed if it doesn't require the penultimate context.
Object ultimate = ctx.lookup(name);
if (ultimate instanceof DirContext) {
return (new DirContextStringPair((DirContext)ultimate, ""));
}
throw (NamingException)cpe.fillInStackTrace();
}
public Attributes getAttributes(String name) throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().getAttributes(res.getString());
}
public Attributes getAttributes(String name, String[] attrIds)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().getAttributes(res.getString(), attrIds);
}
public Attributes getAttributes(Name name) throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().getAttributes(res.getName());
}
public Attributes getAttributes(Name name, String[] attrIds)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().getAttributes(res.getName(), attrIds);
}
public void modifyAttributes(Name name, int mod_op, Attributes attrs)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
res.getDirContext().modifyAttributes(res.getName(), mod_op, attrs);
}
public void modifyAttributes(String name, int mod_op, Attributes attrs)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
res.getDirContext().modifyAttributes(res.getString(), mod_op, attrs);
}
public void modifyAttributes(Name name, ModificationItem[] mods)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
res.getDirContext().modifyAttributes(res.getName(), mods);
}
public void modifyAttributes(String name, ModificationItem[] mods)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
res.getDirContext().modifyAttributes(res.getString(), mods);
}
public void bind(Name name, Object obj, Attributes attrs)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
res.getDirContext().bind(res.getName(), obj, attrs);
}
public void bind(String name, Object obj, Attributes attrs)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
res.getDirContext().bind(res.getString(), obj, attrs);
}
public void rebind(Name name, Object obj, Attributes attrs)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
res.getDirContext().rebind(res.getName(), obj, attrs);
}
public void rebind(String name, Object obj, Attributes attrs)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
res.getDirContext().rebind(res.getString(), obj, attrs);
}
public DirContext createSubcontext(Name name, Attributes attrs)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().createSubcontext(res.getName(), attrs);
}
public DirContext createSubcontext(String name, Attributes attrs)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return
res.getDirContext().createSubcontext(res.getString(), attrs);
}
public NamingEnumeration<SearchResult> search(Name name,
Attributes matchingAttributes,
String[] attributesToReturn)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().search(res.getName(), matchingAttributes,
attributesToReturn);
}
public NamingEnumeration<SearchResult> search(String name,
Attributes matchingAttributes,
String[] attributesToReturn)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().search(res.getString(),
matchingAttributes,
attributesToReturn);
}
public NamingEnumeration<SearchResult> search(Name name,
Attributes matchingAttributes)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().search(res.getName(), matchingAttributes);
}
public NamingEnumeration<SearchResult> search(String name,
Attributes matchingAttributes)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().search(res.getString(),
matchingAttributes);
}
public NamingEnumeration<SearchResult> search(Name name,
String filter,
SearchControls cons)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().search(res.getName(), filter, cons);
}
public NamingEnumeration<SearchResult> search(String name,
String filter,
SearchControls cons)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().search(res.getString(), filter, cons);
}
public NamingEnumeration<SearchResult> search(Name name,
String filterExpr,
Object[] args,
SearchControls cons)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().search(res.getName(), filterExpr, args,
cons);
}
public NamingEnumeration<SearchResult> search(String name,
String filterExpr,
Object[] args,
SearchControls cons)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().search(res.getString(), filterExpr, args,
cons);
}
public DirContext getSchema(String name) throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().getSchema(res.getString());
}
public DirContext getSchema(Name name) throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().getSchema(res.getName());
}
public DirContext getSchemaClassDefinition(String name)
throws NamingException {
DirContextStringPair res = getTargetContext(name);
return res.getDirContext().getSchemaClassDefinition(res.getString());
}
public DirContext getSchemaClassDefinition(Name name)
throws NamingException {
DirContextNamePair res = getTargetContext(name);
return res.getDirContext().getSchemaClassDefinition(res.getName());
}
}
class DirContextNamePair {
DirContext ctx;
Name name;
DirContextNamePair(DirContext ctx, Name name) {
this.ctx = ctx;
this.name = name;
}
DirContext getDirContext() {
return ctx;
}
Name getName() {
return name;
}
}
class DirContextStringPair {
DirContext ctx;
String str;
DirContextStringPair(DirContext ctx, String str) {
this.ctx = ctx;
this.str = str;
}
DirContext getDirContext() {
return ctx;
}
String getString() {
return str;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.*;
import javax.naming.directory.Attributes;
/**
* This interface represents a factory for creating an object given
* an object and attributes about the object.
*<p>
* The JNDI framework allows for object implementations to
* be loaded in dynamically via <em>object factories</em>. See
* <tt>ObjectFactory</tt> for details.
* <p>
* A <tt>DirObjectFactory</tt> extends <tt>ObjectFactory</tt> by allowing
* an <tt>Attributes</tt> instance
* to be supplied to the <tt>getObjectInstance()</tt> method.
* <tt>DirObjectFactory</tt> implementations are intended to be used by <tt>DirContext</tt>
* service providers. The service provider, in addition reading an
* object from the directory, might already have attributes that
* are useful for the object factory to check to see whether the
* factory is supposed to process the object. For instance, an LDAP-style
* service provider might have read the "objectclass" of the object.
* A CORBA object factory might be interested only in LDAP entries
* with "objectclass=corbaObject". By using the attributes supplied by
* the LDAP service provider, the CORBA object factory can quickly
* eliminate objects that it need not worry about, and non-CORBA object
* factories can quickly eliminate CORBA-related LDAP entries.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingManager#getObjectInstance
* @see DirectoryManager#getObjectInstance
* @see ObjectFactory
* @since 1.3
*/
public interface DirObjectFactory extends ObjectFactory {
/**
* Creates an object using the location or reference information, and attributes
* specified.
* <p>
* Special requirements of this object are supplied
* using <code>environment</code>.
* An example of such an environment property is user identity
* information.
*<p>
* <tt>DirectoryManager.getObjectInstance()</tt>
* successively loads in object factories. If it encounters a <tt>DirObjectFactory</tt>,
* it will invoke <tt>DirObjectFactory.getObjectInstance()</tt>;
* otherwise, it invokes
* <tt>ObjectFactory.getObjectInstance()</tt>. It does this until a factory
* produces a non-null answer.
* <p> When an exception
* is thrown by an object factory, the exception is passed on to the caller
* of <tt>DirectoryManager.getObjectInstance()</tt>. The search for other factories
* that may produce a non-null answer is halted.
* An object factory should only throw an exception if it is sure that
* it is the only intended factory and that no other object factories
* should be tried.
* If this factory cannot create an object using the arguments supplied,
* it should return null.
*<p>Since <tt>DirObjectFactory</tt> extends <tt>ObjectFactory</tt>, it
* effectively
* has two <tt>getObjectInstance()</tt> methods, where one differs from the other by
* the attributes argument. Given a factory that implements <tt>DirObjectFactory</tt>,
* <tt>DirectoryManager.getObjectInstance()</tt> will only
* use the method that accepts the attributes argument, while
* <tt>NamingManager.getObjectInstance()</tt> will only use the one that does not accept
* the attributes argument.
*<p>
* See <tt>ObjectFactory</tt> for a description URL context factories and other
* properties of object factories that apply equally to <tt>DirObjectFactory</tt>.
*<p>
* The <tt>name</tt>, <tt>attrs</tt>, and <tt>environment</tt> parameters
* are owned by the caller.
* The implementation will not modify these objects or keep references
* to them, although it may keep references to clones or copies.
*
* @param obj The possibly null object containing location or reference
* information that can be used in creating an object.
* @param name The name of this object relative to <code>nameCtx</code>,
* or null if no name is specified.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified, or null if <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment that is used in
* creating the object.
* @param attrs The possibly null attributes containing some of <tt>obj</tt>'s
* attributes. <tt>attrs</tt> might not necessarily have all of <tt>obj</tt>'s
* attributes. If the object factory requires more attributes, it needs
* to get it, either using <tt>obj</tt>, or <tt>name</tt> and <tt>nameCtx</tt>.
* The factory must not modify attrs.
* @return The object created; null if an object cannot be created.
* @exception Exception If this object factory encountered an exception
* while attempting to create an object, and no other object factories are
* to be tried.
*
* @see DirectoryManager#getObjectInstance
* @see NamingManager#getURLContext
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment,
Attributes attrs)
throws Exception;
}

View File

@@ -0,0 +1,188 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import javax.naming.*;
import javax.naming.directory.Attributes;
import java.util.Hashtable;
/**
* This interface represents a factory for obtaining the state of an
* object and corresponding attributes for binding.
*<p>
* The JNDI framework allows for object implementations to
* be loaded in dynamically via <tt>object factories</tt>.
* <p>
* A <tt>DirStateFactory</tt> extends <tt>StateFactory</tt>
* by allowing an <tt>Attributes</tt> instance
* to be supplied to and be returned by the <tt>getStateToBind()</tt> method.
* <tt>DirStateFactory</tt> implementations are intended to be used by
* <tt>DirContext</tt> service providers.
* When a caller binds an object using <tt>DirContext.bind()</tt>,
* he might also specify a set of attributes to be bound with the object.
* The object and attributes to be bound are passed to
* the <tt>getStateToBind()</tt> method of a factory.
* If the factory processes the object and attributes, it returns
* a corresponding pair of object and attributes to be bound.
* If the factory does not process the object, it must return null.
*<p>
* For example, a caller might bind a printer object with some printer-related
* attributes.
*<blockquote><pre>
* ctx.rebind("inky", printer, printerAttrs);
*</pre></blockquote>
* An LDAP service provider for <tt>ctx</tt> uses a <tt>DirStateFactory</tt>
* (indirectly via <tt>DirectoryManager.getStateToBind()</tt>)
* and gives it <tt>printer</tt> and <tt>printerAttrs</tt>. A factory for
* an LDAP directory might turn <tt>printer</tt> into a set of attributes
* and merge that with <tt>printerAttrs</tt>. The service provider then
* uses the resulting attributes to create an LDAP entry and updates
* the directory.
*
* <p> Since <tt>DirStateFactory</tt> extends <tt>StateFactory</tt>, it
* has two <tt>getStateToBind()</tt> methods, where one
* differs from the other by the attributes
* argument. <tt>DirectoryManager.getStateToBind()</tt> will only use
* the form that accepts the attributes argument, while
* <tt>NamingManager.getStateToBind()</tt> will only use the form that
* does not accept the attributes argument.
*
* <p> Either form of the <tt>getStateToBind()</tt> method of a
* DirStateFactory may be invoked multiple times, possibly using different
* parameters. The implementation is thread-safe.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirectoryManager#getStateToBind
* @see DirObjectFactory
* @since 1.3
*/
public interface DirStateFactory extends StateFactory {
/**
* Retrieves the state of an object for binding given the object and attributes
* to be transformed.
*<p>
* <tt>DirectoryManager.getStateToBind()</tt>
* successively loads in state factories. If a factory implements
* <tt>DirStateFactory</tt>, <tt>DirectoryManager</tt> invokes this method;
* otherwise, it invokes <tt>StateFactory.getStateToBind()</tt>.
* It does this until a factory produces a non-null answer.
*<p>
* When an exception is thrown by a factory,
* the exception is passed on to the caller
* of <tt>DirectoryManager.getStateToBind()</tt>. The search for other factories
* that may produce a non-null answer is halted.
* A factory should only throw an exception if it is sure that
* it is the only intended factory and that no other factories
* should be tried.
* If this factory cannot create an object using the arguments supplied,
* it should return null.
* <p>
* The <code>name</code> and <code>nameCtx</code> parameters may
* optionally be used to specify the name of the object being created.
* See the description of "Name and Context Parameters" in
* {@link ObjectFactory#getObjectInstance ObjectFactory.getObjectInstance()}
* for details.
* If a factory uses <code>nameCtx</code> it should synchronize its use
* against concurrent access, since context implementations are not
* guaranteed to be thread-safe.
*<p>
* The <tt>name</tt>, <tt>inAttrs</tt>, and <tt>environment</tt> parameters
* are owned by the caller.
* The implementation will not modify these objects or keep references
* to them, although it may keep references to clones or copies.
* The object returned by this method is owned by the caller.
* The implementation will not subsequently modify it.
* It will contain either a new <tt>Attributes</tt> object that is
* likewise owned by the caller, or a reference to the original
* <tt>inAttrs</tt> parameter.
*
* @param obj A possibly null object whose state is to be retrieved.
* @param name The name of this object relative to <code>nameCtx</code>,
* or null if no name is specified.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified, or null if <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment to
* be used in the creation of the object's state.
* @param inAttrs The possibly null attributes to be bound with the object.
* The factory must not modify <tt>inAttrs</tt>.
* @return A <tt>Result</tt> containing the object's state for binding
* and the corresponding
* attributes to be bound; null if the object don't use this factory.
* @exception NamingException If this factory encountered an exception
* while attempting to get the object's state, and no other factories are
* to be tried.
*
* @see DirectoryManager#getStateToBind
*/
public Result getStateToBind(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment,
Attributes inAttrs)
throws NamingException;
/**
* An object/attributes pair for returning the result of
* DirStateFactory.getStateToBind().
*/
public static class Result {
/**
* The possibly null object to be bound.
*/
private Object obj;
/**
* The possibly null attributes to be bound.
*/
private Attributes attrs;
/**
* Constructs an instance of Result.
*
* @param obj The possibly null object to be bound.
* @param outAttrs The possibly null attributes to be bound.
*/
public Result(Object obj, Attributes outAttrs) {
this.obj = obj;
this.attrs = outAttrs;
}
/**
* Retrieves the object to be bound.
* @return The possibly null object to be bound.
*/
public Object getObject() { return obj; };
/**
* Retrieves the attributes to be bound.
* @return The possibly null attributes to be bound.
*/
public Attributes getAttributes() { return attrs; };
}
}

View File

@@ -0,0 +1,338 @@
/*
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.NamingException;
import javax.naming.CannotProceedException;
import javax.naming.directory.DirContext;
import javax.naming.directory.Attributes;
import com.sun.naming.internal.ResourceManager;
import com.sun.naming.internal.FactoryEnumeration;
/**
* This class contains methods for supporting <tt>DirContext</tt>
* implementations.
*<p>
* This class is an extension of <tt>NamingManager</tt>. It contains methods
* for use by service providers for accessing object factories and
* state factories, and for getting continuation contexts for
* supporting federation.
*<p>
* <tt>DirectoryManager</tt> is safe for concurrent access by multiple threads.
*<p>
* Except as otherwise noted,
* a <tt>Name</tt>, <tt>Attributes</tt>, or environment parameter
* passed to any method is owned by the caller.
* The implementation will not modify the object or keep a reference
* to it, although it may keep a reference to a clone or copy.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see DirObjectFactory
* @see DirStateFactory
* @since 1.3
*/
public class DirectoryManager extends NamingManager {
/*
* Disallow anyone from creating one of these.
*/
DirectoryManager() {}
/**
* Creates a context in which to continue a <tt>DirContext</tt> operation.
* Operates just like <tt>NamingManager.getContinuationContext()</tt>,
* only the continuation context returned is a <tt>DirContext</tt>.
*
* @param cpe
* The non-null exception that triggered this continuation.
* @return A non-null <tt>DirContext</tt> object for continuing the operation.
* @exception NamingException If a naming exception occurred.
*
* @see NamingManager#getContinuationContext(CannotProceedException)
*/
@SuppressWarnings("unchecked")
public static DirContext getContinuationDirContext(
CannotProceedException cpe) throws NamingException {
Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment();
if (env == null) {
env = new Hashtable<>(7);
} else {
// Make a (shallow) copy of the environment.
env = (Hashtable<Object,Object>) env.clone();
}
env.put(CPE, cpe);
return (new ContinuationDirContext(cpe, env));
}
/**
* Creates an instance of an object for the specified object,
* attributes, and environment.
* <p>
* This method is the same as <tt>NamingManager.getObjectInstance</tt>
* except for the following differences:
*<ul>
*<li>
* It accepts an <tt>Attributes</tt> parameter that contains attributes
* associated with the object. The <tt>DirObjectFactory</tt> might use these
* attributes to save having to look them up from the directory.
*<li>
* The object factories tried must implement either
* <tt>ObjectFactory</tt> or <tt>DirObjectFactory</tt>.
* If it implements <tt>DirObjectFactory</tt>,
* <tt>DirObjectFactory.getObjectInstance()</tt> is used, otherwise,
* <tt>ObjectFactory.getObjectInstance()</tt> is used.
*</ul>
* Service providers that implement the <tt>DirContext</tt> interface
* should use this method, not <tt>NamingManager.getObjectInstance()</tt>.
*<p>
*
* @param refInfo The possibly null object for which to create an object.
* @param name The name of this object relative to <code>nameCtx</code>.
* Specifying a name is optional; if it is
* omitted, <code>name</code> should be null.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified. If null, <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment to
* be used in the creation of the object factory and the object.
* @param attrs The possibly null attributes associated with refInfo.
* This might not be the complete set of attributes for refInfo;
* you might be able to read more attributes from the directory.
* @return An object created using <code>refInfo</code> and <tt>attrs</tt>; or
* <code>refInfo</code> if an object cannot be created by
* a factory.
* @exception NamingException If a naming exception was encountered
* while attempting to get a URL context, or if one of the
* factories accessed throws a NamingException.
* @exception Exception If one of the factories accessed throws an
* exception, or if an error was encountered while loading
* and instantiating the factory and object classes.
* A factory should only throw an exception if it does not want
* other factories to be used in an attempt to create an object.
* See <tt>DirObjectFactory.getObjectInstance()</tt>.
* @see NamingManager#getURLContext
* @see DirObjectFactory
* @see DirObjectFactory#getObjectInstance
* @since 1.3
*/
public static Object
getObjectInstance(Object refInfo, Name name, Context nameCtx,
Hashtable<?,?> environment, Attributes attrs)
throws Exception {
ObjectFactory factory;
ObjectFactoryBuilder builder = getObjectFactoryBuilder();
if (builder != null) {
// builder must return non-null factory
factory = builder.createObjectFactory(refInfo, environment);
if (factory instanceof DirObjectFactory) {
return ((DirObjectFactory)factory).getObjectInstance(
refInfo, name, nameCtx, environment, attrs);
} else {
return factory.getObjectInstance(refInfo, name, nameCtx,
environment);
}
}
// use reference if possible
Reference ref = null;
if (refInfo instanceof Reference) {
ref = (Reference) refInfo;
} else if (refInfo instanceof Referenceable) {
ref = ((Referenceable)(refInfo)).getReference();
}
Object answer;
if (ref != null) {
String f = ref.getFactoryClassName();
if (f != null) {
// if reference identifies a factory, use exclusively
factory = getObjectFactoryFromReference(ref, f);
if (factory instanceof DirObjectFactory) {
return ((DirObjectFactory)factory).getObjectInstance(
ref, name, nameCtx, environment, attrs);
} else if (factory != null) {
return factory.getObjectInstance(ref, name, nameCtx,
environment);
}
// No factory found, so return original refInfo.
// Will reach this point if factory class is not in
// class path and reference does not contain a URL for it
return refInfo;
} else {
// if reference has no factory, check for addresses
// containing URLs
// ignore name & attrs params; not used in URL factory
answer = processURLAddrs(ref, name, nameCtx, environment);
if (answer != null) {
return answer;
}
}
}
// try using any specified factories
answer = createObjectFromFactories(refInfo, name, nameCtx,
environment, attrs);
return (answer != null) ? answer : refInfo;
}
private static Object createObjectFromFactories(Object obj, Name name,
Context nameCtx, Hashtable<?,?> environment, Attributes attrs)
throws Exception {
FactoryEnumeration factories = ResourceManager.getFactories(
Context.OBJECT_FACTORIES, environment, nameCtx);
if (factories == null)
return null;
ObjectFactory factory;
Object answer = null;
// Try each factory until one succeeds
while (answer == null && factories.hasMore()) {
factory = (ObjectFactory)factories.next();
if (factory instanceof DirObjectFactory) {
answer = ((DirObjectFactory)factory).
getObjectInstance(obj, name, nameCtx, environment, attrs);
} else {
answer =
factory.getObjectInstance(obj, name, nameCtx, environment);
}
}
return answer;
}
/**
* Retrieves the state of an object for binding when given the original
* object and its attributes.
* <p>
* This method is like <tt>NamingManager.getStateToBind</tt> except
* for the following differences:
*<ul>
*<li>It accepts an <tt>Attributes</tt> parameter containing attributes
* that were passed to the <tt>DirContext.bind()</tt> method.
*<li>It returns a non-null <tt>DirStateFactory.Result</tt> instance
* containing the object to be bound, and the attributes to
* accompany the binding. Either the object or the attributes may be null.
*<li>
* The state factories tried must each implement either
* <tt>StateFactory</tt> or <tt>DirStateFactory</tt>.
* If it implements <tt>DirStateFactory</tt>, then
* <tt>DirStateFactory.getStateToBind()</tt> is called; otherwise,
* <tt>StateFactory.getStateToBind()</tt> is called.
*</ul>
*
* Service providers that implement the <tt>DirContext</tt> interface
* should use this method, not <tt>NamingManager.getStateToBind()</tt>.
*<p>
* See NamingManager.getStateToBind() for a description of how
* the list of state factories to be tried is determined.
*<p>
* The object returned by this method is owned by the caller.
* The implementation will not subsequently modify it.
* It will contain either a new <tt>Attributes</tt> object that is
* likewise owned by the caller, or a reference to the original
* <tt>attrs</tt> parameter.
*
* @param obj The non-null object for which to get state to bind.
* @param name The name of this object relative to <code>nameCtx</code>,
* or null if no name is specified.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified, or null if <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment to
* be used in the creation of the state factory and
* the object's state.
* @param attrs The possibly null Attributes that is to be bound with the
* object.
* @return A non-null DirStateFactory.Result containing
* the object and attributes to be bound.
* If no state factory returns a non-null answer, the result will contain
* the object (<tt>obj</tt>) itself with the original attributes.
* @exception NamingException If a naming exception was encountered
* while using the factories.
* A factory should only throw an exception if it does not want
* other factories to be used in an attempt to create an object.
* See <tt>DirStateFactory.getStateToBind()</tt>.
* @see DirStateFactory
* @see DirStateFactory#getStateToBind
* @see NamingManager#getStateToBind
* @since 1.3
*/
public static DirStateFactory.Result
getStateToBind(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment, Attributes attrs)
throws NamingException {
// Get list of state factories
FactoryEnumeration factories = ResourceManager.getFactories(
Context.STATE_FACTORIES, environment, nameCtx);
if (factories == null) {
// no factories to try; just return originals
return new DirStateFactory.Result(obj, attrs);
}
// Try each factory until one succeeds
StateFactory factory;
Object objanswer;
DirStateFactory.Result answer = null;
while (answer == null && factories.hasMore()) {
factory = (StateFactory)factories.next();
if (factory instanceof DirStateFactory) {
answer = ((DirStateFactory)factory).
getStateToBind(obj, name, nameCtx, environment, attrs);
} else {
objanswer =
factory.getStateToBind(obj, name, nameCtx, environment);
if (objanswer != null) {
answer = new DirStateFactory.Result(objanswer, attrs);
}
}
}
return (answer != null) ? answer :
new DirStateFactory.Result(obj, attrs); // nothing new
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.*;
/**
* This interface represents a factory that creates an initial context.
*<p>
* The JNDI framework allows for different initial context implementations
* to be specified at runtime. The initial context is created using
* an <em>initial context factory</em>.
* An initial context factory must implement the InitialContextFactory
* interface, which provides a method for creating instances of initial
* context that implement the Context interface.
* In addition, the factory class must be public and must have a public
* constructor that accepts no arguments.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see InitialContextFactoryBuilder
* @see NamingManager#getInitialContext
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
* @since 1.3
*/
public interface InitialContextFactory {
/**
* Creates an Initial Context for beginning name resolution.
* Special requirements of this context are supplied
* using <code>environment</code>.
*<p>
* The environment parameter is owned by the caller.
* The implementation will not modify the object or keep a reference
* to it, although it may keep a reference to a clone or copy.
*
* @param environment The possibly null environment
* specifying information to be used in the creation
* of the initial context.
* @return A non-null initial context object that implements the Context
* interface.
* @exception NamingException If cannot create an initial context.
*/
public Context getInitialContext(Hashtable<?,?> environment)
throws NamingException;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.NamingException;
/**
* This interface represents a builder that creates initial context factories.
*<p>
* The JNDI framework allows for different initial context implementations
* to be specified at runtime. An initial context is created using
* an initial context factory. A program can install its own builder
* that creates initial context factories, thereby overriding the
* default policies used by the framework, by calling
* NamingManager.setInitialContextFactoryBuilder().
* The InitialContextFactoryBuilder interface must be implemented by
* such a builder.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see InitialContextFactory
* @see NamingManager#getInitialContext
* @see NamingManager#setInitialContextFactoryBuilder
* @see NamingManager#hasInitialContextFactoryBuilder
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
* @since 1.3
*/
public interface InitialContextFactoryBuilder {
/**
* Creates an initial context factory using the specified
* environment.
*<p>
* The environment parameter is owned by the caller.
* The implementation will not modify the object or keep a reference
* to it, although it may keep a reference to a clone or copy.
*
* @param environment Environment used in creating an initial
* context implementation. Can be null.
* @return A non-null initial context factory.
* @exception NamingException If an initial context factory could not be created.
*/
public InitialContextFactory
createInitialContextFactory(Hashtable<?,?> environment)
throws NamingException;
}

View File

@@ -0,0 +1,886 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.net.MalformedURLException;
import javax.naming.*;
import com.sun.naming.internal.ObjectFactoriesFilter;
import com.sun.naming.internal.VersionHelper;
import com.sun.naming.internal.ResourceManager;
import com.sun.naming.internal.FactoryEnumeration;
/**
* This class contains methods for creating context objects
* and objects referred to by location information in the naming
* or directory service.
*<p>
* This class cannot be instantiated. It has only static methods.
*<p>
* The mention of URL in the documentation for this class refers to
* a URL string as defined by RFC 1738 and its related RFCs. It is
* any string that conforms to the syntax described therein, and
* may not always have corresponding support in the java.net.URL
* class or Web browsers.
*<p>
* NamingManager is safe for concurrent access by multiple threads.
*<p>
* Except as otherwise noted,
* a <tt>Name</tt> or environment parameter
* passed to any method is owned by the caller.
* The implementation will not modify the object or keep a reference
* to it, although it may keep a reference to a clone or copy.
*
* @author Rosanna Lee
* @author Scott Seligman
* @since 1.3
*/
public class NamingManager {
/*
* Disallow anyone from creating one of these.
* Made package private so that DirectoryManager can subclass.
*/
NamingManager() {}
// should be protected and package private
static final VersionHelper helper = VersionHelper.getVersionHelper();
// --------- object factory stuff
/**
* Package-private; used by DirectoryManager and NamingManager.
*/
private static ObjectFactoryBuilder object_factory_builder = null;
/**
* The ObjectFactoryBuilder determines the policy used when
* trying to load object factories.
* See getObjectInstance() and class ObjectFactory for a description
* of the default policy.
* setObjectFactoryBuilder() overrides this default policy by installing
* an ObjectFactoryBuilder. Subsequent object factories will
* be loaded and created using the installed builder.
*<p>
* The builder can only be installed if the executing thread is allowed
* (by the security manager's checkSetFactory() method) to do so.
* Once installed, the builder cannot be replaced.
*<p>
* @param builder The factory builder to install. If null, no builder
* is installed.
* @exception SecurityException builder cannot be installed
* for security reasons.
* @exception NamingException builder cannot be installed for
* a non-security-related reason.
* @exception IllegalStateException If a factory has already been installed.
* @see #getObjectInstance
* @see ObjectFactory
* @see ObjectFactoryBuilder
* @see java.lang.SecurityManager#checkSetFactory
*/
public static synchronized void setObjectFactoryBuilder(
ObjectFactoryBuilder builder) throws NamingException {
if (object_factory_builder != null)
throw new IllegalStateException("ObjectFactoryBuilder already set");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
object_factory_builder = builder;
}
/**
* Used for accessing object factory builder.
*/
static synchronized ObjectFactoryBuilder getObjectFactoryBuilder() {
return object_factory_builder;
}
/**
* Retrieves the ObjectFactory for the object identified by a reference,
* using the reference's factory class name and factory codebase
* to load in the factory's class.
* @param ref The non-null reference to use.
* @param factoryName The non-null class name of the factory.
* @return The object factory for the object identified by ref; null
* if unable to load the factory.
*/
static ObjectFactory getObjectFactoryFromReference(
Reference ref, String factoryName)
throws IllegalAccessException,
InstantiationException,
MalformedURLException {
Class<?> clas = null;
// Try to use current class loader
try {
clas = helper.loadClassWithoutInit(factoryName);
// Validate factory's class with the objects factory serial filter
if (!ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) {
return null;
}
} catch (ClassNotFoundException e) {
// ignore and continue
// e.printStackTrace();
}
// All other exceptions are passed up.
// Not in class path; try to use codebase
String codebase;
if (clas == null &&
(codebase = ref.getFactoryClassLocation()) != null) {
try {
clas = helper.loadClass(factoryName, codebase);
// Validate factory's class with the objects factory serial filter
if (clas == null ||
!ObjectFactoriesFilter.canInstantiateObjectsFactory(clas)) {
return null;
}
} catch (ClassNotFoundException e) {
}
}
return (clas != null) ? (ObjectFactory) clas.newInstance() : null;
}
/**
* Creates an object using the factories specified in the
* <tt>Context.OBJECT_FACTORIES</tt> property of the environment
* or of the provider resource file associated with <tt>nameCtx</tt>.
*
* @return factory created; null if cannot create
*/
private static Object createObjectFromFactories(Object obj, Name name,
Context nameCtx, Hashtable<?,?> environment) throws Exception {
FactoryEnumeration factories = ResourceManager.getFactories(
Context.OBJECT_FACTORIES, environment, nameCtx);
if (factories == null)
return null;
// Try each factory until one succeeds
ObjectFactory factory;
Object answer = null;
while (answer == null && factories.hasMore()) {
factory = (ObjectFactory)factories.next();
answer = factory.getObjectInstance(obj, name, nameCtx, environment);
}
return answer;
}
private static String getURLScheme(String str) {
int colon_posn = str.indexOf(':');
int slash_posn = str.indexOf('/');
if (colon_posn > 0 && (slash_posn == -1 || colon_posn < slash_posn))
return str.substring(0, colon_posn);
return null;
}
/**
* Creates an instance of an object for the specified object
* and environment.
* <p>
* If an object factory builder has been installed, it is used to
* create a factory for creating the object.
* Otherwise, the following rules are used to create the object:
*<ol>
* <li>If <code>refInfo</code> is a <code>Reference</code>
* or <code>Referenceable</code> containing a factory class name,
* use the named factory to create the object.
* Return <code>refInfo</code> if the factory cannot be created.
* Under JDK 1.1, if the factory class must be loaded from a location
* specified in the reference, a <tt>SecurityManager</tt> must have
* been installed or the factory creation will fail.
* If an exception is encountered while creating the factory,
* it is passed up to the caller.
* <li>If <tt>refInfo</tt> is a <tt>Reference</tt> or
* <tt>Referenceable</tt> with no factory class name,
* and the address or addresses are <tt>StringRefAddr</tt>s with
* address type "URL",
* try the URL context factory corresponding to each URL's scheme id
* to create the object (see <tt>getURLContext()</tt>).
* If that fails, continue to the next step.
* <li> Use the object factories specified in
* the <tt>Context.OBJECT_FACTORIES</tt> property of the environment,
* and of the provider resource file associated with
* <tt>nameCtx</tt>, in that order.
* The value of this property is a colon-separated list of factory
* class names that are tried in order, and the first one that succeeds
* in creating an object is the one used.
* If none of the factories can be loaded,
* return <code>refInfo</code>.
* If an exception is encountered while creating the object, the
* exception is passed up to the caller.
*</ol>
*<p>
* Service providers that implement the <tt>DirContext</tt>
* interface should use
* <tt>DirectoryManager.getObjectInstance()</tt>, not this method.
* Service providers that implement only the <tt>Context</tt>
* interface should use this method.
* <p>
* Note that an object factory (an object that implements the ObjectFactory
* interface) must be public and must have a public constructor that
* accepts no arguments.
* <p>
* The <code>name</code> and <code>nameCtx</code> parameters may
* optionally be used to specify the name of the object being created.
* <code>name</code> is the name of the object, relative to context
* <code>nameCtx</code>. This information could be useful to the object
* factory or to the object implementation.
* If there are several possible contexts from which the object
* could be named -- as will often be the case -- it is up to
* the caller to select one. A good rule of thumb is to select the
* "deepest" context available.
* If <code>nameCtx</code> is null, <code>name</code> is relative
* to the default initial context. If no name is being specified, the
* <code>name</code> parameter should be null.
*
* @param refInfo The possibly null object for which to create an object.
* @param name The name of this object relative to <code>nameCtx</code>.
* Specifying a name is optional; if it is
* omitted, <code>name</code> should be null.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified. If null, <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment to
* be used in the creation of the object factory and the object.
* @return An object created using <code>refInfo</code>; or
* <code>refInfo</code> if an object cannot be created using
* the algorithm described above.
* @exception NamingException if a naming exception was encountered
* while attempting to get a URL context, or if one of the
* factories accessed throws a NamingException.
* @exception Exception if one of the factories accessed throws an
* exception, or if an error was encountered while loading
* and instantiating the factory and object classes.
* A factory should only throw an exception if it does not want
* other factories to be used in an attempt to create an object.
* See ObjectFactory.getObjectInstance().
* @see #getURLContext
* @see ObjectFactory
* @see ObjectFactory#getObjectInstance
*/
public static Object
getObjectInstance(Object refInfo, Name name, Context nameCtx,
Hashtable<?,?> environment)
throws Exception
{
ObjectFactory factory;
// Use builder if installed
ObjectFactoryBuilder builder = getObjectFactoryBuilder();
if (builder != null) {
// builder must return non-null factory
factory = builder.createObjectFactory(refInfo, environment);
return factory.getObjectInstance(refInfo, name, nameCtx,
environment);
}
// Use reference if possible
Reference ref = null;
if (refInfo instanceof Reference) {
ref = (Reference) refInfo;
} else if (refInfo instanceof Referenceable) {
ref = ((Referenceable)(refInfo)).getReference();
}
Object answer;
if (ref != null) {
String f = ref.getFactoryClassName();
if (f != null) {
// if reference identifies a factory, use exclusively
factory = getObjectFactoryFromReference(ref, f);
if (factory != null) {
return factory.getObjectInstance(ref, name, nameCtx,
environment);
}
// No factory found, so return original refInfo.
// Will reach this point if factory class is not in
// class path and reference does not contain a URL for it
return refInfo;
} else {
// if reference has no factory, check for addresses
// containing URLs
answer = processURLAddrs(ref, name, nameCtx, environment);
if (answer != null) {
return answer;
}
}
}
// try using any specified factories
answer =
createObjectFromFactories(refInfo, name, nameCtx, environment);
return (answer != null) ? answer : refInfo;
}
/*
* Ref has no factory. For each address of type "URL", try its URL
* context factory. Returns null if unsuccessful in creating and
* invoking a factory.
*/
static Object processURLAddrs(Reference ref, Name name, Context nameCtx,
Hashtable<?,?> environment)
throws NamingException {
for (int i = 0; i < ref.size(); i++) {
RefAddr addr = ref.get(i);
if (addr instanceof StringRefAddr &&
addr.getType().equalsIgnoreCase("URL")) {
String url = (String)addr.getContent();
Object answer = processURL(url, name, nameCtx, environment);
if (answer != null) {
return answer;
}
}
}
return null;
}
private static Object processURL(Object refInfo, Name name,
Context nameCtx, Hashtable<?,?> environment)
throws NamingException {
Object answer;
// If refInfo is a URL string, try to use its URL context factory
// If no context found, continue to try object factories.
if (refInfo instanceof String) {
String url = (String)refInfo;
String scheme = getURLScheme(url);
if (scheme != null) {
answer = getURLObject(scheme, refInfo, name, nameCtx,
environment);
if (answer != null) {
return answer;
}
}
}
// If refInfo is an array of URL strings,
// try to find a context factory for any one of its URLs.
// If no context found, continue to try object factories.
if (refInfo instanceof String[]) {
String[] urls = (String[])refInfo;
for (int i = 0; i <urls.length; i++) {
String scheme = getURLScheme(urls[i]);
if (scheme != null) {
answer = getURLObject(scheme, refInfo, name, nameCtx,
environment);
if (answer != null)
return answer;
}
}
}
return null;
}
/**
* Retrieves a context identified by <code>obj</code>, using the specified
* environment.
* Used by ContinuationContext.
*
* @param obj The object identifying the context.
* @param name The name of the context being returned, relative to
* <code>nameCtx</code>, or null if no name is being
* specified.
* See the <code>getObjectInstance</code> method for
* details.
* @param nameCtx The context relative to which <code>name</code> is
* specified, or null for the default initial context.
* See the <code>getObjectInstance</code> method for
* details.
* @param environment Environment specifying characteristics of the
* resulting context.
* @return A context identified by <code>obj</code>.
*
* @see #getObjectInstance
*/
static Context getContext(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment) throws NamingException {
Object answer;
if (obj instanceof Context) {
// %%% Ignore environment for now. OK since method not public.
return (Context)obj;
}
try {
answer = getObjectInstance(obj, name, nameCtx, environment);
} catch (NamingException e) {
throw e;
} catch (Exception e) {
NamingException ne = new NamingException();
ne.setRootCause(e);
throw ne;
}
return (answer instanceof Context)
? (Context)answer
: null;
}
// Used by ContinuationContext
static Resolver getResolver(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment) throws NamingException {
Object answer;
if (obj instanceof Resolver) {
// %%% Ignore environment for now. OK since method not public.
return (Resolver)obj;
}
try {
answer = getObjectInstance(obj, name, nameCtx, environment);
} catch (NamingException e) {
throw e;
} catch (Exception e) {
NamingException ne = new NamingException();
ne.setRootCause(e);
throw ne;
}
return (answer instanceof Resolver)
? (Resolver)answer
: null;
}
/***************** URL Context implementations ***************/
/**
* Creates a context for the given URL scheme id.
* <p>
* The resulting context is for resolving URLs of the
* scheme <code>scheme</code>. The resulting context is not tied
* to a specific URL. It is able to handle arbitrary URLs with
* the specified scheme.
*<p>
* The class name of the factory that creates the resulting context
* has the naming convention <i>scheme-id</i>URLContextFactory
* (e.g. "ftpURLContextFactory" for the "ftp" scheme-id),
* in the package specified as follows.
* The <tt>Context.URL_PKG_PREFIXES</tt> environment property (which
* may contain values taken from applet parameters, system properties,
* or application resource files)
* contains a colon-separated list of package prefixes.
* Each package prefix in
* the property is tried in the order specified to load the factory class.
* The default package prefix is "com.sun.jndi.url" (if none of the
* specified packages work, this default is tried).
* The complete package name is constructed using the package prefix,
* concatenated with the scheme id.
*<p>
* For example, if the scheme id is "ldap", and the
* <tt>Context.URL_PKG_PREFIXES</tt> property
* contains "com.widget:com.wiz.jndi",
* the naming manager would attempt to load the following classes
* until one is successfully instantiated:
*<ul>
* <li>com.widget.ldap.ldapURLContextFactory
* <li>com.wiz.jndi.ldap.ldapURLContextFactory
* <li>com.sun.jndi.url.ldap.ldapURLContextFactory
*</ul>
* If none of the package prefixes work, null is returned.
*<p>
* If a factory is instantiated, it is invoked with the following
* parameters to produce the resulting context.
* <p>
* <code>factory.getObjectInstance(null, environment);</code>
* <p>
* For example, invoking getObjectInstance() as shown above
* on a LDAP URL context factory would return a
* context that can resolve LDAP urls
* (e.g. "ldap://ldap.wiz.com/o=wiz,c=us",
* "ldap://ldap.umich.edu/o=umich,c=us", ...).
*<p>
* Note that an object factory (an object that implements the ObjectFactory
* interface) must be public and must have a public constructor that
* accepts no arguments.
*
* @param scheme The non-null scheme-id of the URLs supported by the context.
* @param environment The possibly null environment properties to be
* used in the creation of the object factory and the context.
* @return A context for resolving URLs with the
* scheme id <code>scheme</code>;
* <code>null</code> if the factory for creating the
* context is not found.
* @exception NamingException If a naming exception occurs while creating
* the context.
* @see #getObjectInstance
* @see ObjectFactory#getObjectInstance
*/
public static Context getURLContext(String scheme,
Hashtable<?,?> environment)
throws NamingException
{
// pass in 'null' to indicate creation of generic context for scheme
// (i.e. not specific to a URL).
Object answer = getURLObject(scheme, null, null, null, environment);
if (answer instanceof Context) {
return (Context)answer;
} else {
return null;
}
}
private static final String defaultPkgPrefix = "com.sun.jndi.url";
/**
* Creates an object for the given URL scheme id using
* the supplied urlInfo.
* <p>
* If urlInfo is null, the result is a context for resolving URLs
* with the scheme id 'scheme'.
* If urlInfo is a URL, the result is a context named by the URL.
* Names passed to this context is assumed to be relative to this
* context (i.e. not a URL). For example, if urlInfo is
* "ldap://ldap.wiz.com/o=Wiz,c=us", the resulting context will
* be that pointed to by "o=Wiz,c=us" on the server 'ldap.wiz.com'.
* Subsequent names that can be passed to this context will be
* LDAP names relative to this context (e.g. cn="Barbs Jensen").
* If urlInfo is an array of URLs, the URLs are assumed
* to be equivalent in terms of the context to which they refer.
* The resulting context is like that of the single URL case.
* If urlInfo is of any other type, that is handled by the
* context factory for the URL scheme.
* @param scheme the URL scheme id for the context
* @param urlInfo information used to create the context
* @param name name of this object relative to <code>nameCtx</code>
* @param nameCtx Context whose provider resource file will be searched
* for package prefix values (or null if none)
* @param environment Environment properties for creating the context
* @see javax.naming.InitialContext
*/
private static Object getURLObject(String scheme, Object urlInfo,
Name name, Context nameCtx,
Hashtable<?,?> environment)
throws NamingException {
// e.g. "ftpURLContextFactory"
ObjectFactory factory = (ObjectFactory)ResourceManager.getFactory(
Context.URL_PKG_PREFIXES, environment, nameCtx,
"." + scheme + "." + scheme + "URLContextFactory", defaultPkgPrefix);
if (factory == null)
return null;
// Found object factory
try {
return factory.getObjectInstance(urlInfo, name, nameCtx, environment);
} catch (NamingException e) {
throw e;
} catch (Exception e) {
NamingException ne = new NamingException();
ne.setRootCause(e);
throw ne;
}
}
// ------------ Initial Context Factory Stuff
private static InitialContextFactoryBuilder initctx_factory_builder = null;
/**
* Use this method for accessing initctx_factory_builder while
* inside an unsynchronized method.
*/
private static synchronized InitialContextFactoryBuilder
getInitialContextFactoryBuilder() {
return initctx_factory_builder;
}
/**
* Creates an initial context using the specified environment
* properties.
*<p>
* If an InitialContextFactoryBuilder has been installed,
* it is used to create the factory for creating the initial context.
* Otherwise, the class specified in the
* <tt>Context.INITIAL_CONTEXT_FACTORY</tt> environment property is used.
* Note that an initial context factory (an object that implements the
* InitialContextFactory interface) must be public and must have a
* public constructor that accepts no arguments.
*
* @param env The possibly null environment properties used when
* creating the context.
* @return A non-null initial context.
* @exception NoInitialContextException If the
* <tt>Context.INITIAL_CONTEXT_FACTORY</tt> property
* is not found or names a nonexistent
* class or a class that cannot be instantiated,
* or if the initial context could not be created for some other
* reason.
* @exception NamingException If some other naming exception was encountered.
* @see javax.naming.InitialContext
* @see javax.naming.directory.InitialDirContext
*/
public static Context getInitialContext(Hashtable<?,?> env)
throws NamingException {
InitialContextFactory factory;
InitialContextFactoryBuilder builder = getInitialContextFactoryBuilder();
if (builder == null) {
// No factory installed, use property
// Get initial context factory class name
String className = env != null ?
(String)env.get(Context.INITIAL_CONTEXT_FACTORY) : null;
if (className == null) {
NoInitialContextException ne = new NoInitialContextException(
"Need to specify class name in environment or system " +
"property, or as an applet parameter, or in an " +
"application resource file: " +
Context.INITIAL_CONTEXT_FACTORY);
throw ne;
}
try {
factory = (InitialContextFactory)
helper.loadClass(className).newInstance();
} catch(Exception e) {
NoInitialContextException ne =
new NoInitialContextException(
"Cannot instantiate class: " + className);
ne.setRootCause(e);
throw ne;
}
} else {
factory = builder.createInitialContextFactory(env);
}
return factory.getInitialContext(env);
}
/**
* Sets the InitialContextFactory builder to be builder.
*
*<p>
* The builder can only be installed if the executing thread is allowed by
* the security manager to do so. Once installed, the builder cannot
* be replaced.
* @param builder The initial context factory builder to install. If null,
* no builder is set.
* @exception SecurityException builder cannot be installed for security
* reasons.
* @exception NamingException builder cannot be installed for
* a non-security-related reason.
* @exception IllegalStateException If a builder was previous installed.
* @see #hasInitialContextFactoryBuilder
* @see java.lang.SecurityManager#checkSetFactory
*/
public static synchronized void setInitialContextFactoryBuilder(
InitialContextFactoryBuilder builder)
throws NamingException {
if (initctx_factory_builder != null)
throw new IllegalStateException(
"InitialContextFactoryBuilder already set");
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkSetFactory();
}
initctx_factory_builder = builder;
}
/**
* Determines whether an initial context factory builder has
* been set.
* @return true if an initial context factory builder has
* been set; false otherwise.
* @see #setInitialContextFactoryBuilder
*/
public static boolean hasInitialContextFactoryBuilder() {
return (getInitialContextFactoryBuilder() != null);
}
// ----- Continuation Context Stuff
/**
* Constant that holds the name of the environment property into
* which <tt>getContinuationContext()</tt> stores the value of its
* <tt>CannotProceedException</tt> parameter.
* This property is inherited by the continuation context, and may
* be used by that context's service provider to inspect the
* fields of the exception.
*<p>
* The value of this constant is "java.naming.spi.CannotProceedException".
*
* @see #getContinuationContext
* @since 1.3
*/
public static final String CPE = "java.naming.spi.CannotProceedException";
/**
* Creates a context in which to continue a context operation.
*<p>
* In performing an operation on a name that spans multiple
* namespaces, a context from one naming system may need to pass
* the operation on to the next naming system. The context
* implementation does this by first constructing a
* <code>CannotProceedException</code> containing information
* pinpointing how far it has proceeded. It then obtains a
* continuation context from JNDI by calling
* <code>getContinuationContext</code>. The context
* implementation should then resume the context operation by
* invoking the same operation on the continuation context, using
* the remainder of the name that has not yet been resolved.
*<p>
* Before making use of the <tt>cpe</tt> parameter, this method
* updates the environment associated with that object by setting
* the value of the property <a href="#CPE"><tt>CPE</tt></a>
* to <tt>cpe</tt>. This property will be inherited by the
* continuation context, and may be used by that context's
* service provider to inspect the fields of this exception.
*
* @param cpe
* The non-null exception that triggered this continuation.
* @return A non-null Context object for continuing the operation.
* @exception NamingException If a naming exception occurred.
*/
@SuppressWarnings("unchecked")
public static Context getContinuationContext(CannotProceedException cpe)
throws NamingException {
Hashtable<Object,Object> env = (Hashtable<Object,Object>)cpe.getEnvironment();
if (env == null) {
env = new Hashtable<>(7);
} else {
// Make a (shallow) copy of the environment.
env = (Hashtable<Object,Object>)env.clone();
}
env.put(CPE, cpe);
ContinuationContext cctx = new ContinuationContext(cpe, env);
return cctx.getTargetContext();
}
// ------------ State Factory Stuff
/**
* Retrieves the state of an object for binding.
* <p>
* Service providers that implement the <tt>DirContext</tt> interface
* should use <tt>DirectoryManager.getStateToBind()</tt>, not this method.
* Service providers that implement only the <tt>Context</tt> interface
* should use this method.
*<p>
* This method uses the specified state factories in
* the <tt>Context.STATE_FACTORIES</tt> property from the environment
* properties, and from the provider resource file associated with
* <tt>nameCtx</tt>, in that order.
* The value of this property is a colon-separated list of factory
* class names that are tried in order, and the first one that succeeds
* in returning the object's state is the one used.
* If no object's state can be retrieved in this way, return the
* object itself.
* If an exception is encountered while retrieving the state, the
* exception is passed up to the caller.
* <p>
* Note that a state factory
* (an object that implements the StateFactory
* interface) must be public and must have a public constructor that
* accepts no arguments.
* <p>
* The <code>name</code> and <code>nameCtx</code> parameters may
* optionally be used to specify the name of the object being created.
* See the description of "Name and Context Parameters" in
* {@link ObjectFactory#getObjectInstance
* ObjectFactory.getObjectInstance()}
* for details.
* <p>
* This method may return a <tt>Referenceable</tt> object. The
* service provider obtaining this object may choose to store it
* directly, or to extract its reference (using
* <tt>Referenceable.getReference()</tt>) and store that instead.
*
* @param obj The non-null object for which to get state to bind.
* @param name The name of this object relative to <code>nameCtx</code>,
* or null if no name is specified.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified, or null if <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment to
* be used in the creation of the state factory and
* the object's state.
* @return The non-null object representing <tt>obj</tt>'s state for
* binding. It could be the object (<tt>obj</tt>) itself.
* @exception NamingException If one of the factories accessed throws an
* exception, or if an error was encountered while loading
* and instantiating the factory and object classes.
* A factory should only throw an exception if it does not want
* other factories to be used in an attempt to create an object.
* See <tt>StateFactory.getStateToBind()</tt>.
* @see StateFactory
* @see StateFactory#getStateToBind
* @see DirectoryManager#getStateToBind
* @since 1.3
*/
public static Object
getStateToBind(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment)
throws NamingException
{
FactoryEnumeration factories = ResourceManager.getFactories(
Context.STATE_FACTORIES, environment, nameCtx);
if (factories == null) {
return obj;
}
// Try each factory until one succeeds
StateFactory factory;
Object answer = null;
while (answer == null && factories.hasMore()) {
factory = (StateFactory)factories.next();
answer = factory.getStateToBind(obj, name, nameCtx, environment);
}
return (answer != null) ? answer : obj;
}
}

View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.*;
/**
* This interface represents a factory for creating an object.
*<p>
* The JNDI framework allows for object implementations to
* be loaded in dynamically via <em>object factories</em>.
* For example, when looking up a printer bound in the name space,
* if the print service binds printer names to References, the printer
* Reference could be used to create a printer object, so that
* the caller of lookup can directly operate on the printer object
* after the lookup.
* <p>An <tt>ObjectFactory</tt> is responsible
* for creating objects of a specific type. In the above example,
* you may have a PrinterObjectFactory for creating Printer objects.
*<p>
* An object factory must implement the <tt>ObjectFactory</tt> interface.
* In addition, the factory class must be public and must have a
* public constructor that accepts no parameters.
*<p>
* The <tt>getObjectInstance()</tt> method of an object factory may
* be invoked multiple times, possibly using different parameters.
* The implementation is thread-safe.
*<p>
* The mention of URL in the documentation for this class refers to
* a URL string as defined by RFC 1738 and its related RFCs. It is
* any string that conforms to the syntax described therein, and
* may not always have corresponding support in the java.net.URL
* class or Web browsers.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see NamingManager#getObjectInstance
* @see NamingManager#getURLContext
* @see ObjectFactoryBuilder
* @see StateFactory
* @since 1.3
*/
public interface ObjectFactory {
/**
* Creates an object using the location or reference information
* specified.
* <p>
* Special requirements of this object are supplied
* using <code>environment</code>.
* An example of such an environment property is user identity
* information.
*<p>
* <tt>NamingManager.getObjectInstance()</tt>
* successively loads in object factories and invokes this method
* on them until one produces a non-null answer. When an exception
* is thrown by an object factory, the exception is passed on to the caller
* of <tt>NamingManager.getObjectInstance()</tt>
* (and no search is made for other factories
* that may produce a non-null answer).
* An object factory should only throw an exception if it is sure that
* it is the only intended factory and that no other object factories
* should be tried.
* If this factory cannot create an object using the arguments supplied,
* it should return null.
*<p>
* A <em>URL context factory</em> is a special ObjectFactory that
* creates contexts for resolving URLs or objects whose locations
* are specified by URLs. The <tt>getObjectInstance()</tt> method
* of a URL context factory will obey the following rules.
* <ol>
* <li>If <code>obj</code> is null, create a context for resolving URLs of the
* scheme associated with this factory. The resulting context is not tied
* to a specific URL: it is able to handle arbitrary URLs with this factory's
* scheme id. For example, invoking <tt>getObjectInstance()</tt> with
* <code>obj</code> set to null on an LDAP URL context factory would return a
* context that can resolve LDAP URLs
* such as "ldap://ldap.wiz.com/o=wiz,c=us" and
* "ldap://ldap.umich.edu/o=umich,c=us".
* <li>
* If <code>obj</code> is a URL string, create an object (typically a context)
* identified by the URL. For example, suppose this is an LDAP URL context
* factory. If <code>obj</code> is "ldap://ldap.wiz.com/o=wiz,c=us",
* getObjectInstance() would return the context named by the distinguished
* name "o=wiz, c=us" at the LDAP server ldap.wiz.com. This context can
* then be used to resolve LDAP names (such as "cn=George")
* relative to that context.
* <li>
* If <code>obj</code> is an array of URL strings, the assumption is that the
* URLs are equivalent in terms of the context to which they refer.
* Verification of whether the URLs are, or need to be, equivalent is up
* to the context factory. The order of the URLs in the array is
* not significant.
* The object returned by getObjectInstance() is like that of the single
* URL case. It is the object named by the URLs.
* <li>
* If <code>obj</code> is of any other type, the behavior of
* <tt>getObjectInstance()</tt> is determined by the context factory
* implementation.
* </ol>
*
* <p>
* The <tt>name</tt> and <tt>environment</tt> parameters
* are owned by the caller.
* The implementation will not modify these objects or keep references
* to them, although it may keep references to clones or copies.
*
* <p>
* <b>Name and Context Parameters.</b> &nbsp;&nbsp;&nbsp;
* <a name=NAMECTX></a>
*
* The <code>name</code> and <code>nameCtx</code> parameters may
* optionally be used to specify the name of the object being created.
* <code>name</code> is the name of the object, relative to context
* <code>nameCtx</code>.
* If there are several possible contexts from which the object
* could be named -- as will often be the case -- it is up to
* the caller to select one. A good rule of thumb is to select the
* "deepest" context available.
* If <code>nameCtx</code> is null, <code>name</code> is relative
* to the default initial context. If no name is being specified, the
* <code>name</code> parameter should be null.
* If a factory uses <code>nameCtx</code> it should synchronize its use
* against concurrent access, since context implementations are not
* guaranteed to be thread-safe.
* <p>
*
* @param obj The possibly null object containing location or reference
* information that can be used in creating an object.
* @param name The name of this object relative to <code>nameCtx</code>,
* or null if no name is specified.
* @param nameCtx The context relative to which the <code>name</code>
* parameter is specified, or null if <code>name</code> is
* relative to the default initial context.
* @param environment The possibly null environment that is used in
* creating the object.
* @return The object created; null if an object cannot be created.
* @exception Exception if this object factory encountered an exception
* while attempting to create an object, and no other object factories are
* to be tried.
*
* @see NamingManager#getObjectInstance
* @see NamingManager#getURLContext
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable<?,?> environment)
throws Exception;
}

View File

@@ -0,0 +1,75 @@
/*
* Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.naming.spi;
import java.util.Hashtable;
import javax.naming.NamingException;
/**
* This interface represents a builder that creates object factories.
*<p>
* The JNDI framework allows for object implementations to
* be loaded in dynamically via <em>object factories</em>.
* For example, when looking up a printer bound in the name space,
* if the print service binds printer names to References, the printer
* Reference could be used to create a printer object, so that
* the caller of lookup can directly operate on the printer object
* after the lookup. An ObjectFactory is responsible for creating
* objects of a specific type. JNDI uses a default policy for using
* and loading object factories. You can override this default policy
* by calling <tt>NamingManager.setObjectFactoryBuilder()</tt> with an ObjectFactoryBuilder,
* which contains the program-defined way of creating/loading
* object factories.
* Any <tt>ObjectFactoryBuilder</tt> implementation must implement this
* interface that for creating object factories.
*
* @author Rosanna Lee
* @author Scott Seligman
*
* @see ObjectFactory
* @see NamingManager#getObjectInstance
* @see NamingManager#setObjectFactoryBuilder
* @since 1.3
*/
public interface ObjectFactoryBuilder {
/**
* Creates a new object factory using the environment supplied.
*<p>
* The environment parameter is owned by the caller.
* The implementation will not modify the object or keep a reference
* to it, although it may keep a reference to a clone or copy.
*
* @param obj The possibly null object for which to create a factory.
* @param environment Environment to use when creating the factory.
* Can be null.
* @return A non-null new instance of an ObjectFactory.
* @exception NamingException If an object factory cannot be created.
*
*/
public ObjectFactory createObjectFactory(Object obj,
Hashtable<?,?> environment)
throws NamingException;
}

Some files were not shown because too many files have changed in this diff Show More