feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
117
jdkSrc/jdk8/javax/naming/ldap/BasicControl.java
Normal file
117
jdkSrc/jdk8/javax/naming/ldap/BasicControl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
96
jdkSrc/jdk8/javax/naming/ldap/Control.java
Normal file
96
jdkSrc/jdk8/javax/naming/ldap/Control.java
Normal 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;
|
||||
}
|
||||
157
jdkSrc/jdk8/javax/naming/ldap/ControlFactory.java
Normal file
157
jdkSrc/jdk8/javax/naming/ldap/ControlFactory.java
Normal 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;
|
||||
}
|
||||
}
|
||||
148
jdkSrc/jdk8/javax/naming/ldap/ExtendedRequest.java
Normal file
148
jdkSrc/jdk8/javax/naming/ldap/ExtendedRequest.java
Normal 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;
|
||||
}
|
||||
99
jdkSrc/jdk8/javax/naming/ldap/ExtendedResponse.java
Normal file
99
jdkSrc/jdk8/javax/naming/ldap/ExtendedResponse.java
Normal 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;
|
||||
}
|
||||
70
jdkSrc/jdk8/javax/naming/ldap/HasControls.java
Normal file
70
jdkSrc/jdk8/javax/naming/ldap/HasControls.java
Normal 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;
|
||||
}
|
||||
212
jdkSrc/jdk8/javax/naming/ldap/InitialLdapContext.java
Normal file
212
jdkSrc/jdk8/javax/naming/ldap/InitialLdapContext.java
Normal 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();
|
||||
}
|
||||
}
|
||||
347
jdkSrc/jdk8/javax/naming/ldap/LdapContext.java
Normal file
347
jdkSrc/jdk8/javax/naming/ldap/LdapContext.java
Normal 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";
|
||||
}
|
||||
787
jdkSrc/jdk8/javax/naming/ldap/LdapName.java
Normal file
787
jdkSrc/jdk8/javax/naming/ldap/LdapName.java
Normal 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();
|
||||
}
|
||||
}
|
||||
162
jdkSrc/jdk8/javax/naming/ldap/LdapReferralException.java
Normal file
162
jdkSrc/jdk8/javax/naming/ldap/LdapReferralException.java
Normal 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;
|
||||
}
|
||||
67
jdkSrc/jdk8/javax/naming/ldap/ManageReferralControl.java
Normal file
67
jdkSrc/jdk8/javax/naming/ldap/ManageReferralControl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
198
jdkSrc/jdk8/javax/naming/ldap/PagedResultsControl.java
Normal file
198
jdkSrc/jdk8/javax/naming/ldap/PagedResultsControl.java
Normal 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();
|
||||
}
|
||||
}
|
||||
133
jdkSrc/jdk8/javax/naming/ldap/PagedResultsResponseControl.java
Normal file
133
jdkSrc/jdk8/javax/naming/ldap/PagedResultsResponseControl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
759
jdkSrc/jdk8/javax/naming/ldap/Rdn.java
Normal file
759
jdkSrc/jdk8/javax/naming/ldap/Rdn.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
253
jdkSrc/jdk8/javax/naming/ldap/Rfc2253Parser.java
Normal file
253
jdkSrc/jdk8/javax/naming/ldap/Rfc2253Parser.java
Normal 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');
|
||||
}
|
||||
}
|
||||
222
jdkSrc/jdk8/javax/naming/ldap/SortControl.java
Normal file
222
jdkSrc/jdk8/javax/naming/ldap/SortControl.java
Normal 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();
|
||||
}
|
||||
}
|
||||
118
jdkSrc/jdk8/javax/naming/ldap/SortKey.java
Normal file
118
jdkSrc/jdk8/javax/naming/ldap/SortKey.java
Normal 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;
|
||||
}
|
||||
}
|
||||
169
jdkSrc/jdk8/javax/naming/ldap/SortResponseControl.java
Normal file
169
jdkSrc/jdk8/javax/naming/ldap/SortResponseControl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
249
jdkSrc/jdk8/javax/naming/ldap/StartTlsRequest.java
Normal file
249
jdkSrc/jdk8/javax/naming/ldap/StartTlsRequest.java
Normal 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;
|
||||
}
|
||||
206
jdkSrc/jdk8/javax/naming/ldap/StartTlsResponse.java
Normal file
206
jdkSrc/jdk8/javax/naming/ldap/StartTlsResponse.java
Normal 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;
|
||||
}
|
||||
64
jdkSrc/jdk8/javax/naming/ldap/UnsolicitedNotification.java
Normal file
64
jdkSrc/jdk8/javax/naming/ldap/UnsolicitedNotification.java
Normal 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();
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user