Add JavaFormat format Gradle Task
Closes gh-744
This commit is contained in:
18
build.gradle
18
build.gradle
@@ -17,11 +17,13 @@ buildscript {
|
||||
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.28.2"
|
||||
classpath 'org.hidetake:gradle-ssh-plugin:2.10.1'
|
||||
classpath 'io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0'
|
||||
classpath 'io.spring.javaformat:spring-javaformat-gradle-plugin:0.0.38'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.root'
|
||||
apply plugin: 'io.spring.convention.docs'
|
||||
apply plugin: 'io.spring.javaformat'
|
||||
apply plugin: 's101'
|
||||
|
||||
group = "org.springframework.ldap"
|
||||
@@ -60,4 +62,18 @@ asciidoctor {
|
||||
|
||||
s101 {
|
||||
configurationDirectory = project.file("etc/s101")
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
if (!['spring-ldap-bom', 'spring-security-docs'].contains(project.name)) {
|
||||
apply plugin: 'io.spring.javaformat'
|
||||
|
||||
if (project.name.contains('sample')) {
|
||||
tasks.whenTaskAdded { task ->
|
||||
if (task.name.contains('format') || task.name.contains('checkFormat')) {
|
||||
task.enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,49 +11,43 @@ import java.util.SortedSet;
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface LdapDataEntry {
|
||||
|
||||
/**
|
||||
* Get the value of a String attribute. If more than one attribute value
|
||||
* exists for the specified attribute, only the first one will be returned.
|
||||
* If an attribute has no value, <code>null</code> will be returned.
|
||||
*
|
||||
* Get the value of a String attribute. If more than one attribute value exists for
|
||||
* the specified attribute, only the first one will be returned. If an attribute has
|
||||
* no value, <code>null</code> will be returned.
|
||||
* @param name name of the attribute.
|
||||
* @return the value of the attribute if it exists, or <code>null</code> if
|
||||
* the attribute doesn't exist or if it exists but with no value.
|
||||
* @return the value of the attribute if it exists, or <code>null</code> if the
|
||||
* attribute doesn't exist or if it exists but with no value.
|
||||
* @throws ClassCastException if the value of the entry is not a String.
|
||||
*/
|
||||
String getStringAttribute(String name);
|
||||
|
||||
/**
|
||||
* Get the value of an Object attribute. If more than one attribute value
|
||||
* exists for the specified attribute, only the first one will be returned.
|
||||
* If an attribute has no value, <code>null</code> will be returned.
|
||||
*
|
||||
* Get the value of an Object attribute. If more than one attribute value exists for
|
||||
* the specified attribute, only the first one will be returned. If an attribute has
|
||||
* no value, <code>null</code> will be returned.
|
||||
* @param name name of the attribute.
|
||||
* @return the attribute value as an object if it exists, or
|
||||
* <code>null</code> if the attribute doesn't exist or if it exists but with
|
||||
* no value.
|
||||
* @return the attribute value as an object if it exists, or <code>null</code> if the
|
||||
* attribute doesn't exist or if it exists but with no value.
|
||||
*/
|
||||
Object getObjectAttribute(String name);
|
||||
|
||||
/**
|
||||
* Check if an Object attribute exists, regardless of whether it has a value
|
||||
* or not.
|
||||
*
|
||||
* Check if an Object attribute exists, regardless of whether it has a value or not.
|
||||
* @param name name of the attribute
|
||||
* @return <code>true</code> if the attribute exists, <code>false</code>
|
||||
* otherwise
|
||||
* @return <code>true</code> if the attribute exists, <code>false</code> otherwise
|
||||
*/
|
||||
boolean attributeExists(String name);
|
||||
|
||||
/**
|
||||
* Set the with the name <code>name</code> to the <code>value</code>.
|
||||
* If the value is a {@link Name} instance, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
*
|
||||
* Set the with the name <code>name</code> to the <code>value</code>. If the value is
|
||||
* a {@link Name} instance, equality for Distinguished Names will be used for
|
||||
* calculating attribute modifications.
|
||||
* @param name name of the attribute.
|
||||
* @param value value to set the attribute to.
|
||||
* @throws IllegalArgumentException if the value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @throws IllegalArgumentException if the value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void setAttributeValue(String name, Object value);
|
||||
@@ -63,17 +57,15 @@ public interface LdapDataEntry {
|
||||
*
|
||||
* If value is null or value.length == 0 then the attribute will be removed.
|
||||
*
|
||||
* If update mode, changes will be made only if the array has more or less
|
||||
* objects or if one or more object has changed. Reordering the objects will
|
||||
* not cause an update.
|
||||
*
|
||||
* If the values are {@link Name} instances, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
* If update mode, changes will be made only if the array has more or less objects or
|
||||
* if one or more object has changed. Reordering the objects will not cause an update.
|
||||
*
|
||||
* If the values are {@link Name} instances, equality for Distinguished Names will be
|
||||
* used for calculating attribute modifications.
|
||||
* @param name The id of the attribute.
|
||||
* @param values Attribute values.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void setAttributeValues(String name, Object[] values);
|
||||
@@ -83,130 +75,115 @@ public interface LdapDataEntry {
|
||||
*
|
||||
* If value is null or value.length == 0 then the attribute will be removed.
|
||||
*
|
||||
* If update mode, changes will be made if the array has more or less
|
||||
* objects or if one or more string has changed.
|
||||
* If update mode, changes will be made if the array has more or less objects or if
|
||||
* one or more string has changed.
|
||||
*
|
||||
* Reordering the objects will only cause an update if orderMatters is set
|
||||
* to true.
|
||||
* Reordering the objects will only cause an update if orderMatters is set to true.
|
||||
*
|
||||
* If the values are {@link Name} instances, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
* If the values are {@link Name} instances, equality for Distinguished Names will be
|
||||
* used for calculating attribute modifications.
|
||||
* @param name The id of the attribute.
|
||||
* @param values Attribute values.
|
||||
* @param orderMatters If <code>true</code>, it will be changed even if data
|
||||
* was just reordered.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @param orderMatters If <code>true</code>, it will be changed even if data was just
|
||||
* reordered.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void setAttributeValues(String name, Object[] values, boolean orderMatters);
|
||||
|
||||
/**
|
||||
* Add a value to the Attribute with the specified name. If the Attribute
|
||||
* doesn't exist it will be created. This method makes sure that the there
|
||||
* will be no duplicates of an added value - it the value exists it will not
|
||||
* be added again.
|
||||
* Add a value to the Attribute with the specified name. If the Attribute doesn't
|
||||
* exist it will be created. This method makes sure that the there will be no
|
||||
* duplicates of an added value - it the value exists it will not be added again.
|
||||
*
|
||||
* If the value is a {@link Name} instance, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
*
|
||||
* @param name the name of the Attribute to which the specified value should
|
||||
* be added.
|
||||
* If the value is a {@link Name} instance, equality for Distinguished Names will be
|
||||
* used for calculating attribute modifications.
|
||||
* @param name the name of the Attribute to which the specified value should be added.
|
||||
* @param value the Attribute value to add.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void addAttributeValue(String name, Object value);
|
||||
|
||||
/**
|
||||
* Add a value to the Attribute with the specified name. If the Attribute
|
||||
* doesn't exist it will be created. The <code>addIfDuplicateExists</code>
|
||||
* parameter controls the handling of duplicates. It <code>false</code>,
|
||||
* this method makes sure that the there will be no duplicates of an added
|
||||
* value - it the value exists it will not be added again.
|
||||
* Add a value to the Attribute with the specified name. If the Attribute doesn't
|
||||
* exist it will be created. The <code>addIfDuplicateExists</code> parameter controls
|
||||
* the handling of duplicates. It <code>false</code>, this method makes sure that the
|
||||
* there will be no duplicates of an added value - it the value exists it will not be
|
||||
* added again.
|
||||
*
|
||||
* If the value is a {@link Name} instance, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
*
|
||||
* @param name the name of the Attribute to which the specified value should
|
||||
* be added.
|
||||
* If the value is a {@link Name} instance, equality for Distinguished Names will be
|
||||
* used for calculating attribute modifications.
|
||||
* @param name the name of the Attribute to which the specified value should be added.
|
||||
* @param value the Attribute value to add.
|
||||
* @param addIfDuplicateExists <code>true</code> will add the value
|
||||
* regardless of whether there is an identical value already, allowing for
|
||||
* duplicate attribute values; <code>false</code> will not add the value if
|
||||
* it already exists.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @param addIfDuplicateExists <code>true</code> will add the value regardless of
|
||||
* whether there is an identical value already, allowing for duplicate attribute
|
||||
* values; <code>false</code> will not add the value if it already exists.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void addAttributeValue(String name, Object value,
|
||||
boolean addIfDuplicateExists);
|
||||
void addAttributeValue(String name, Object value, boolean addIfDuplicateExists);
|
||||
|
||||
/**
|
||||
* Remove a value from the Attribute with the specified name. If the
|
||||
* Attribute doesn't exist, do nothing.
|
||||
* Remove a value from the Attribute with the specified name. If the Attribute doesn't
|
||||
* exist, do nothing.
|
||||
*
|
||||
* If the value is a {@link Name} instance, equality for Distinguished
|
||||
* Names will be used for calculating attribute modifications.
|
||||
*
|
||||
* @param name the name of the Attribute from which the specified value
|
||||
* should be removed.
|
||||
* If the value is a {@link Name} instance, equality for Distinguished Names will be
|
||||
* used for calculating attribute modifications.
|
||||
* @param name the name of the Attribute from which the specified value should be
|
||||
* removed.
|
||||
* @param value the value to remove.
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance
|
||||
* and one or several of the currently present attribute values is <strong>not</strong>
|
||||
* @throws IllegalArgumentException if value is a {@link Name} instance and one or
|
||||
* several of the currently present attribute values is <strong>not</strong>
|
||||
* {@link Name} instances or Strings representing valid Distinguished Names.
|
||||
*/
|
||||
void removeAttributeValue(String name, Object value);
|
||||
|
||||
/**
|
||||
* Get all values of a String attribute.
|
||||
*
|
||||
* @param name name of the attribute.
|
||||
* @return a (possibly empty) array containing all registered values of the
|
||||
* attribute as Strings if the attribute is defined or <code>null</code>
|
||||
* otherwise.
|
||||
* @throws IllegalArgumentException if any of the attribute values is not a
|
||||
* String.
|
||||
* @return a (possibly empty) array containing all registered values of the attribute
|
||||
* as Strings if the attribute is defined or <code>null</code> otherwise.
|
||||
* @throws IllegalArgumentException if any of the attribute values is not a String.
|
||||
*/
|
||||
String[] getStringAttributes(String name);
|
||||
|
||||
/**
|
||||
* Get all values of an Object attribute.
|
||||
*
|
||||
* @param name name of the attribute.
|
||||
* @return a (possibly empty) array containing all registered values of the
|
||||
* attribute if the attribute is defined or <code>null</code> otherwise.
|
||||
* @return a (possibly empty) array containing all registered values of the attribute
|
||||
* if the attribute is defined or <code>null</code> otherwise.
|
||||
* @since 1.3
|
||||
*/
|
||||
Object[] getObjectAttributes(String name);
|
||||
|
||||
/**
|
||||
* Get all String values of the attribute as a <code>SortedSet</code>.
|
||||
*
|
||||
* @param name name of the attribute.
|
||||
* @return a <code>SortedSet</code> containing all values of the attribute,
|
||||
* or <code>null</code> if the attribute does not exist.
|
||||
* @throws IllegalArgumentException if one of the found attribute values cannot be cast to a String.
|
||||
* @return a <code>SortedSet</code> containing all values of the attribute, or
|
||||
* <code>null</code> if the attribute does not exist.
|
||||
* @throws IllegalArgumentException if one of the found attribute values cannot be
|
||||
* cast to a String.
|
||||
*/
|
||||
SortedSet<String> getAttributeSortedStringSet(String name);
|
||||
|
||||
/**
|
||||
* Returns the DN relative to the base path.
|
||||
* <b>NB</b>: as of version 2.0 the returned name will be an LdapName instance.
|
||||
*
|
||||
* Returns the DN relative to the base path. <b>NB</b>: as of version 2.0 the returned
|
||||
* name will be an LdapName instance.
|
||||
* @return The distinguished name of the current context.
|
||||
*
|
||||
* @see org.springframework.ldap.core.DirContextAdapter#getNameInNamespace()
|
||||
*/
|
||||
Name getDn();
|
||||
|
||||
|
||||
/**
|
||||
* Get all the Attributes.
|
||||
*
|
||||
* @return all the Attributes.
|
||||
* @since 1.3
|
||||
*/
|
||||
Attributes getAttributes();
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI AttributeInUseException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.AttributeInUseException
|
||||
*/
|
||||
public class AttributeInUseException extends NamingException {
|
||||
|
||||
public AttributeInUseException(
|
||||
javax.naming.directory.AttributeInUseException cause) {
|
||||
public AttributeInUseException(javax.naming.directory.AttributeInUseException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI AttributeModificationException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.AttributeModificationException
|
||||
*/
|
||||
public class AttributeModificationException extends NamingException {
|
||||
|
||||
public AttributeModificationException(
|
||||
javax.naming.directory.AttributeModificationException cause) {
|
||||
public AttributeModificationException(javax.naming.directory.AttributeModificationException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI AuthenticationException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.AuthenticationException
|
||||
@@ -32,4 +32,5 @@ public class AuthenticationException extends NamingSecurityException {
|
||||
public AuthenticationException() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,16 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI AuthenticationNotSupportedException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.AuthenticationNotSupportedException
|
||||
*/
|
||||
public class AuthenticationNotSupportedException extends
|
||||
NamingSecurityException {
|
||||
public class AuthenticationNotSupportedException extends NamingSecurityException {
|
||||
|
||||
public AuthenticationNotSupportedException(
|
||||
javax.naming.AuthenticationNotSupportedException cause) {
|
||||
public AuthenticationNotSupportedException(javax.naming.AuthenticationNotSupportedException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Thrown to indicate that an invalid value has been supplied to an LDAP
|
||||
* operation. This could be an invalid filter or dn.
|
||||
*
|
||||
* Thrown to indicate that an invalid value has been supplied to an LDAP operation. This
|
||||
* could be an invalid filter or dn.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public class BadLdapGrammarException extends NamingException {
|
||||
@@ -33,4 +33,5 @@ public class BadLdapGrammarException extends NamingException {
|
||||
public BadLdapGrammarException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI CannotProceedException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.CannotProceedException
|
||||
@@ -28,4 +28,5 @@ public class CannotProceedException extends NamingException {
|
||||
public CannotProceedException(javax.naming.CannotProceedException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI CommunicationException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.CommunicationException
|
||||
@@ -28,4 +28,5 @@ public class CommunicationException extends NamingException {
|
||||
public CommunicationException(javax.naming.CommunicationException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI ConfigurationException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.ConfigurationException
|
||||
@@ -28,4 +28,5 @@ public class ConfigurationException extends NamingException {
|
||||
public ConfigurationException(javax.naming.ConfigurationException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI ContextNotEmptyException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.ContextNotEmptyException
|
||||
@@ -28,4 +28,5 @@ public class ContextNotEmptyException extends NamingException {
|
||||
public ContextNotEmptyException(javax.naming.ContextNotEmptyException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InsufficientResourcesException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.InsufficientResourcesException
|
||||
*/
|
||||
public class InsufficientResourcesException extends NamingException {
|
||||
|
||||
public InsufficientResourcesException(
|
||||
javax.naming.InsufficientResourcesException cause) {
|
||||
public InsufficientResourcesException(javax.naming.InsufficientResourcesException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InterruptedNamingException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.InterruptedNamingException
|
||||
*/
|
||||
public class InterruptedNamingException extends NamingException {
|
||||
|
||||
public InterruptedNamingException(
|
||||
javax.naming.InterruptedNamingException cause) {
|
||||
public InterruptedNamingException(javax.naming.InterruptedNamingException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidAttributeIdentifierException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.InvalidAttributeIdentifierException
|
||||
*/
|
||||
public class InvalidAttributeIdentifierException extends NamingException {
|
||||
|
||||
public InvalidAttributeIdentifierException(
|
||||
javax.naming.directory.InvalidAttributeIdentifierException cause) {
|
||||
public InvalidAttributeIdentifierException(javax.naming.directory.InvalidAttributeIdentifierException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidAttributeValueException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.InvalidAttributeValueException
|
||||
*/
|
||||
public class InvalidAttributeValueException extends NamingException {
|
||||
|
||||
public InvalidAttributeValueException(
|
||||
javax.naming.directory.InvalidAttributeValueException cause) {
|
||||
public InvalidAttributeValueException(javax.naming.directory.InvalidAttributeValueException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidAttributesException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.InvalidAttributesException
|
||||
*/
|
||||
public class InvalidAttributesException extends NamingException {
|
||||
|
||||
public InvalidAttributesException(
|
||||
javax.naming.directory.InvalidAttributesException cause) {
|
||||
public InvalidAttributesException(javax.naming.directory.InvalidAttributesException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidNameException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.InvalidNameException
|
||||
@@ -28,4 +28,5 @@ public class InvalidNameException extends NamingException {
|
||||
public InvalidNameException(javax.naming.InvalidNameException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidSearchControlsException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.InvalidSearchControlsException
|
||||
*/
|
||||
public class InvalidSearchControlsException extends NamingException {
|
||||
|
||||
public InvalidSearchControlsException(
|
||||
javax.naming.directory.InvalidSearchControlsException cause) {
|
||||
public InvalidSearchControlsException(javax.naming.directory.InvalidSearchControlsException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI InvalidSearchFilterException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.InvalidSearchFilterException
|
||||
*/
|
||||
public class InvalidSearchFilterException extends NamingException {
|
||||
|
||||
public InvalidSearchFilterException(
|
||||
javax.naming.directory.InvalidSearchFilterException cause) {
|
||||
public InvalidSearchFilterException(javax.naming.directory.InvalidSearchFilterException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI LdapReferralException.
|
||||
*
|
||||
* This class is not abstract. We need to be able to instantiate it, should the
|
||||
* caught exception be a provider-specific subclass of
|
||||
*
|
||||
* This class is not abstract. We need to be able to instantiate it, should the caught
|
||||
* exception be a provider-specific subclass of
|
||||
* {@link javax.naming.ldap.LdapReferralException}.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.ldap.LdapReferralException
|
||||
@@ -32,4 +32,5 @@ public class LdapReferralException extends ReferralException {
|
||||
public LdapReferralException(javax.naming.ldap.LdapReferralException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI LimitExceededException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.LimitExceededException
|
||||
@@ -28,4 +28,5 @@ public class LimitExceededException extends NamingException {
|
||||
public LimitExceededException(javax.naming.LimitExceededException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI LinkException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.LinkException
|
||||
@@ -28,4 +28,5 @@ public class LinkException extends NamingException {
|
||||
public LinkException(javax.naming.LinkException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI LinkLoopException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.LinkLoopException
|
||||
@@ -28,4 +28,5 @@ public class LinkLoopException extends LinkException {
|
||||
public LinkLoopException(javax.naming.LinkLoopException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI MalformedLinkException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.MalformedLinkException
|
||||
@@ -28,4 +28,5 @@ public class MalformedLinkException extends LinkException {
|
||||
public MalformedLinkException(javax.naming.MalformedLinkException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NameAlreadyBoundException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NameAlreadyBoundException
|
||||
*/
|
||||
public class NameAlreadyBoundException extends NamingException {
|
||||
|
||||
public NameAlreadyBoundException(
|
||||
javax.naming.NameAlreadyBoundException cause) {
|
||||
public NameAlreadyBoundException(javax.naming.NameAlreadyBoundException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NameNotFoundException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NameNotFoundException
|
||||
*/
|
||||
public class NameNotFoundException extends NamingException {
|
||||
|
||||
|
||||
public NameNotFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
@@ -32,4 +32,5 @@ public class NameNotFoundException extends NamingException {
|
||||
public NameNotFoundException(javax.naming.NameNotFoundException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import javax.naming.Name;
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
/**
|
||||
* Base class for exception thrown by the framework whenever it encounters a
|
||||
* problem related to LDAP.
|
||||
*
|
||||
* Base class for exception thrown by the framework whenever it encounters a problem
|
||||
* related to LDAP.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
@@ -36,12 +36,11 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
private Throwable cause;
|
||||
|
||||
/**
|
||||
* Overrides {@link NestedRuntimeException#getCause()} since serialization
|
||||
* always tries to serialize the base class before the subclass. Our
|
||||
* <tt>cause</tt> may have a <tt>resolvedObj</tt> that is not
|
||||
* serializable. By storing the cause in this class, we get a chance at
|
||||
* temporarily nulling the cause before serialization, thus in effect making
|
||||
* the current instance serializable.
|
||||
* Overrides {@link NestedRuntimeException#getCause()} since serialization always
|
||||
* tries to serialize the base class before the subclass. Our <tt>cause</tt> may have
|
||||
* a <tt>resolvedObj</tt> that is not serializable. By storing the cause in this
|
||||
* class, we get a chance at temporarily nulling the cause before serialization, thus
|
||||
* in effect making the current instance serializable.
|
||||
*/
|
||||
public Throwable getCause() {
|
||||
// Even if you cannot set the cause of this exception other than through
|
||||
@@ -53,9 +52,7 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Constructor that takes a message.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public NamingException(String msg) {
|
||||
super(msg);
|
||||
@@ -63,13 +60,9 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Constructor that allows a message and a root cause.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
* @param cause
|
||||
* the cause of the exception. This argument is generally
|
||||
* expected to be a proper subclass of
|
||||
* {@link javax.naming.NamingException}.
|
||||
* @param msg the detail message
|
||||
* @param cause the cause of the exception. This argument is generally expected to be
|
||||
* a proper subclass of {@link javax.naming.NamingException}.
|
||||
*/
|
||||
public NamingException(String msg, Throwable cause) {
|
||||
super(msg);
|
||||
@@ -77,26 +70,21 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that allows a plain root cause, intended for subclasses
|
||||
* mirroring corresponding <code>javax.naming</code> exceptions.
|
||||
*
|
||||
* @param cause
|
||||
* the cause of the exception. This argument is generally
|
||||
* expected to be a proper subclass of
|
||||
* {@link javax.naming.NamingException}.
|
||||
* Constructor that allows a plain root cause, intended for subclasses mirroring
|
||||
* corresponding <code>javax.naming</code> exceptions.
|
||||
* @param cause the cause of the exception. This argument is generally expected to be
|
||||
* a proper subclass of {@link javax.naming.NamingException}.
|
||||
*/
|
||||
public NamingException(Throwable cause) {
|
||||
this(cause != null ? cause.getMessage() : null, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the explanation associated with this exception,
|
||||
* if the root cause was an instance of {@link javax.naming.NamingException}.
|
||||
*
|
||||
* @return a detail string explaining more about this exception if the root
|
||||
* cause is an instance of javax.naming.NamingException, or
|
||||
* <code>null</code> if there is no detail message for this
|
||||
* exception
|
||||
* Convenience method to get the explanation associated with this exception, if the
|
||||
* root cause was an instance of {@link javax.naming.NamingException}.
|
||||
* @return a detail string explaining more about this exception if the root cause is
|
||||
* an instance of javax.naming.NamingException, or <code>null</code> if there is no
|
||||
* detail message for this exception
|
||||
*/
|
||||
public String getExplanation() {
|
||||
if (getCause() instanceof javax.naming.NamingException) {
|
||||
@@ -106,49 +94,42 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the unresolved part of the name associated with
|
||||
* this exception, if the root cause was an instance of
|
||||
* Convenience method to get the unresolved part of the name associated with this
|
||||
* exception, if the root cause was an instance of
|
||||
* {@link javax.naming.NamingException}.
|
||||
*
|
||||
* @return a composite name describing the part of the name that has not
|
||||
* been resolved if the root cause is an instance of
|
||||
* javax.naming.NamingException, or <code>null</code> if the
|
||||
* remaining name field has not been set
|
||||
* @return a composite name describing the part of the name that has not been resolved
|
||||
* if the root cause is an instance of javax.naming.NamingException, or
|
||||
* <code>null</code> if the remaining name field has not been set
|
||||
*/
|
||||
public Name getRemainingName() {
|
||||
if (getCause() instanceof javax.naming.NamingException) {
|
||||
return ((javax.naming.NamingException) getCause())
|
||||
.getRemainingName();
|
||||
return ((javax.naming.NamingException) getCause()).getRemainingName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the leading portion of the resolved name
|
||||
* associated with this exception, if the root cause was an instance of
|
||||
* Convenience method to get the leading portion of the resolved name associated with
|
||||
* this exception, if the root cause was an instance of
|
||||
* {@link javax.naming.NamingException}.
|
||||
*
|
||||
* @return a composite name describing the leading portion of the name
|
||||
* that was resolved successfully if the root cause is an instance
|
||||
* of javax.naming.NamingException, or <code>null</code> if the
|
||||
* resolved name field has not been set
|
||||
* @return a composite name describing the leading portion of the name that was
|
||||
* resolved successfully if the root cause is an instance of
|
||||
* javax.naming.NamingException, or <code>null</code> if the resolved name field has
|
||||
* not been set
|
||||
*/
|
||||
public Name getResolvedName() {
|
||||
if (getCause() instanceof javax.naming.NamingException) {
|
||||
return ((javax.naming.NamingException) getCause())
|
||||
.getResolvedName();
|
||||
return ((javax.naming.NamingException) getCause()).getResolvedName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get the resolved object associated with this
|
||||
* exception, if the root cause was an instance of
|
||||
* {@link javax.naming.NamingException}.
|
||||
*
|
||||
* @return the object that was resolved so far if the root cause is an
|
||||
* instance of javax.naming.NamingException, or <code>null</code>
|
||||
* if the resolved object field has not been set
|
||||
* Convenience method to get the resolved object associated with this exception, if
|
||||
* the root cause was an instance of {@link javax.naming.NamingException}.
|
||||
* @return the object that was resolved so far if the root cause is an instance of
|
||||
* javax.naming.NamingException, or <code>null</code> if the resolved object field has
|
||||
* not been set
|
||||
*/
|
||||
public Object getResolvedObj() {
|
||||
if (getCause() instanceof javax.naming.NamingException) {
|
||||
@@ -158,14 +139,11 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the <tt>resolvedObj</tt> of the causing exception is
|
||||
* suspected to be non-serializable, and if so temporarily nulls it before
|
||||
* calling the default serialization mechanism.
|
||||
*
|
||||
* @param stream
|
||||
* the stream onto which this object is serialized
|
||||
* @throws IOException
|
||||
* if there is an error writing this object to the stream
|
||||
* Checks if the <tt>resolvedObj</tt> of the causing exception is suspected to be
|
||||
* non-serializable, and if so temporarily nulls it before calling the default
|
||||
* serialization mechanism.
|
||||
* @param stream the stream onto which this object is serialized
|
||||
* @throws IOException if there is an error writing this object to the stream
|
||||
*/
|
||||
private void writeObject(ObjectOutputStream stream) throws IOException {
|
||||
Object resolvedObj = getResolvedObj();
|
||||
@@ -176,11 +154,14 @@ public abstract class NamingException extends NestedRuntimeException {
|
||||
namingException.setResolvedObj(null);
|
||||
try {
|
||||
stream.defaultWriteObject();
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
namingException.setResolvedObj(resolvedObj);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
stream.defaultWriteObject();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NamingSecurityException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NamingSecurityException
|
||||
@@ -28,4 +28,5 @@ public class NamingSecurityException extends NamingException {
|
||||
public NamingSecurityException(javax.naming.NamingSecurityException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NoInitialContextException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NoInitialContextException
|
||||
*/
|
||||
public class NoInitialContextException extends NamingException {
|
||||
|
||||
public NoInitialContextException(
|
||||
javax.naming.NoInitialContextException cause) {
|
||||
public NoInitialContextException(javax.naming.NoInitialContextException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NoPermissionException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NoPermissionException
|
||||
@@ -28,4 +28,5 @@ public class NoPermissionException extends NamingSecurityException {
|
||||
public NoPermissionException(javax.naming.NoPermissionException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NoSuchAttributeException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.NoSuchAttributeException
|
||||
@@ -32,4 +32,5 @@ public class NoSuchAttributeException extends NamingException {
|
||||
public NoSuchAttributeException(javax.naming.directory.NoSuchAttributeException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI NotContextException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.NotContextException
|
||||
@@ -28,4 +28,5 @@ public class NotContextException extends NamingException {
|
||||
public NotContextException(javax.naming.NotContextException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI OperationNotSupportedException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.OperationNotSupportedException
|
||||
*/
|
||||
public class OperationNotSupportedException extends NamingException {
|
||||
|
||||
public OperationNotSupportedException(
|
||||
javax.naming.OperationNotSupportedException cause) {
|
||||
public OperationNotSupportedException(javax.naming.OperationNotSupportedException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI PartialResultException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.PartialResultException
|
||||
@@ -28,4 +28,5 @@ public class PartialResultException extends NamingException {
|
||||
public PartialResultException(javax.naming.PartialResultException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI ReferralException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.ReferralException
|
||||
@@ -28,4 +28,5 @@ public class ReferralException extends NamingException {
|
||||
public ReferralException(javax.naming.ReferralException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI SchemaViolationException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.directory.SchemaViolationException
|
||||
*/
|
||||
public class SchemaViolationException extends NamingException {
|
||||
|
||||
public SchemaViolationException(
|
||||
javax.naming.directory.SchemaViolationException cause) {
|
||||
public SchemaViolationException(javax.naming.directory.SchemaViolationException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI ServiceUnavailableException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.ServiceUnavailableException
|
||||
*/
|
||||
public class ServiceUnavailableException extends NamingException {
|
||||
|
||||
public ServiceUnavailableException(
|
||||
javax.naming.ServiceUnavailableException cause) {
|
||||
public ServiceUnavailableException(javax.naming.ServiceUnavailableException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI SizeLimitExceededException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.SizeLimitExceededException
|
||||
*/
|
||||
public class SizeLimitExceededException extends LimitExceededException {
|
||||
|
||||
public SizeLimitExceededException(
|
||||
javax.naming.SizeLimitExceededException cause) {
|
||||
public SizeLimitExceededException(javax.naming.SizeLimitExceededException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* Runtime exception mirroring the JNDI TimeLimitExceededException.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
* @see javax.naming.TimeLimitExceededException
|
||||
*/
|
||||
public class TimeLimitExceededException extends LimitExceededException {
|
||||
|
||||
public TimeLimitExceededException(
|
||||
javax.naming.TimeLimitExceededException cause) {
|
||||
public TimeLimitExceededException(javax.naming.TimeLimitExceededException cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.springframework.ldap;
|
||||
|
||||
/**
|
||||
* NamingException to be thrown when no other matching subclass is found.
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
@@ -35,4 +35,5 @@ public class UncategorizedLdapException extends NamingException {
|
||||
public UncategorizedLdapException(Throwable cause) {
|
||||
super("Uncategorized exception occured during LDAP processing", cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -68,9 +68,9 @@ class LdapCoreRuntimeHints implements RuntimeHintsRegistrar {
|
||||
hints.reflection().registerTypeIfPresent(classLoader, "com.sun.jndi.ldap.ctl.SortResponseControl",
|
||||
(builder) -> builder.onReachableType(SortControlDirContextProcessor.class)
|
||||
.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
|
||||
hints.reflection().registerType(TypeReference.of("javax.net.ssl.SSLSocketFactory"), (builder) -> builder
|
||||
.withMethod("getDefault", Collections.emptyList(), ExecutableMode.INVOKE)
|
||||
.onReachableType(TypeReference.of("com.sun.jndi.ldap.Connection")));
|
||||
hints.reflection().registerType(TypeReference.of("javax.net.ssl.SSLSocketFactory"),
|
||||
(builder) -> builder.withMethod("getDefault", Collections.emptyList(), ExecutableMode.INVOKE)
|
||||
.onReachableType(TypeReference.of("com.sun.jndi.ldap.Connection")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,21 +20,19 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.ldap.core.AuthenticationSource;
|
||||
|
||||
/**
|
||||
* Decorator on AuthenticationSource to have default authentication information
|
||||
* be returned should the target return empty principal and credentials. Useful
|
||||
* in combination with <code>AcegiAuthenticationSource</code> if users are to be
|
||||
* allowed to read some information even though they are not logged in.
|
||||
* Decorator on AuthenticationSource to have default authentication information be
|
||||
* returned should the target return empty principal and credentials. Useful in
|
||||
* combination with <code>AcegiAuthenticationSource</code> if users are to be allowed to
|
||||
* read some information even though they are not logged in.
|
||||
* <p>
|
||||
* <b>Note:</b> The <code>defaultUser</code> should be an non-privileged
|
||||
* user. This is important as this is the one that will be used when no user is
|
||||
* logged in (i.e. empty principal is returned from the target
|
||||
* AuthenticationSource).
|
||||
*
|
||||
* <b>Note:</b> The <code>defaultUser</code> should be an non-privileged user. This is
|
||||
* important as this is the one that will be used when no user is logged in (i.e. empty
|
||||
* principal is returned from the target AuthenticationSource).
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
AuthenticationSource, InitializingBean {
|
||||
public class DefaultValuesAuthenticationSourceDecorator implements AuthenticationSource, InitializingBean {
|
||||
|
||||
private AuthenticationSource target;
|
||||
|
||||
@@ -50,18 +48,13 @@ public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
|
||||
/**
|
||||
* Constructor to setup instance directly.
|
||||
*
|
||||
* @param target
|
||||
* the target AuthenticationSource.
|
||||
* @param defaultUser
|
||||
* dn of the user to use when the target returns an empty
|
||||
* principal.
|
||||
* @param defaultPassword
|
||||
* password of the user to use when the target returns an empty
|
||||
* principal.
|
||||
* @param target the target AuthenticationSource.
|
||||
* @param defaultUser dn of the user to use when the target returns an empty
|
||||
* principal.
|
||||
* @param defaultPassword password of the user to use when the target returns an empty
|
||||
* principal.
|
||||
*/
|
||||
public DefaultValuesAuthenticationSourceDecorator(
|
||||
AuthenticationSource target, String defaultUser,
|
||||
public DefaultValuesAuthenticationSourceDecorator(AuthenticationSource target, String defaultUser,
|
||||
String defaultPassword) {
|
||||
this.target = target;
|
||||
this.defaultUser = defaultUser;
|
||||
@@ -69,54 +62,48 @@ public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the target's principal is not empty; if not, the credentials
|
||||
* from the target is returned - otherwise return the
|
||||
* <code>defaultPassword</code>.
|
||||
*
|
||||
* Checks if the target's principal is not empty; if not, the credentials from the
|
||||
* target is returned - otherwise return the <code>defaultPassword</code>.
|
||||
* @return the target's password if the target's principal is not empty, the
|
||||
* <code>defaultPassword</code> otherwise.
|
||||
* <code>defaultPassword</code> otherwise.
|
||||
*/
|
||||
public String getCredentials() {
|
||||
if (StringUtils.hasText(target.getPrincipal())) {
|
||||
return target.getCredentials();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return defaultPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the target's principal is not empty; if not, this is returned -
|
||||
* otherwise return the <code>defaultPassword</code>.
|
||||
*
|
||||
* @return the target's principal if it is not empty, the
|
||||
* <code>defaultPassword</code> otherwise.
|
||||
* Checks if the target's principal is not empty; if not, this is returned - otherwise
|
||||
* return the <code>defaultPassword</code>.
|
||||
* @return the target's principal if it is not empty, the <code>defaultPassword</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public String getPrincipal() {
|
||||
String principal = target.getPrincipal();
|
||||
if (StringUtils.hasText(principal)) {
|
||||
return principal;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return defaultUser;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the password of the default user.
|
||||
*
|
||||
* @param defaultPassword
|
||||
* the password of the default user.
|
||||
* @param defaultPassword the password of the default user.
|
||||
*/
|
||||
public void setDefaultPassword(String defaultPassword) {
|
||||
this.defaultPassword = defaultPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default user DN. This should be a non-privileged user, since it
|
||||
* will be used when no authentication information is returned from the
|
||||
* target.
|
||||
*
|
||||
* @param defaultUser
|
||||
* DN of the default user.
|
||||
* Set the default user DN. This should be a non-privileged user, since it will be
|
||||
* used when no authentication information is returned from the target.
|
||||
* @param defaultUser DN of the default user.
|
||||
*/
|
||||
public void setDefaultUser(String defaultUser) {
|
||||
this.defaultUser = defaultUser;
|
||||
@@ -124,9 +111,7 @@ public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
|
||||
/**
|
||||
* Set the target AuthenticationSource.
|
||||
*
|
||||
* @param target
|
||||
* the target AuthenticationSource.
|
||||
* @param target the target AuthenticationSource.
|
||||
*/
|
||||
public void setTarget(AuthenticationSource target) {
|
||||
this.target = target;
|
||||
@@ -134,23 +119,21 @@ public class DefaultValuesAuthenticationSourceDecorator implements
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'target' must be set.'");
|
||||
throw new IllegalArgumentException("Property 'target' must be set.'");
|
||||
}
|
||||
|
||||
if (defaultUser == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'defaultUser' must be set.'");
|
||||
throw new IllegalArgumentException("Property 'defaultUser' must be set.'");
|
||||
}
|
||||
|
||||
if (defaultPassword == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property 'defaultPassword' must be set.'");
|
||||
throw new IllegalArgumentException("Property 'defaultPassword' must be set.'");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,69 +48,123 @@ import static org.springframework.ldap.config.ParserUtils.getString;
|
||||
* @author Eddu Melendez
|
||||
*/
|
||||
public class ContextSourceParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String ATT_ANONYMOUS_READ_ONLY = "anonymous-read-only";
|
||||
|
||||
private static final String ATT_AUTHENTICATION_SOURCE_REF = "authentication-source-ref";
|
||||
|
||||
private static final String ATT_AUTHENTICATION_STRATEGY_REF = "authentication-strategy-ref";
|
||||
|
||||
private static final String ATT_BASE = "base";
|
||||
|
||||
private static final String ATT_PASSWORD = "password";
|
||||
|
||||
private static final String ATT_NATIVE_POOLING = "native-pooling";
|
||||
|
||||
private static final String ATT_REFERRAL = "referral";
|
||||
|
||||
private static final String ATT_URL = "url";
|
||||
|
||||
private static final String ATT_BASE_ENV_PROPS_REF = "base-env-props-ref";
|
||||
|
||||
// pooling attributes
|
||||
private static final String ATT_MAX_ACTIVE = "max-active";
|
||||
private static final String ATT_MAX_TOTAL = "max-total";
|
||||
private static final String ATT_MAX_IDLE = "max-idle";
|
||||
private static final String ATT_MIN_IDLE = "min-idle";
|
||||
private static final String ATT_MAX_WAIT = "max-wait";
|
||||
private static final String ATT_WHEN_EXHAUSTED = "when-exhausted";
|
||||
private static final String ATT_TEST_ON_BORROW = "test-on-borrow";
|
||||
private static final String ATT_TEST_ON_RETURN = "test-on-return";
|
||||
private static final String ATT_TEST_WHILE_IDLE = "test-while-idle";
|
||||
private static final String ATT_EVICTION_RUN_MILLIS = "eviction-run-interval-millis";
|
||||
private static final String ATT_TESTS_PER_EVICTION_RUN = "tests-per-eviction-run";
|
||||
private static final String ATT_EVICTABLE_TIME_MILLIS = "min-evictable-time-millis";
|
||||
private static final String ATT_VALIDATION_QUERY_BASE = "validation-query-base";
|
||||
private static final String ATT_VALIDATION_QUERY_FILTER = "validation-query-filter";
|
||||
private static final String ATT_VALIDATION_QUERY_SEARCH_CONTROLS_REF = "validation-query-search-controls-ref";
|
||||
private static final String ATT_NON_TRANSIENT_EXCEPTIONS = "non-transient-exceptions";
|
||||
private static final String ATT_MAX_IDLE_PER_KEY = "max-idle-per-key";
|
||||
private static final String ATT_MIN_IDLE_PER_KEY = "min-idle-per-key";
|
||||
private static final String ATT_MAX_TOTAL_PER_KEY = "max-total-per-key";
|
||||
private static final String ATT_EVICTION_POLICY_CLASS = "eviction-policy-class";
|
||||
private static final String ATT_FAIRNESS = "fairness";
|
||||
private static final String ATT_JMX_ENABLE = "jmx-enable";
|
||||
private static final String ATT_JMX_NAME_BASE = "jmx-name-base";
|
||||
private static final String ATT_JMX_NAME_PREFIX = "jmx-name-prefix";
|
||||
private static final String ATT_LIFO = "lifo";
|
||||
private static final String ATT_BLOCK_WHEN_EXHAUSTED = "block-when-exhausted";
|
||||
private static final String ATT_TEST_ON_CREATE = "test-on-create";
|
||||
private static final String ATT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = "soft-min-evictable-idle-time-millis";
|
||||
|
||||
private static final String ATT_MAX_TOTAL = "max-total";
|
||||
|
||||
private static final String ATT_MAX_IDLE = "max-idle";
|
||||
|
||||
private static final String ATT_MIN_IDLE = "min-idle";
|
||||
|
||||
private static final String ATT_MAX_WAIT = "max-wait";
|
||||
|
||||
private static final String ATT_WHEN_EXHAUSTED = "when-exhausted";
|
||||
|
||||
private static final String ATT_TEST_ON_BORROW = "test-on-borrow";
|
||||
|
||||
private static final String ATT_TEST_ON_RETURN = "test-on-return";
|
||||
|
||||
private static final String ATT_TEST_WHILE_IDLE = "test-while-idle";
|
||||
|
||||
private static final String ATT_EVICTION_RUN_MILLIS = "eviction-run-interval-millis";
|
||||
|
||||
private static final String ATT_TESTS_PER_EVICTION_RUN = "tests-per-eviction-run";
|
||||
|
||||
private static final String ATT_EVICTABLE_TIME_MILLIS = "min-evictable-time-millis";
|
||||
|
||||
private static final String ATT_VALIDATION_QUERY_BASE = "validation-query-base";
|
||||
|
||||
private static final String ATT_VALIDATION_QUERY_FILTER = "validation-query-filter";
|
||||
|
||||
private static final String ATT_VALIDATION_QUERY_SEARCH_CONTROLS_REF = "validation-query-search-controls-ref";
|
||||
|
||||
private static final String ATT_NON_TRANSIENT_EXCEPTIONS = "non-transient-exceptions";
|
||||
|
||||
private static final String ATT_MAX_IDLE_PER_KEY = "max-idle-per-key";
|
||||
|
||||
private static final String ATT_MIN_IDLE_PER_KEY = "min-idle-per-key";
|
||||
|
||||
private static final String ATT_MAX_TOTAL_PER_KEY = "max-total-per-key";
|
||||
|
||||
private static final String ATT_EVICTION_POLICY_CLASS = "eviction-policy-class";
|
||||
|
||||
private static final String ATT_FAIRNESS = "fairness";
|
||||
|
||||
private static final String ATT_JMX_ENABLE = "jmx-enable";
|
||||
|
||||
private static final String ATT_JMX_NAME_BASE = "jmx-name-base";
|
||||
|
||||
private static final String ATT_JMX_NAME_PREFIX = "jmx-name-prefix";
|
||||
|
||||
private static final String ATT_LIFO = "lifo";
|
||||
|
||||
private static final String ATT_BLOCK_WHEN_EXHAUSTED = "block-when-exhausted";
|
||||
|
||||
private static final String ATT_TEST_ON_CREATE = "test-on-create";
|
||||
|
||||
private static final String ATT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = "soft-min-evictable-idle-time-millis";
|
||||
|
||||
private static final String ATT_USERNAME = "username";
|
||||
static final String DEFAULT_ID = "contextSource";
|
||||
|
||||
private static final int DEFAULT_MAX_ACTIVE = 8;
|
||||
|
||||
private static final int DEFAULT_MAX_TOTAL = -1;
|
||||
|
||||
private static final int DEFAULT_MAX_IDLE = 8;
|
||||
|
||||
private static final int DEFAULT_MIN_IDLE = 0;
|
||||
|
||||
private static final int DEFAULT_MAX_WAIT = -1;
|
||||
|
||||
private static final int DEFAULT_EVICTION_RUN_MILLIS = -1;
|
||||
|
||||
private static final int DEFAULT_TESTS_PER_EVICTION_RUN = 3;
|
||||
|
||||
private static final int DEFAULT_EVICTABLE_MILLIS = 1000 * 60 * 30;
|
||||
|
||||
private static final int DEFAULT_MAX_TOTAL_PER_KEY = 8;
|
||||
|
||||
private static final int DEFAULT_MAX_IDLE_PER_KEY = 8;
|
||||
|
||||
private static final int DEFAULT_MIN_IDLE_PER_KEY = 0;
|
||||
private static final String DEFAULT_EVICTION_POLICY_CLASS_NAME =
|
||||
"org.apache.commons.pool2.impl.DefaultEvictionPolicy";
|
||||
|
||||
private static final String DEFAULT_EVICTION_POLICY_CLASS_NAME = "org.apache.commons.pool2.impl.DefaultEvictionPolicy";
|
||||
|
||||
private static final boolean DEFAULT_FAIRNESS = false;
|
||||
|
||||
private static final boolean DEFAULT_JMX_ENABLE = true;
|
||||
|
||||
private static final String DEFAULT_JMX_NAME_BASE = null;
|
||||
|
||||
private static final String DEFAULT_JMX_NAME_PREFIX = "ldap-pool";
|
||||
|
||||
private static final boolean DEFAULT_LIFO = true;
|
||||
|
||||
private static final int DEFAULT_MAX_WAIT_MILLIS = -1;
|
||||
|
||||
private static final boolean DEFAULT_BLOCK_WHEN_EXHAUSTED = true;
|
||||
|
||||
private static final int DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS = -1;
|
||||
|
||||
@Override
|
||||
@@ -125,10 +179,8 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
builder.addPropertyValue("userDn", username);
|
||||
builder.addPropertyValue("password", password);
|
||||
|
||||
BeanDefinitionBuilder urlsBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(UrlsFactory.class)
|
||||
.setFactoryMethod("urls")
|
||||
.addConstructorArgValue(url);
|
||||
BeanDefinitionBuilder urlsBuilder = BeanDefinitionBuilder.rootBeanDefinition(UrlsFactory.class)
|
||||
.setFactoryMethod("urls").addConstructorArgValue(url);
|
||||
|
||||
builder.addPropertyValue("urls", urlsBuilder.getBeanDefinition());
|
||||
builder.addPropertyValue("base", getString(element, ATT_BASE, ""));
|
||||
@@ -140,20 +192,23 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
builder.addPropertyValue("pooled", nativePooling);
|
||||
|
||||
String authStrategyRef = element.getAttribute(ATT_AUTHENTICATION_STRATEGY_REF);
|
||||
if(StringUtils.hasText(authStrategyRef)) {
|
||||
if (StringUtils.hasText(authStrategyRef)) {
|
||||
builder.addPropertyReference("authenticationStrategy", authStrategyRef);
|
||||
}
|
||||
|
||||
String authSourceRef = element.getAttribute(ATT_AUTHENTICATION_SOURCE_REF);
|
||||
if(StringUtils.hasText(authSourceRef)) {
|
||||
if (StringUtils.hasText(authSourceRef)) {
|
||||
builder.addPropertyReference("authenticationSource", authSourceRef);
|
||||
} else {
|
||||
Assert.hasText(username, "username attribute must be specified unless an authentication-source-ref explicitly configured");
|
||||
Assert.hasText(password, "password attribute must be specified unless an authentication-source-ref explicitly configured");
|
||||
}
|
||||
else {
|
||||
Assert.hasText(username,
|
||||
"username attribute must be specified unless an authentication-source-ref explicitly configured");
|
||||
Assert.hasText(password,
|
||||
"password attribute must be specified unless an authentication-source-ref explicitly configured");
|
||||
}
|
||||
|
||||
String baseEnvPropsRef = element.getAttribute(ATT_BASE_ENV_PROPS_REF);
|
||||
if(StringUtils.hasText(baseEnvPropsRef)) {
|
||||
if (StringUtils.hasText(baseEnvPropsRef)) {
|
||||
builder.addPropertyReference("baseEnvironmentProperties", baseEnvPropsRef);
|
||||
}
|
||||
|
||||
@@ -162,7 +217,8 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
|
||||
BeanDefinition actualContextSourceDefinition = targetContextSourceDefinition;
|
||||
if (!anonymousReadOnly) {
|
||||
BeanDefinitionBuilder proxyBuilder = BeanDefinitionBuilder.rootBeanDefinition(TransactionAwareContextSourceProxy.class);
|
||||
BeanDefinitionBuilder proxyBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(TransactionAwareContextSourceProxy.class);
|
||||
proxyBuilder.addConstructorArgValue(targetContextSourceDefinition);
|
||||
actualContextSourceDefinition = proxyBuilder.getBeanDefinition();
|
||||
}
|
||||
@@ -173,9 +229,7 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
return actualContextSourceDefinition;
|
||||
}
|
||||
|
||||
private BeanDefinition applyPoolingIfApplicable(
|
||||
BeanDefinition targetContextSourceDefinition,
|
||||
Element element,
|
||||
private BeanDefinition applyPoolingIfApplicable(BeanDefinition targetContextSourceDefinition, Element element,
|
||||
boolean nativePooling) {
|
||||
|
||||
Element poolingElement = DomUtils.getChildElementByTagName(element, Elements.POOLING);
|
||||
@@ -184,11 +238,12 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
if (pooling2Element != null && poolingElement != null) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s cannot be enabled together with %s.", Elements.POOLING2, Elements.POOLING));
|
||||
} else if (poolingElement == null && pooling2Element == null) {
|
||||
}
|
||||
else if (poolingElement == null && pooling2Element == null) {
|
||||
return targetContextSourceDefinition;
|
||||
}
|
||||
|
||||
if(nativePooling) {
|
||||
if (nativePooling) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("%s cannot be enabled together with %s", ATT_NATIVE_POOLING, Elements.POOLING));
|
||||
}
|
||||
@@ -209,20 +264,29 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(PoolingContextSource.class);
|
||||
builder.addPropertyValue("contextSource", targetContextSourceDefinition);
|
||||
|
||||
builder.addPropertyValue("maxActive", getString(poolingElement, ATT_MAX_ACTIVE, String.valueOf(DEFAULT_MAX_ACTIVE)));
|
||||
builder.addPropertyValue("maxTotal", getString(poolingElement, ATT_MAX_TOTAL, String.valueOf(DEFAULT_MAX_TOTAL)));
|
||||
builder.addPropertyValue("maxIdle", getString(poolingElement, ATT_MAX_IDLE, String.valueOf(DEFAULT_MAX_IDLE)));
|
||||
builder.addPropertyValue("minIdle", getString(poolingElement, ATT_MIN_IDLE, String.valueOf(DEFAULT_MIN_IDLE)));
|
||||
builder.addPropertyValue("maxWait", getString(poolingElement, ATT_MAX_WAIT, String.valueOf(DEFAULT_MAX_WAIT)));
|
||||
builder.addPropertyValue("maxActive",
|
||||
getString(poolingElement, ATT_MAX_ACTIVE, String.valueOf(DEFAULT_MAX_ACTIVE)));
|
||||
builder.addPropertyValue("maxTotal",
|
||||
getString(poolingElement, ATT_MAX_TOTAL, String.valueOf(DEFAULT_MAX_TOTAL)));
|
||||
builder.addPropertyValue("maxIdle",
|
||||
getString(poolingElement, ATT_MAX_IDLE, String.valueOf(DEFAULT_MAX_IDLE)));
|
||||
builder.addPropertyValue("minIdle",
|
||||
getString(poolingElement, ATT_MIN_IDLE, String.valueOf(DEFAULT_MIN_IDLE)));
|
||||
builder.addPropertyValue("maxWait",
|
||||
getString(poolingElement, ATT_MAX_WAIT, String.valueOf(DEFAULT_MAX_WAIT)));
|
||||
String whenExhausted = getString(poolingElement, ATT_WHEN_EXHAUSTED, PoolExhaustedAction.BLOCK.name());
|
||||
builder.addPropertyValue("whenExhaustedAction", PoolExhaustedAction.valueOf(whenExhausted).getValue());
|
||||
builder.addPropertyValue("timeBetweenEvictionRunsMillis", getString(poolingElement, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
builder.addPropertyValue("minEvictableIdleTimeMillis", getString(poolingElement, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
builder.addPropertyValue("numTestsPerEvictionRun", getString(poolingElement, ATT_TESTS_PER_EVICTION_RUN, String.valueOf(DEFAULT_TESTS_PER_EVICTION_RUN)));
|
||||
builder.addPropertyValue("timeBetweenEvictionRunsMillis",
|
||||
getString(poolingElement, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
builder.addPropertyValue("minEvictableIdleTimeMillis",
|
||||
getString(poolingElement, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
builder.addPropertyValue("numTestsPerEvictionRun", getString(poolingElement, ATT_TESTS_PER_EVICTION_RUN,
|
||||
String.valueOf(DEFAULT_TESTS_PER_EVICTION_RUN)));
|
||||
|
||||
boolean testOnBorrow = getBoolean(poolingElement, ATT_TEST_ON_BORROW, false);
|
||||
boolean testOnReturn = getBoolean(poolingElement, ATT_TEST_ON_RETURN, false);
|
||||
@@ -236,34 +300,40 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
}
|
||||
}
|
||||
|
||||
private void populatePoolValidationProperties(BeanDefinitionBuilder builder, Element element,
|
||||
boolean testOnBorrow, boolean testOnReturn, boolean testWhileIdle) {
|
||||
private void populatePoolValidationProperties(BeanDefinitionBuilder builder, Element element, boolean testOnBorrow,
|
||||
boolean testOnReturn, boolean testWhileIdle) {
|
||||
|
||||
builder.addPropertyValue("testOnBorrow", testOnBorrow);
|
||||
builder.addPropertyValue("testOnReturn", testOnReturn);
|
||||
builder.addPropertyValue("testWhileIdle", testWhileIdle);
|
||||
|
||||
BeanDefinitionBuilder validatorBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultDirContextValidator.class);
|
||||
BeanDefinitionBuilder validatorBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(DefaultDirContextValidator.class);
|
||||
validatorBuilder.addPropertyValue("base", getString(element, ATT_VALIDATION_QUERY_BASE, ""));
|
||||
validatorBuilder.addPropertyValue("filter",
|
||||
getString(element, ATT_VALIDATION_QUERY_FILTER, DefaultDirContextValidator.DEFAULT_FILTER));
|
||||
String searchControlsRef = element.getAttribute(ATT_VALIDATION_QUERY_SEARCH_CONTROLS_REF);
|
||||
if(StringUtils.hasText(searchControlsRef)) {
|
||||
if (StringUtils.hasText(searchControlsRef)) {
|
||||
validatorBuilder.addPropertyReference("searchControls", searchControlsRef);
|
||||
}
|
||||
builder.addPropertyValue("dirContextValidator", validatorBuilder.getBeanDefinition());
|
||||
|
||||
builder.addPropertyValue("timeBetweenEvictionRunsMillis", getString(element, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
builder.addPropertyValue("numTestsPerEvictionRun", getInt(element, ATT_TESTS_PER_EVICTION_RUN, DEFAULT_TESTS_PER_EVICTION_RUN));
|
||||
builder.addPropertyValue("minEvictableIdleTimeMillis", getString(element, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
builder.addPropertyValue("timeBetweenEvictionRunsMillis",
|
||||
getString(element, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
builder.addPropertyValue("numTestsPerEvictionRun",
|
||||
getInt(element, ATT_TESTS_PER_EVICTION_RUN, DEFAULT_TESTS_PER_EVICTION_RUN));
|
||||
builder.addPropertyValue("minEvictableIdleTimeMillis",
|
||||
getString(element, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
|
||||
String nonTransientExceptions = getString(element, ATT_NON_TRANSIENT_EXCEPTIONS, CommunicationException.class.getName());
|
||||
String nonTransientExceptions = getString(element, ATT_NON_TRANSIENT_EXCEPTIONS,
|
||||
CommunicationException.class.getName());
|
||||
String[] strings = StringUtils.commaDelimitedListToStringArray(nonTransientExceptions);
|
||||
Set<Class<?>> nonTransientExceptionClasses = new HashSet<Class<?>>();
|
||||
for (String className : strings) {
|
||||
try {
|
||||
nonTransientExceptionClasses.add(ClassUtils.getDefaultClassLoader().loadClass(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException(String.format("%s is not a valid class name", className), e);
|
||||
}
|
||||
}
|
||||
@@ -271,28 +341,28 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
builder.addPropertyValue("nonTransientExceptions", nonTransientExceptionClasses);
|
||||
}
|
||||
|
||||
|
||||
private void populatePoolValidationProperties(BeanDefinitionBuilder builder, Element element) {
|
||||
|
||||
BeanDefinitionBuilder validatorBuilder = BeanDefinitionBuilder.rootBeanDefinition(
|
||||
org.springframework.ldap.pool2.validation.DefaultDirContextValidator.class);
|
||||
BeanDefinitionBuilder validatorBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(org.springframework.ldap.pool2.validation.DefaultDirContextValidator.class);
|
||||
validatorBuilder.addPropertyValue("base", getString(element, ATT_VALIDATION_QUERY_BASE, ""));
|
||||
validatorBuilder.addPropertyValue("filter",
|
||||
getString(element, ATT_VALIDATION_QUERY_FILTER,
|
||||
org.springframework.ldap.pool2.validation.DefaultDirContextValidator.DEFAULT_FILTER));
|
||||
validatorBuilder.addPropertyValue("filter", getString(element, ATT_VALIDATION_QUERY_FILTER,
|
||||
org.springframework.ldap.pool2.validation.DefaultDirContextValidator.DEFAULT_FILTER));
|
||||
String searchControlsRef = element.getAttribute(ATT_VALIDATION_QUERY_SEARCH_CONTROLS_REF);
|
||||
if(StringUtils.hasText(searchControlsRef)) {
|
||||
if (StringUtils.hasText(searchControlsRef)) {
|
||||
validatorBuilder.addPropertyReference("searchControls", searchControlsRef);
|
||||
}
|
||||
builder.addPropertyValue("dirContextValidator", validatorBuilder.getBeanDefinition());
|
||||
|
||||
String nonTransientExceptions = getString(element, ATT_NON_TRANSIENT_EXCEPTIONS, CommunicationException.class.getName());
|
||||
String nonTransientExceptions = getString(element, ATT_NON_TRANSIENT_EXCEPTIONS,
|
||||
CommunicationException.class.getName());
|
||||
String[] strings = StringUtils.commaDelimitedListToStringArray(nonTransientExceptions);
|
||||
Set<Class<?>> nonTransientExceptionClasses = new HashSet<Class<?>>();
|
||||
for (String className : strings) {
|
||||
try {
|
||||
nonTransientExceptionClasses.add(ClassUtils.getDefaultClassLoader().loadClass(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalArgumentException(String.format("%s is not a valid class name", className), e);
|
||||
}
|
||||
}
|
||||
@@ -301,36 +371,50 @@ public class ContextSourceParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
private void populatePoolConfigProperties(BeanDefinitionBuilder builder, Element element) {
|
||||
BeanDefinitionBuilder configBuilder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(PoolConfig.class);
|
||||
BeanDefinitionBuilder configBuilder = BeanDefinitionBuilder.rootBeanDefinition(PoolConfig.class);
|
||||
|
||||
configBuilder.addPropertyValue("maxTotal", getString(element, ATT_MAX_TOTAL, String.valueOf(DEFAULT_MAX_TOTAL)));
|
||||
configBuilder.addPropertyValue("maxTotalPerKey", getString(element, ATT_MAX_TOTAL_PER_KEY, String.valueOf(DEFAULT_MAX_TOTAL_PER_KEY)));
|
||||
configBuilder.addPropertyValue("maxIdlePerKey", getString(element, ATT_MAX_IDLE_PER_KEY, String.valueOf(DEFAULT_MAX_IDLE_PER_KEY)));
|
||||
configBuilder.addPropertyValue("minIdlePerKey", getString(element, ATT_MIN_IDLE_PER_KEY, String.valueOf(DEFAULT_MIN_IDLE_PER_KEY)));
|
||||
configBuilder.addPropertyValue("evictionPolicyClassName", getString(element, ATT_EVICTION_POLICY_CLASS, DEFAULT_EVICTION_POLICY_CLASS_NAME));
|
||||
configBuilder.addPropertyValue("maxTotal",
|
||||
getString(element, ATT_MAX_TOTAL, String.valueOf(DEFAULT_MAX_TOTAL)));
|
||||
configBuilder.addPropertyValue("maxTotalPerKey",
|
||||
getString(element, ATT_MAX_TOTAL_PER_KEY, String.valueOf(DEFAULT_MAX_TOTAL_PER_KEY)));
|
||||
configBuilder.addPropertyValue("maxIdlePerKey",
|
||||
getString(element, ATT_MAX_IDLE_PER_KEY, String.valueOf(DEFAULT_MAX_IDLE_PER_KEY)));
|
||||
configBuilder.addPropertyValue("minIdlePerKey",
|
||||
getString(element, ATT_MIN_IDLE_PER_KEY, String.valueOf(DEFAULT_MIN_IDLE_PER_KEY)));
|
||||
configBuilder.addPropertyValue("evictionPolicyClassName",
|
||||
getString(element, ATT_EVICTION_POLICY_CLASS, DEFAULT_EVICTION_POLICY_CLASS_NAME));
|
||||
configBuilder.addPropertyValue("fairness", getBoolean(element, ATT_FAIRNESS, DEFAULT_FAIRNESS));
|
||||
configBuilder.addPropertyValue("jmxEnabled", getBoolean(element, ATT_JMX_ENABLE, DEFAULT_JMX_ENABLE));
|
||||
configBuilder.addPropertyValue("jmxNameBase", getString(element, ATT_JMX_NAME_BASE, DEFAULT_JMX_NAME_BASE));
|
||||
configBuilder.addPropertyValue("jmxNamePrefix", getString(element, ATT_JMX_NAME_PREFIX, DEFAULT_JMX_NAME_PREFIX));
|
||||
configBuilder.addPropertyValue("jmxNamePrefix",
|
||||
getString(element, ATT_JMX_NAME_PREFIX, DEFAULT_JMX_NAME_PREFIX));
|
||||
configBuilder.addPropertyValue("lifo", getBoolean(element, ATT_LIFO, DEFAULT_LIFO));
|
||||
configBuilder.addPropertyValue("maxWaitMillis", getString(element, ATT_MAX_WAIT, String.valueOf(DEFAULT_MAX_WAIT_MILLIS)));
|
||||
configBuilder.addPropertyValue("blockWhenExhausted", Boolean.valueOf(getString(element, ATT_BLOCK_WHEN_EXHAUSTED, String.valueOf(DEFAULT_BLOCK_WHEN_EXHAUSTED))));
|
||||
configBuilder.addPropertyValue("maxWaitMillis",
|
||||
getString(element, ATT_MAX_WAIT, String.valueOf(DEFAULT_MAX_WAIT_MILLIS)));
|
||||
configBuilder.addPropertyValue("blockWhenExhausted", Boolean
|
||||
.valueOf(getString(element, ATT_BLOCK_WHEN_EXHAUSTED, String.valueOf(DEFAULT_BLOCK_WHEN_EXHAUSTED))));
|
||||
configBuilder.addPropertyValue("testOnBorrow", getBoolean(element, ATT_TEST_ON_BORROW, false));
|
||||
configBuilder.addPropertyValue("testOnCreate", getBoolean(element, ATT_TEST_ON_CREATE, false));
|
||||
configBuilder.addPropertyValue("testOnReturn", getBoolean(element, ATT_TEST_ON_RETURN, false));
|
||||
configBuilder.addPropertyValue("testWhileIdle", getBoolean(element, ATT_TEST_WHILE_IDLE, false));
|
||||
configBuilder.addPropertyValue("timeBetweenEvictionRunsMillis", getString(element, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
configBuilder.addPropertyValue("numTestsPerEvictionRun", getString(element, ATT_TESTS_PER_EVICTION_RUN, String.valueOf(DEFAULT_TESTS_PER_EVICTION_RUN)));
|
||||
configBuilder.addPropertyValue("minEvictableIdleTimeMillis", getString(element, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
configBuilder.addPropertyValue("softMinEvictableIdleTimeMillis", getString(element, ATT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS, String.valueOf(DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS)));
|
||||
configBuilder.addPropertyValue("timeBetweenEvictionRunsMillis",
|
||||
getString(element, ATT_EVICTION_RUN_MILLIS, String.valueOf(DEFAULT_EVICTION_RUN_MILLIS)));
|
||||
configBuilder.addPropertyValue("numTestsPerEvictionRun",
|
||||
getString(element, ATT_TESTS_PER_EVICTION_RUN, String.valueOf(DEFAULT_TESTS_PER_EVICTION_RUN)));
|
||||
configBuilder.addPropertyValue("minEvictableIdleTimeMillis",
|
||||
getString(element, ATT_EVICTABLE_TIME_MILLIS, String.valueOf(DEFAULT_EVICTABLE_MILLIS)));
|
||||
configBuilder.addPropertyValue("softMinEvictableIdleTimeMillis", getString(element,
|
||||
ATT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS, String.valueOf(DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS)));
|
||||
|
||||
builder.addConstructorArgValue(configBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
static class UrlsFactory {
|
||||
|
||||
public static String[] urls(String value) {
|
||||
return StringUtils.commaDelimitedListToStringArray(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,20 +30,22 @@ import static org.springframework.ldap.config.ParserUtils.getString;
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public class DefaultRenamingStrategyParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String ATT_TEMP_SUFFIX = "temp-suffix";
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DefaultTempEntryRenamingStrategy.class);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(DefaultTempEntryRenamingStrategy.class);
|
||||
|
||||
builder.addPropertyValue("tempSuffix",
|
||||
getString(element, ATT_TEMP_SUFFIX,
|
||||
DefaultTempEntryRenamingStrategy.DEFAULT_TEMP_SUFFIX));
|
||||
getString(element, ATT_TEMP_SUFFIX, DefaultTempEntryRenamingStrategy.DEFAULT_TEMP_SUFFIX));
|
||||
|
||||
AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
|
||||
parserContext.getContainingBeanDefinition().getPropertyValues()
|
||||
.addPropertyValue("renamingStrategy", beanDefinition);
|
||||
parserContext.getContainingBeanDefinition().getPropertyValues().addPropertyValue("renamingStrategy",
|
||||
beanDefinition);
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,12 +21,21 @@ package org.springframework.ldap.config;
|
||||
* @author Anindya Chatterjee
|
||||
*/
|
||||
public abstract class Elements {
|
||||
|
||||
public static final String CONTEXT_SOURCE = "context-source";
|
||||
|
||||
public static final String POOLING = "pooling";
|
||||
|
||||
public static final String POOLING2 = "pooling2";
|
||||
|
||||
public static final String LDAP_TEMPLATE = "ldap-template";
|
||||
|
||||
public static final String TRANSACTION_MANAGER = "transaction-manager";
|
||||
|
||||
public static final String REPOSITORIES = "repositories";
|
||||
|
||||
public static final String DEFAULT_RENAMING_STRATEGY = "default-renaming-strategy";
|
||||
|
||||
public static final String DIFFERENT_SUBTREE_RENAMING_STRATEGY = "different-subtree-renaming-strategy";
|
||||
|
||||
}
|
||||
|
||||
@@ -23,10 +23,12 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
|
||||
* @author Rob Winch
|
||||
*/
|
||||
public class LdapNamespaceHandler extends NamespaceHandlerSupport {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
registerBeanDefinitionParser(Elements.CONTEXT_SOURCE, new ContextSourceParser());
|
||||
registerBeanDefinitionParser(Elements.LDAP_TEMPLATE, new LdapTemplateParser());
|
||||
registerBeanDefinitionParser(Elements.TRANSACTION_MANAGER, new TransactionManagerParser());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,16 +35,25 @@ import static org.springframework.ldap.config.ParserUtils.getString;
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public class LdapTemplateParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String ATT_COUNT_LIMIT = "count-limit";
|
||||
|
||||
private static final String ATT_TIME_LIMIT = "time-limit";
|
||||
|
||||
private static final String ATT_SEARCH_SCOPE = "search-scope";
|
||||
|
||||
private static final String ATT_IGNORE_PARTIAL_RESULT = "ignore-partial-result";
|
||||
|
||||
private static final String ATT_IGNORE_NAME_NOT_FOUND = "ignore-name-not-found";
|
||||
|
||||
private static final String ATT_ODM_REF = "odm-ref";
|
||||
|
||||
private static final String ATT_CONTEXT_SOURCE_REF = "context-source-ref";
|
||||
|
||||
private static final String DEFAULT_ID = "ldapTemplate";
|
||||
|
||||
private static final int DEFAULT_COUNT_LIMIT = 0;
|
||||
|
||||
private static final int DEFAULT_TIME_LIMIT = 0;
|
||||
|
||||
@Override
|
||||
@@ -62,7 +71,7 @@ public class LdapTemplateParser implements BeanDefinitionParser {
|
||||
builder.addPropertyValue("ignoreNameNotFoundException", getBoolean(element, ATT_IGNORE_NAME_NOT_FOUND, false));
|
||||
|
||||
String odmRef = element.getAttribute(ATT_ODM_REF);
|
||||
if(StringUtils.hasText(odmRef)) {
|
||||
if (StringUtils.hasText(odmRef)) {
|
||||
builder.addPropertyReference("objectDirectoryMapper", odmRef);
|
||||
}
|
||||
|
||||
@@ -73,4 +82,5 @@ public class LdapTemplateParser implements BeanDefinitionParser {
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.w3c.dom.Element;
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
final class ParserUtils {
|
||||
|
||||
static final String NAMESPACE = "http://www.springframework.org/schema/ldap";
|
||||
|
||||
/**
|
||||
@@ -58,4 +59,5 @@ final class ParserUtils {
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,15 @@ import static org.springframework.ldap.config.ParserUtils.getString;
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public class TransactionManagerParser implements BeanDefinitionParser {
|
||||
|
||||
private static final String ATT_CONTEXT_SOURCE_REF = "context-source-ref";
|
||||
|
||||
private static final String ATT_DATA_SOURCE_REF = "data-source-ref";
|
||||
|
||||
private static final String ATT_SESSION_FACTORY_REF = "session-factory-ref";
|
||||
|
||||
private static final String ATT_TEMP_SUFFIX = "temp-suffix";
|
||||
|
||||
private static final String ATT_SUBTREE_NODE = "subtree-node";
|
||||
|
||||
private static final String DEFAULT_ID = "transactionManager";
|
||||
@@ -54,20 +58,21 @@ public class TransactionManagerParser implements BeanDefinitionParser {
|
||||
String dataSourceRef = element.getAttribute(ATT_DATA_SOURCE_REF);
|
||||
String sessionFactoryRef = element.getAttribute(ATT_SESSION_FACTORY_REF);
|
||||
|
||||
if(StringUtils.hasText(dataSourceRef) && StringUtils.hasText(sessionFactoryRef)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Only one of %s and %s can be specified",
|
||||
ATT_DATA_SOURCE_REF, ATT_SESSION_FACTORY_REF));
|
||||
if (StringUtils.hasText(dataSourceRef) && StringUtils.hasText(sessionFactoryRef)) {
|
||||
throw new IllegalArgumentException(String.format("Only one of %s and %s can be specified",
|
||||
ATT_DATA_SOURCE_REF, ATT_SESSION_FACTORY_REF));
|
||||
}
|
||||
|
||||
BeanDefinitionBuilder builder;
|
||||
if(StringUtils.hasText(dataSourceRef)) {
|
||||
if (StringUtils.hasText(dataSourceRef)) {
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(ContextSourceAndDataSourceTransactionManager.class);
|
||||
builder.addPropertyReference("dataSource", dataSourceRef);
|
||||
} else if(StringUtils.hasText(sessionFactoryRef)) {
|
||||
}
|
||||
else if (StringUtils.hasText(sessionFactoryRef)) {
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(ContextSourceAndHibernateTransactionManager.class);
|
||||
builder.addPropertyReference("sessionFactory", sessionFactoryRef);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// Standard transaction manager
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(ContextSourceTransactionManager.class);
|
||||
}
|
||||
@@ -75,13 +80,14 @@ public class TransactionManagerParser implements BeanDefinitionParser {
|
||||
builder.addPropertyReference("contextSource", contextSourceRef);
|
||||
|
||||
Element defaultStrategyChild = DomUtils.getChildElementByTagName(element, Elements.DEFAULT_RENAMING_STRATEGY);
|
||||
Element differentSubtreeChild = DomUtils.getChildElementByTagName(element, Elements.DIFFERENT_SUBTREE_RENAMING_STRATEGY);
|
||||
Element differentSubtreeChild = DomUtils.getChildElementByTagName(element,
|
||||
Elements.DIFFERENT_SUBTREE_RENAMING_STRATEGY);
|
||||
|
||||
if(defaultStrategyChild != null) {
|
||||
if (defaultStrategyChild != null) {
|
||||
builder.addPropertyValue("renamingStrategy", parseDefaultRenamingStrategy(defaultStrategyChild));
|
||||
}
|
||||
|
||||
if(differentSubtreeChild != null) {
|
||||
if (differentSubtreeChild != null) {
|
||||
builder.addPropertyValue("renamingStrategy", parseDifferentSubtreeRenamingStrategy(differentSubtreeChild));
|
||||
}
|
||||
|
||||
@@ -94,7 +100,8 @@ public class TransactionManagerParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
private BeanDefinition parseDifferentSubtreeRenamingStrategy(Element element) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DifferentSubtreeTempEntryRenamingStrategy.class);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(DifferentSubtreeTempEntryRenamingStrategy.class);
|
||||
|
||||
String subtreeNode = element.getAttribute(ATT_SUBTREE_NODE);
|
||||
Assert.hasText(subtreeNode, ATT_SUBTREE_NODE + " must be specified");
|
||||
@@ -105,11 +112,11 @@ public class TransactionManagerParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
public BeanDefinition parseDefaultRenamingStrategy(Element element) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DefaultTempEntryRenamingStrategy.class);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(DefaultTempEntryRenamingStrategy.class);
|
||||
|
||||
builder.addPropertyValue("tempSuffix",
|
||||
getString(element, ATT_TEMP_SUFFIX,
|
||||
DefaultTempEntryRenamingStrategy.DEFAULT_TEMP_SUFFIX));
|
||||
getString(element, ATT_TEMP_SUFFIX, DefaultTempEntryRenamingStrategy.DEFAULT_TEMP_SUFFIX));
|
||||
|
||||
return builder.getBeanDefinition();
|
||||
}
|
||||
|
||||
@@ -29,47 +29,47 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Convenient base class useful when implementing a standard DirContextProcessor
|
||||
* which has a request control and a response control. It handles the loading of
|
||||
* the control classes, using fallback implementations specified by the subclass
|
||||
* if necessary. It handles the request control constructor invocation; it only
|
||||
* needs the constructor arguments to be provided. It also handles most of the
|
||||
* work in the post processing of the response control, only delegating to a
|
||||
* template method for the actual value retrieval. In short, it makes it easy to
|
||||
* implement a custom DirContextProcessor.<p>
|
||||
*
|
||||
* Convenient base class useful when implementing a standard DirContextProcessor which has
|
||||
* a request control and a response control. It handles the loading of the control
|
||||
* classes, using fallback implementations specified by the subclass if necessary. It
|
||||
* handles the request control constructor invocation; it only needs the constructor
|
||||
* arguments to be provided. It also handles most of the work in the post processing of
|
||||
* the response control, only delegating to a template method for the actual value
|
||||
* retrieval. In short, it makes it easy to implement a custom DirContextProcessor.
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
* public class SortControlDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor {
|
||||
* String sortKey;
|
||||
*
|
||||
*
|
||||
* private boolean sorted = false;
|
||||
*
|
||||
*
|
||||
* private int resultCode = -1;
|
||||
*
|
||||
*
|
||||
* public SortControlDirContextProcessor(String sortKey) {
|
||||
* this.sortKey = sortKey;
|
||||
*
|
||||
*
|
||||
* defaultRequestControl = "javax.naming.ldap.SortControl";
|
||||
* defaultResponseControl = "com.sun.jndi.ldap.ctl.SortControl";
|
||||
* fallbackRequestControl = "javax.naming.ldap.SortResponseControl";
|
||||
* fallbackResponseControl = "com.sun.jndi.ldap.ctl.SortResponseControl";
|
||||
*
|
||||
*
|
||||
* loadControlClasses();
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public boolean isSorted() {
|
||||
* return sorted;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public int getResultCode() {
|
||||
* return resultCode;
|
||||
* }
|
||||
*
|
||||
*
|
||||
* public Control createRequestControl() {
|
||||
* return super.createRequestControl(new Class[] { String[].class, boolean.class }, new Object[] {
|
||||
* new String[] { sortKey }, Boolean.valueOf(critical) });
|
||||
* }
|
||||
*
|
||||
*
|
||||
* protected void handleResponse(Object control) {
|
||||
* Boolean result = (Boolean) invokeMethod("isSorted", responseControlClass, control);
|
||||
* this.sorted = result.booleanValue();
|
||||
@@ -78,11 +78,11 @@ import java.lang.reflect.Method;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractFallbackRequestAndResponseControlDirContextProcessor extends
|
||||
AbstractRequestControlDirContextProcessor {
|
||||
public abstract class AbstractFallbackRequestAndResponseControlDirContextProcessor
|
||||
extends AbstractRequestControlDirContextProcessor {
|
||||
|
||||
private static final boolean CRITICAL_CONTROL = true;
|
||||
|
||||
@@ -124,9 +124,7 @@ public abstract class AbstractFallbackRequestAndResponseControlDirContextProcess
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class of the expected ResponseControl for the sorted result
|
||||
* response.
|
||||
*
|
||||
* Set the class of the expected ResponseControl for the sorted result response.
|
||||
* @param responseControlClass Class of the expected response control.
|
||||
*/
|
||||
public void setResponseControlClass(Class<?> responseControlClass) {
|
||||
@@ -174,8 +172,7 @@ public abstract class AbstractFallbackRequestAndResponseControlDirContextProcess
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.ldap.core.DirContextProcessor#postProcess(javax.naming
|
||||
* @see org.springframework.ldap.core.DirContextProcessor#postProcess(javax.naming
|
||||
* .directory.DirContext)
|
||||
*/
|
||||
public void postProcess(DirContext ctx) throws NamingException {
|
||||
@@ -200,7 +197,6 @@ public abstract class AbstractFallbackRequestAndResponseControlDirContextProcess
|
||||
|
||||
/**
|
||||
* Set whether this control should be indicated as critical.
|
||||
*
|
||||
* @param critical whether the control is critical.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -209,4 +205,5 @@ public abstract class AbstractFallbackRequestAndResponseControlDirContextProcess
|
||||
}
|
||||
|
||||
protected abstract void handleResponse(Object control);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,25 +26,24 @@ import javax.naming.ldap.Control;
|
||||
import javax.naming.ldap.LdapContext;
|
||||
|
||||
/**
|
||||
* Abstract superclass with responsibility to apply a single RequestControl on
|
||||
* an LdapContext, preserving any existing controls. Subclasses should implement
|
||||
* Abstract superclass with responsibility to apply a single RequestControl on an
|
||||
* LdapContext, preserving any existing controls. Subclasses should implement
|
||||
* {@link DirContextProcessor#postProcess(DirContext)} and template method
|
||||
* {@link #createRequestControl()}.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public abstract class AbstractRequestControlDirContextProcessor implements DirContextProcessor {
|
||||
|
||||
protected Logger log = LoggerFactory.getLogger(AbstractRequestControlDirContextProcessor.class);
|
||||
|
||||
private boolean replaceSameControlEnabled = true;
|
||||
|
||||
/**
|
||||
* If there already exists a request control of the same class as the one
|
||||
* created by {@link #createRequestControl()} in the context, the new
|
||||
* control can either replace the existing one (default behavior) or be
|
||||
* added.
|
||||
*
|
||||
* If there already exists a request control of the same class as the one created by
|
||||
* {@link #createRequestControl()} in the context, the new control can either replace
|
||||
* the existing one (default behavior) or be added.
|
||||
* @return true if an already existing control will be replaced
|
||||
*/
|
||||
public boolean isReplaceSameControlEnabled() {
|
||||
@@ -52,13 +51,11 @@ public abstract class AbstractRequestControlDirContextProcessor implements DirCo
|
||||
}
|
||||
|
||||
/**
|
||||
* If there already exists a request control of the same class as the one
|
||||
* created by {@link #createRequestControl()} in the context, the new
|
||||
* control can either replace the existing one (default behavior) or be
|
||||
* added.
|
||||
*
|
||||
* @param replaceSameControlEnabled <code>true</code> if an already
|
||||
* existing control should be replaced
|
||||
* If there already exists a request control of the same class as the one created by
|
||||
* {@link #createRequestControl()} in the context, the new control can either replace
|
||||
* the existing one (default behavior) or be added.
|
||||
* @param replaceSameControlEnabled <code>true</code> if an already existing control
|
||||
* should be replaced
|
||||
*/
|
||||
public void setReplaceSameControlEnabled(boolean replaceSameControlEnabled) {
|
||||
this.replaceSameControlEnabled = replaceSameControlEnabled;
|
||||
@@ -66,19 +63,17 @@ public abstract class AbstractRequestControlDirContextProcessor implements DirCo
|
||||
|
||||
/**
|
||||
* Get the existing RequestControls from the LdapContext, call
|
||||
* {@link #createRequestControl()} to get a new instance, build a new array
|
||||
* of Controls and set it on the LdapContext.
|
||||
* {@link #createRequestControl()} to get a new instance, build a new array of
|
||||
* Controls and set it on the LdapContext.
|
||||
* <p>
|
||||
* The {@link Control} feature is specific for LDAP v3 and thus applies only
|
||||
* to {@link LdapContext}. However, the generic DirContextProcessor
|
||||
* mechanism used for calling <code>preProcess</code> and
|
||||
* <code>postProcess</code> uses DirContext, since it also works for LDAP
|
||||
* v2. This is the reason that DirContext has to be cast to a LdapContext.
|
||||
*
|
||||
* The {@link Control} feature is specific for LDAP v3 and thus applies only to
|
||||
* {@link LdapContext}. However, the generic DirContextProcessor mechanism used for
|
||||
* calling <code>preProcess</code> and <code>postProcess</code> uses DirContext, since
|
||||
* it also works for LDAP v2. This is the reason that DirContext has to be cast to a
|
||||
* LdapContext.
|
||||
* @param ctx an LdapContext instance.
|
||||
* @throws NamingException
|
||||
* @throws IllegalArgumentException if the supplied DirContext is not an
|
||||
* LdapContext.
|
||||
* @throws IllegalArgumentException if the supplied DirContext is not an LdapContext.
|
||||
*/
|
||||
public void preProcess(DirContext ctx) throws NamingException {
|
||||
LdapContext ldapContext;
|
||||
@@ -86,8 +81,8 @@ public abstract class AbstractRequestControlDirContextProcessor implements DirCo
|
||||
ldapContext = (LdapContext) ctx;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Request Control operations require LDAPv3 - "
|
||||
+ "Context must be of type LdapContext");
|
||||
throw new IllegalArgumentException(
|
||||
"Request Control operations require LDAPv3 - " + "Context must be of type LdapContext");
|
||||
}
|
||||
|
||||
Control[] requestControls = ldapContext.getRequestControls();
|
||||
@@ -115,8 +110,8 @@ public abstract class AbstractRequestControlDirContextProcessor implements DirCo
|
||||
|
||||
/**
|
||||
* Create an instance of the appropriate RequestControl.
|
||||
*
|
||||
* @return the new instance.
|
||||
*/
|
||||
public abstract Control createRequestControl();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package org.springframework.ldap.control;
|
||||
import org.springframework.ldap.NamingException;
|
||||
|
||||
/**
|
||||
* Thrown by an AbstractRequestControlDirContextProcessor when it cannot create
|
||||
* a request control.
|
||||
*
|
||||
* Thrown by an AbstractRequestControlDirContextProcessor when it cannot create a request
|
||||
* control.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
@@ -29,9 +29,7 @@ public class CreateControlFailedException extends NamingException {
|
||||
|
||||
/**
|
||||
* Create a new CreateControlFailedException.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public CreateControlFailedException(String msg) {
|
||||
super(msg);
|
||||
@@ -39,13 +37,11 @@ public class CreateControlFailedException extends NamingException {
|
||||
|
||||
/**
|
||||
* Create a new CreateControlFailedException.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
* @param cause
|
||||
* the root cause (if any)
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause (if any)
|
||||
*/
|
||||
public CreateControlFailedException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,9 +18,9 @@ package org.springframework.ldap.control;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Bean to encapsulate a result List and a {@link PagedResultsCookie} to use for
|
||||
* returning the results when using {@link PagedResultsRequestControl}.
|
||||
*
|
||||
* Bean to encapsulate a result List and a {@link PagedResultsCookie} to use for returning
|
||||
* the results when using {@link PagedResultsRequestControl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
* @deprecated
|
||||
@@ -32,13 +32,9 @@ public class PagedResult {
|
||||
private PagedResultsCookie cookie;
|
||||
|
||||
/**
|
||||
* Constructs a PagedResults using the supplied List and
|
||||
* {@link PagedResultsCookie}.
|
||||
*
|
||||
* @param resultList
|
||||
* the result list.
|
||||
* @param cookie
|
||||
* the cookie.
|
||||
* Constructs a PagedResults using the supplied List and {@link PagedResultsCookie}.
|
||||
* @param resultList the result list.
|
||||
* @param cookie the cookie.
|
||||
*/
|
||||
public PagedResult(List<?> resultList, PagedResultsCookie cookie) {
|
||||
this.resultList = resultList;
|
||||
@@ -47,7 +43,6 @@ public class PagedResult {
|
||||
|
||||
/**
|
||||
* Get the cookie.
|
||||
*
|
||||
* @return the cookie.
|
||||
*/
|
||||
public PagedResultsCookie getCookie() {
|
||||
@@ -56,7 +51,6 @@ public class PagedResult {
|
||||
|
||||
/**
|
||||
* Get the result list.
|
||||
*
|
||||
* @return the result list.
|
||||
*/
|
||||
public List<?> getResultList() {
|
||||
@@ -65,13 +59,17 @@ public class PagedResult {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
PagedResult that = (PagedResult) o;
|
||||
|
||||
if (cookie != null ? !cookie.equals(that.cookie) : that.cookie != null) return false;
|
||||
if (resultList != null ? !resultList.equals(that.resultList) : that.resultList != null) return false;
|
||||
if (cookie != null ? !cookie.equals(that.cookie) : that.cookie != null)
|
||||
return false;
|
||||
if (resultList != null ? !resultList.equals(that.resultList) : that.resultList != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -82,4 +80,5 @@ public class PagedResult {
|
||||
result = 31 * result + (cookie != null ? cookie.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,8 @@ import javax.naming.ldap.PagedResultsControl;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Wrapper class for the cookie returned when using the
|
||||
* {@link PagedResultsControl}.
|
||||
*
|
||||
* Wrapper class for the cookie returned when using the {@link PagedResultsControl}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
@@ -31,40 +30,42 @@ public class PagedResultsCookie {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param cookie
|
||||
* the cookie returned by a PagedResultsResponseControl.
|
||||
* @param cookie the cookie returned by a PagedResultsResponseControl.
|
||||
*/
|
||||
public PagedResultsCookie(byte[] cookie) {
|
||||
if (cookie != null) {
|
||||
this.cookie = Arrays.copyOf(cookie, cookie.length);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.cookie = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie.
|
||||
*
|
||||
* @return the cookie. This value may be <code>null</code>, indicating that there are no more requests,
|
||||
* or that the control wasn't supported by the server.
|
||||
* @return the cookie. This value may be <code>null</code>, indicating that there are
|
||||
* no more requests, or that the control wasn't supported by the server.
|
||||
*/
|
||||
public byte[] getCookie() {
|
||||
if (cookie != null) {
|
||||
return Arrays.copyOf(cookie, cookie.length);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
PagedResultsCookie that = (PagedResultsCookie) o;
|
||||
|
||||
if (!Arrays.equals(cookie, that.cookie)) return false;
|
||||
if (!Arrays.equals(cookie, that.cookie))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -73,4 +74,5 @@ public class PagedResultsCookie {
|
||||
public int hashCode() {
|
||||
return cookie != null ? Arrays.hashCode(cookie) : 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,15 +19,14 @@ package org.springframework.ldap.control;
|
||||
import javax.naming.ldap.Control;
|
||||
|
||||
/**
|
||||
* DirContextProcessor implementation for managing the paged results control.
|
||||
* Note that due to the internal workings of <code>LdapTemplate</code>, the
|
||||
* target connection is closed after each LDAP call. The PagedResults control
|
||||
* require the same connection be used for each call, which means we need to
|
||||
* make sure the target connection is never actually closed. There's basically
|
||||
* two ways of making this happen: use the <code>SingleContextSource</code>
|
||||
* implementation or make sure all calls happen within a single LDAP transaction
|
||||
* (using <code>ContextSourceTransactionManager</code>).
|
||||
*
|
||||
* DirContextProcessor implementation for managing the paged results control. Note that
|
||||
* due to the internal workings of <code>LdapTemplate</code>, the target connection is
|
||||
* closed after each LDAP call. The PagedResults control require the same connection be
|
||||
* used for each call, which means we need to make sure the target connection is never
|
||||
* actually closed. There's basically two ways of making this happen: use the
|
||||
* <code>SingleContextSource</code> implementation or make sure all calls happen within a
|
||||
* single LDAP transaction (using <code>ContextSourceTransactionManager</code>).
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
@@ -50,10 +49,8 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
private boolean more = true;
|
||||
|
||||
/**
|
||||
* Constructs a new instance. This constructor should be used when
|
||||
* performing the first paged search operation, when no other results have
|
||||
* been retrieved.
|
||||
*
|
||||
* Constructs a new instance. This constructor should be used when performing the
|
||||
* first paged search operation, when no other results have been retrieved.
|
||||
* @param pageSize the page size.
|
||||
*/
|
||||
public PagedResultsDirContextProcessor(int pageSize) {
|
||||
@@ -61,11 +58,9 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the supplied page size and cookie. The
|
||||
* cookie must be the exact same instance as received from a previous paged
|
||||
* results search, or <code>null</code> if it is the first in an operation
|
||||
* sequence.
|
||||
*
|
||||
* Constructs a new instance with the supplied page size and cookie. The cookie must
|
||||
* be the exact same instance as received from a previous paged results search, or
|
||||
* <code>null</code> if it is the first in an operation sequence.
|
||||
* @param pageSize the page size.
|
||||
* @param cookie the cookie, as received from a previous search.
|
||||
*/
|
||||
@@ -77,16 +72,15 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
defaultResponseControl = DEFAULT_RESPONSE_CONTROL;
|
||||
fallbackRequestControl = FALLBACK_REQUEST_CONTROL;
|
||||
fallbackResponseControl = FALLBACK_RESPONSE_CONTROL;
|
||||
|
||||
|
||||
loadControlClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cookie.
|
||||
*
|
||||
* @return the cookie. The cookie will always be set after at leas one query, however the actual cookie content
|
||||
* can be <code>null</code>, indicating that there are no more results, in which case {@link #hasMore()} will return
|
||||
* <code>false</code>.
|
||||
* @return the cookie. The cookie will always be set after at leas one query, however
|
||||
* the actual cookie content can be <code>null</code>, indicating that there are no
|
||||
* more results, in which case {@link #hasMore()} will return <code>false</code>.
|
||||
* @see #hasMore()
|
||||
*/
|
||||
public PagedResultsCookie getCookie() {
|
||||
@@ -95,7 +89,6 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
|
||||
/**
|
||||
* Get the page size.
|
||||
*
|
||||
* @return the page size.
|
||||
*/
|
||||
public int getPageSize() {
|
||||
@@ -103,10 +96,9 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total estimated number of entries that matches the issued search.
|
||||
* Note that this value is optional for the LDAP server to return, so it
|
||||
* does not always contain any valid data.
|
||||
*
|
||||
* Get the total estimated number of entries that matches the issued search. Note that
|
||||
* this value is optional for the LDAP server to return, so it does not always contain
|
||||
* any valid data.
|
||||
* @return the estimated result size, if returned from the server.
|
||||
*/
|
||||
public int getResultSize() {
|
||||
@@ -114,8 +106,7 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* @see org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* #createRequestControl()
|
||||
*/
|
||||
public Control createRequestControl() {
|
||||
@@ -124,15 +115,15 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
actualCookie = cookie.getCookie();
|
||||
}
|
||||
return super.createRequestControl(new Class<?>[] { int.class, byte[].class, boolean.class },
|
||||
new Object[] {pageSize, actualCookie, critical});
|
||||
new Object[] { pageSize, actualCookie, critical });
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether there are more results to retrieved. When there are no more results to retrieve,
|
||||
* this is indicated by a <code>null</code> cookie being returned from the server.
|
||||
* When this happen, the internal status will set to false.
|
||||
*
|
||||
* @return <code>true</code> if there are more results to retrieve, <code>false</code> otherwise.
|
||||
* Check whether there are more results to retrieved. When there are no more results
|
||||
* to retrieve, this is indicated by a <code>null</code> cookie being returned from
|
||||
* the server. When this happen, the internal status will set to false.
|
||||
* @return <code>true</code> if there are more results to retrieve, <code>false</code>
|
||||
* otherwise.
|
||||
* @since 2.0
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
@@ -146,10 +137,11 @@ public class PagedResultsDirContextProcessor extends AbstractFallbackRequestAndR
|
||||
*/
|
||||
protected void handleResponse(Object control) {
|
||||
byte[] result = (byte[]) invokeMethod("getCookie", responseControlClass, control);
|
||||
if(result == null) {
|
||||
if (result == null) {
|
||||
more = false;
|
||||
}
|
||||
this.cookie = new PagedResultsCookie(result);
|
||||
this.resultSize = (Integer) invokeMethod("getResultSize", responseControlClass, control);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,15 +28,14 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* DirContextProcessor implementation for managing the paged results control.
|
||||
* Note that due to the internal workings of <code>LdapTemplate</code>, the
|
||||
* target connection is closed after each LDAP call. The PagedResults control
|
||||
* require the same connection be used for each call, which means we need to
|
||||
* make sure the target connection is never actually closed. There's basically
|
||||
* two ways of making this happen: use the <code>SingleContextSource</code>
|
||||
* implementation or make sure all calls happen within a single LDAP transaction
|
||||
* (using <code>ContextSourceTransactionManager</code>).
|
||||
*
|
||||
* DirContextProcessor implementation for managing the paged results control. Note that
|
||||
* due to the internal workings of <code>LdapTemplate</code>, the target connection is
|
||||
* closed after each LDAP call. The PagedResults control require the same connection be
|
||||
* used for each call, which means we need to make sure the target connection is never
|
||||
* actually closed. There's basically two ways of making this happen: use the
|
||||
* <code>SingleContextSource</code> implementation or make sure all calls happen within a
|
||||
* single LDAP transaction (using <code>ContextSourceTransactionManager</code>).
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
* @deprecated Use PagedResultsDirContextProcessor instead.
|
||||
@@ -66,10 +65,8 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
private Class requestControlClass;
|
||||
|
||||
/**
|
||||
* Constructs a new instance. This constructor should be used when
|
||||
* performing the first paged search operation, when no other results have
|
||||
* been retrieved.
|
||||
*
|
||||
* Constructs a new instance. This constructor should be used when performing the
|
||||
* first paged search operation, when no other results have been retrieved.
|
||||
* @param pageSize the page size.
|
||||
*/
|
||||
public PagedResultsRequestControl(int pageSize) {
|
||||
@@ -77,11 +74,9 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the supplied page size and cookie. The
|
||||
* cookie must be the exact same instance as received from a previous paged
|
||||
* resullts search, or <code>null</code> if it is the first in an operation
|
||||
* sequence.
|
||||
*
|
||||
* Constructs a new instance with the supplied page size and cookie. The cookie must
|
||||
* be the exact same instance as received from a previous paged resullts search, or
|
||||
* <code>null</code> if it is the first in an operation sequence.
|
||||
* @param pageSize the page size.
|
||||
* @param cookie the cookie, as received from a previous search.
|
||||
*/
|
||||
@@ -114,7 +109,6 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
|
||||
/**
|
||||
* Get the cookie.
|
||||
*
|
||||
* @return the cookie.
|
||||
*/
|
||||
public PagedResultsCookie getCookie() {
|
||||
@@ -123,7 +117,6 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
|
||||
/**
|
||||
* Get the page size.
|
||||
*
|
||||
* @return the page size.
|
||||
*/
|
||||
public int getPageSize() {
|
||||
@@ -131,10 +124,9 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total estimated number of entries that matches the issued search.
|
||||
* Note that this value is optional for the LDAP server to return, so it
|
||||
* does not always contain any valid data.
|
||||
*
|
||||
* Get the total estimated number of entries that matches the issued search. Note that
|
||||
* this value is optional for the LDAP server to return, so it does not always contain
|
||||
* any valid data.
|
||||
* @return the estimated result size, if returned from the server.
|
||||
*/
|
||||
public int getResultSize() {
|
||||
@@ -142,9 +134,7 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class of the expected ResponseControl for the paged results
|
||||
* response.
|
||||
*
|
||||
* Set the class of the expected ResponseControl for the paged results response.
|
||||
* @param responseControlClass Class of the expected response control.
|
||||
*/
|
||||
public void setResponseControlClass(Class responseControlClass) {
|
||||
@@ -156,8 +146,7 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* @see org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* #createRequestControl()
|
||||
*/
|
||||
|
||||
@@ -166,16 +155,15 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
if (cookie != null) {
|
||||
actualCookie = cookie.getCookie();
|
||||
}
|
||||
Constructor constructor = ClassUtils.getConstructorIfAvailable(requestControlClass, new Class[] { int.class,
|
||||
byte[].class, boolean.class });
|
||||
Constructor constructor = ClassUtils.getConstructorIfAvailable(requestControlClass,
|
||||
new Class[] { int.class, byte[].class, boolean.class });
|
||||
if (constructor == null) {
|
||||
throw new IllegalArgumentException("Failed to find an appropriate RequestControl constructor");
|
||||
}
|
||||
|
||||
Control result = null;
|
||||
try {
|
||||
result = (Control) constructor.newInstance(pageSize, actualCookie,
|
||||
critical);
|
||||
result = (Control) constructor.newInstance(pageSize, actualCookie, critical);
|
||||
}
|
||||
catch (Exception e) {
|
||||
ReflectionUtils.handleReflectionException(e);
|
||||
@@ -185,8 +173,7 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.ldap.core.DirContextProcessor#postProcess(javax.naming
|
||||
* @see org.springframework.ldap.core.DirContextProcessor#postProcess(javax.naming
|
||||
* .directory.DirContext)
|
||||
*/
|
||||
|
||||
@@ -220,4 +207,5 @@ public class PagedResultsRequestControl extends AbstractRequestControlDirContext
|
||||
Method actualMethod = ReflectionUtils.findMethod(clazz, method);
|
||||
return ReflectionUtils.invokeMethod(actualMethod, control);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,10 +19,9 @@ package org.springframework.ldap.control;
|
||||
import javax.naming.ldap.Control;
|
||||
|
||||
/**
|
||||
* DirContextProcessor implementation for managing the SortControl. Note that
|
||||
* this class is stateful, so a new instance needs to be instantiated for each
|
||||
* new search.
|
||||
*
|
||||
* DirContextProcessor implementation for managing the SortControl. Note that this class
|
||||
* is stateful, so a new instance needs to be instantiated for each new search.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public class SortControlDirContextProcessor extends AbstractFallbackRequestAndResponseControlDirContextProcessor {
|
||||
@@ -52,7 +51,6 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
|
||||
/**
|
||||
* Constructs a new instance using the supplied sort key.
|
||||
*
|
||||
* @param sortKey the sort key, i.e. the attribute name to sort on.
|
||||
*/
|
||||
public SortControlDirContextProcessor(String sortKey) {
|
||||
@@ -71,9 +69,7 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
|
||||
/**
|
||||
* Check whether the returned values were actually sorted by the server.
|
||||
*
|
||||
* @return <code>true</code> if the result was sorted, <code>false</code>
|
||||
* otherwise.
|
||||
* @return <code>true</code> if the result was sorted, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isSorted() {
|
||||
return sorted;
|
||||
@@ -81,7 +77,6 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
|
||||
/**
|
||||
* Get the result code returned by the control.
|
||||
*
|
||||
* @return result code.
|
||||
*/
|
||||
public int getResultCode() {
|
||||
@@ -90,7 +85,6 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
|
||||
/**
|
||||
* Get the sort key.
|
||||
*
|
||||
* @return the sort key.
|
||||
*/
|
||||
public String getSortKey() {
|
||||
@@ -98,13 +92,12 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
}
|
||||
|
||||
/*
|
||||
* @see
|
||||
* org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* @see org.springframework.ldap.control.AbstractRequestControlDirContextProcessor
|
||||
* #createRequestControl()
|
||||
*/
|
||||
public Control createRequestControl() {
|
||||
return super.createRequestControl(new Class<?>[] { String[].class, boolean.class }, new Object[] {
|
||||
new String[] { sortKey }, critical});
|
||||
return super.createRequestControl(new Class<?>[] { String[].class, boolean.class },
|
||||
new Object[] { new String[] { sortKey }, critical });
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -116,4 +109,5 @@ public class SortControlDirContextProcessor extends AbstractFallbackRequestAndRe
|
||||
this.sorted = (Boolean) invokeMethod("isSorted", responseControlClass, control);
|
||||
this.resultCode = (Integer) invokeMethod("getResultCode", responseControlClass, control);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,19 +19,19 @@ package org.springframework.ldap.core;
|
||||
import javax.naming.directory.ModificationItem;
|
||||
|
||||
/**
|
||||
* Indicates that the implementing class is capable of keeping track of any
|
||||
* attribute modifications and return them as ModificationItems.
|
||||
*
|
||||
* Indicates that the implementing class is capable of keeping track of any attribute
|
||||
* modifications and return them as ModificationItems.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface AttributeModificationsAware {
|
||||
|
||||
/**
|
||||
* Creates an array of which attributes have been changed, added or removed
|
||||
* since the initialization of this object.
|
||||
*
|
||||
* Creates an array of which attributes have been changed, added or removed since the
|
||||
* initialization of this object.
|
||||
* @return an array of modification items.
|
||||
*/
|
||||
ModificationItem[] getModificationItems();
|
||||
|
||||
}
|
||||
|
||||
@@ -21,35 +21,31 @@ import javax.naming.NamingException;
|
||||
import javax.naming.directory.Attributes;
|
||||
|
||||
/**
|
||||
* An interface used by LdapTemplate for mapping LDAP Attributes to beans.
|
||||
* Implementions of this interface perform the actual work of extracting
|
||||
* results, but need not worry about exception handling. <code>NamingExceptions</code> will
|
||||
* be caught and handled correctly by the {@link LdapTemplate} class.
|
||||
* An interface used by LdapTemplate for mapping LDAP Attributes to beans. Implementions
|
||||
* of this interface perform the actual work of extracting results, but need not worry
|
||||
* about exception handling. <code>NamingExceptions</code> will be caught and handled
|
||||
* correctly by the {@link LdapTemplate} class.
|
||||
* <p>
|
||||
* Typically used in search methods of {@link LdapTemplate}.
|
||||
* <code>AttributeMapper</code> objects are normally stateless and thus
|
||||
* reusable; they are ideal for implementing attribute-mapping logic in one
|
||||
* place.
|
||||
* Typically used in search methods of {@link LdapTemplate}. <code>AttributeMapper</code>
|
||||
* objects are normally stateless and thus reusable; they are ideal for implementing
|
||||
* attribute-mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using a {@link ContextMapper} in stead.
|
||||
*
|
||||
*
|
||||
* @see LdapTemplate#search(Name, String, AttributesMapper)
|
||||
* @see LdapTemplate#lookup(Name, AttributesMapper)
|
||||
* @see ContextMapper
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface AttributesMapper<T> {
|
||||
|
||||
/**
|
||||
* Map Attributes to an object. The supplied attributes are the attributes
|
||||
* from a single SearchResult.
|
||||
*
|
||||
* @param attributes
|
||||
* attributes from a SearchResult.
|
||||
* Map Attributes to an object. The supplied attributes are the attributes from a
|
||||
* single SearchResult.
|
||||
* @param attributes attributes from a SearchResult.
|
||||
* @return an object built from the attributes.
|
||||
* @throws NamingException
|
||||
* if any error occurs mapping the attributes
|
||||
* @throws NamingException if any error occurs mapping the attributes
|
||||
*/
|
||||
T mapFromAttributes(Attributes attributes)
|
||||
throws NamingException;
|
||||
T mapFromAttributes(Attributes attributes) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -23,21 +23,20 @@ import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
/**
|
||||
* A CollectingNameClassPairCallbackHandler to wrap an {@link AttributesMapper}.
|
||||
* That is, the found object is extracted from the {@link Attributes} of each
|
||||
* {@link SearchResult}, and then passed to the specified
|
||||
* {@link AttributesMapper} for translation.
|
||||
*
|
||||
* A CollectingNameClassPairCallbackHandler to wrap an {@link AttributesMapper}. That is,
|
||||
* the found object is extracted from the {@link Attributes} of each {@link SearchResult},
|
||||
* and then passed to the specified {@link AttributesMapper} for translation.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
public class AttributesMapperCallbackHandler<T> extends CollectingNameClassPairCallbackHandler<T> {
|
||||
|
||||
private AttributesMapper<T> mapper;
|
||||
|
||||
/**
|
||||
* Constructs a new instance around the specified {@link AttributesMapper}.
|
||||
*
|
||||
* @param mapper the target mapper.
|
||||
*/
|
||||
public AttributesMapperCallbackHandler(AttributesMapper<T> mapper) {
|
||||
@@ -47,7 +46,6 @@ public class AttributesMapperCallbackHandler<T> extends CollectingNameClassPairC
|
||||
/**
|
||||
* Cast the NameClassPair to a SearchResult and pass its attributes to the
|
||||
* {@link AttributesMapper}.
|
||||
*
|
||||
* @param nameClassPair a <code> SearchResult</code> instance.
|
||||
* @return the Object returned from the mapper.
|
||||
*/
|
||||
@@ -65,4 +63,5 @@ public class AttributesMapperCallbackHandler<T> extends CollectingNameClassPairC
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,23 +18,21 @@ package org.springframework.ldap.core;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Callback interface to be used in the authentication methods in
|
||||
* {@link LdapOperations} for performing operations on individually
|
||||
* authenticated contexts.
|
||||
*
|
||||
* Callback interface to be used in the authentication methods in {@link LdapOperations}
|
||||
* for performing operations on individually authenticated contexts.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @since 1.3
|
||||
*/
|
||||
public interface AuthenticatedLdapEntryContextCallback {
|
||||
|
||||
/**
|
||||
* Perform some LDAP operation on the supplied authenticated
|
||||
* <code>DirContext</code> instance. The target context will be
|
||||
* automatically closed.
|
||||
*
|
||||
* @param ctx the <code>DirContext</code> instance to perform an operation
|
||||
* on.
|
||||
* @param ldapEntryIdentification the identification of the LDAP entry used
|
||||
* to authenticate the supplied <code>DirContext</code>.
|
||||
* Perform some LDAP operation on the supplied authenticated <code>DirContext</code>
|
||||
* instance. The target context will be automatically closed.
|
||||
* @param ctx the <code>DirContext</code> instance to perform an operation on.
|
||||
* @param ldapEntryIdentification the identification of the LDAP entry used to
|
||||
* authenticate the supplied <code>DirContext</code>.
|
||||
*/
|
||||
void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,24 +19,22 @@ package org.springframework.ldap.core;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Callback interface to be used in the authentication methods in
|
||||
* {@link LdapOperations} for performing operations on individually
|
||||
* authenticated contexts.
|
||||
* Callback interface to be used in the authentication methods in {@link LdapOperations}
|
||||
* for performing operations on individually authenticated contexts.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface AuthenticatedLdapEntryContextMapper<T> {
|
||||
|
||||
/**
|
||||
* Perform some LDAP operation on the supplied authenticated
|
||||
* <code>DirContext</code> instance. The target context will be
|
||||
* automatically closed.
|
||||
*
|
||||
* @param ctx the <code>DirContext</code> instance to perform an operation
|
||||
* on.
|
||||
* @param ldapEntryIdentification the identification of the LDAP entry used
|
||||
* to authenticate the supplied <code>DirContext</code>.
|
||||
* Perform some LDAP operation on the supplied authenticated <code>DirContext</code>
|
||||
* instance. The target context will be automatically closed.
|
||||
* @param ctx the <code>DirContext</code> instance to perform an operation on.
|
||||
* @param ldapEntryIdentification the identification of the LDAP entry used to
|
||||
* authenticate the supplied <code>DirContext</code>.
|
||||
* @return the result of the operation, if any.
|
||||
*/
|
||||
T mapWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
package org.springframework.ldap.core;
|
||||
|
||||
/**
|
||||
* Callback interface to be used in the authentication methods in
|
||||
* {@link LdapOperations} for performing operations when there
|
||||
* are authentication errors. Can be useful when the cause of the
|
||||
* authentication failure needs to be retrieved.
|
||||
* Callback interface to be used in the authentication methods in {@link LdapOperations}
|
||||
* for performing operations when there are authentication errors. Can be useful when the
|
||||
* cause of the authentication failure needs to be retrieved.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.3.1
|
||||
*/
|
||||
public interface AuthenticationErrorCallback {
|
||||
|
||||
/**
|
||||
* This method will be called with the authentication exception in
|
||||
* case there is a problem with the authentication.
|
||||
*
|
||||
* This method will be called with the authentication exception in case there is a
|
||||
* problem with the authentication.
|
||||
* @param e the exception that was caught in the authentication method
|
||||
*/
|
||||
void execute(Exception e);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
package org.springframework.ldap.core;
|
||||
|
||||
/**
|
||||
* An <code>AuthenticationSource</code> is responsible for providing the
|
||||
* principal (user DN) and credentials to be used when creating a new context.
|
||||
*
|
||||
* An <code>AuthenticationSource</code> is responsible for providing the principal (user
|
||||
* DN) and credentials to be used when creating a new context.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
*
|
||||
*/
|
||||
public interface AuthenticationSource {
|
||||
|
||||
/**
|
||||
* Get the principal to use when creating an authenticated context.
|
||||
*
|
||||
* @return the principal (userDn).
|
||||
*/
|
||||
String getPrincipal();
|
||||
|
||||
/**
|
||||
* Get the credentials to use when creating an authenticated context.
|
||||
*
|
||||
* @return the credentials (password).
|
||||
*/
|
||||
String getCredentials();
|
||||
|
||||
}
|
||||
|
||||
@@ -16,23 +16,23 @@
|
||||
package org.springframework.ldap.core;
|
||||
|
||||
/**
|
||||
* Convenience implementation of AuthenticationErrorCallback that stores the
|
||||
* given exception and provides a method for retrieving it. The caller of the
|
||||
* authenticate method can provide an instance of this class as an error
|
||||
* callback. If the authentication fails, the caller can ask the callback
|
||||
* instance for the actual authentication exception.
|
||||
*
|
||||
* Convenience implementation of AuthenticationErrorCallback that stores the given
|
||||
* exception and provides a method for retrieving it. The caller of the authenticate
|
||||
* method can provide an instance of this class as an error callback. If the
|
||||
* authentication fails, the caller can ask the callback instance for the actual
|
||||
* authentication exception.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.3.1
|
||||
*/
|
||||
public final class CollectingAuthenticationErrorCallback implements AuthenticationErrorCallback {
|
||||
|
||||
private Exception error;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.springframework.ldap.core.AuthenticationErrorCallback#execute(java
|
||||
*
|
||||
* @see org.springframework.ldap.core.AuthenticationErrorCallback#execute(java
|
||||
* .lang.Exception)
|
||||
*/
|
||||
public void execute(Exception e) {
|
||||
@@ -48,10 +48,11 @@ public final class CollectingAuthenticationErrorCallback implements Authenticati
|
||||
|
||||
/**
|
||||
* Check whether this callback has collected an error.
|
||||
*
|
||||
* @return <code>true</code> if an error has been collected, <code>false</code> otherwise.
|
||||
* @return <code>true</code> if an error has been collected, <code>false</code>
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean hasError() {
|
||||
return error != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,19 +22,16 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* A NameClassPairCallbackHandler to collect all results in an internal List.
|
||||
*
|
||||
*
|
||||
* @see LdapTemplate
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public abstract class CollectingNameClassPairCallbackHandler<T> implements
|
||||
NameClassPairCallbackHandler {
|
||||
public abstract class CollectingNameClassPairCallbackHandler<T> implements NameClassPairCallbackHandler {
|
||||
|
||||
private List<T> list = new LinkedList<T>();
|
||||
|
||||
/**
|
||||
* Get the assembled list.
|
||||
*
|
||||
* @return the list of all assembled objects.
|
||||
*/
|
||||
public List<T> getList() {
|
||||
@@ -43,22 +40,20 @@ public abstract class CollectingNameClassPairCallbackHandler<T> implements
|
||||
|
||||
/**
|
||||
* Pass on the supplied NameClassPair to
|
||||
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to
|
||||
* the internal list.
|
||||
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to the
|
||||
* internal list.
|
||||
*/
|
||||
public final void handleNameClassPair(NameClassPair nameClassPair) throws NamingException {
|
||||
list.add(getObjectFromNameClassPair(nameClassPair));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a NameClassPair and transform it to an Object of the desired type
|
||||
* and with data from the NameClassPair.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* a NameClassPair from a search operation.
|
||||
* Handle a NameClassPair and transform it to an Object of the desired type and with
|
||||
* data from the NameClassPair.
|
||||
* @param nameClassPair a NameClassPair from a search operation.
|
||||
* @return an object constructed from the data in the NameClassPair.
|
||||
* @throws NamingException if an error occurs.
|
||||
*/
|
||||
public abstract T getObjectFromNameClassPair(
|
||||
NameClassPair nameClassPair) throws NamingException;
|
||||
public abstract T getObjectFromNameClassPair(NameClassPair nameClassPair) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,20 +17,19 @@
|
||||
package org.springframework.ldap.core;
|
||||
|
||||
/**
|
||||
* Helper interface to be used by Dao implementations for assembling to and from
|
||||
* context. Useful if we have assembler classes responsible for mapping to and
|
||||
* from a specific entry.
|
||||
*
|
||||
* Helper interface to be used by Dao implementations for assembling to and from context.
|
||||
* Useful if we have assembler classes responsible for mapping to and from a specific
|
||||
* entry.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface ContextAssembler extends ContextMapper {
|
||||
|
||||
/**
|
||||
* Map the supplied object to the specified context.
|
||||
*
|
||||
* @param obj
|
||||
* the object to read data from.
|
||||
* @param ctx
|
||||
* the context to map to.
|
||||
* @param obj the object to read data from.
|
||||
* @param ctx the context to map to.
|
||||
*/
|
||||
void mapToContext(Object obj, Object ctx);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual operation to be performed on a
|
||||
* <code>DirContext</code>. For searches, use {@link SearchExecutor} in
|
||||
* stead. A typical usage of this interface could be e.g.:
|
||||
*
|
||||
* <code>DirContext</code>. For searches, use {@link SearchExecutor} in stead. A typical
|
||||
* usage of this interface could be e.g.:
|
||||
*
|
||||
* <pre>
|
||||
* ContextExecutor executor = new ContextExecutor() {
|
||||
* public Object executeWithContext(DirContext ctx) throws NamingException {
|
||||
@@ -30,21 +30,19 @@ import javax.naming.directory.DirContext;
|
||||
* }
|
||||
* };
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @see LdapTemplate#executeReadOnly(ContextExecutor)
|
||||
* @see LdapTemplate#executeReadWrite(ContextExecutor)
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface ContextExecutor<T> {
|
||||
|
||||
/**
|
||||
* Perform any operation on the context.
|
||||
*
|
||||
* @param ctx
|
||||
* the DirContext to perform the operation on.
|
||||
* @param ctx the DirContext to perform the operation on.
|
||||
* @return any object resulting from the operation - might be null.
|
||||
* @throws NamingException
|
||||
* if the operation resulted in one.
|
||||
* @throws NamingException if the operation resulted in one.
|
||||
*/
|
||||
T executeWithContext(DirContext ctx) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,18 +27,17 @@ import javax.naming.directory.SearchResult;
|
||||
/**
|
||||
* An interface used by LdapTemplate to map LDAP Contexts to beans. When a
|
||||
* DirObjectFactory is set on the ContextSource, the objects returned from
|
||||
* <code>search</code> and <code>listBindings</code> operations are
|
||||
* automatically transformed to DirContext objects (when using the
|
||||
* {@link DefaultDirObjectFactory} - which is typically the case, unless
|
||||
* something else has been explicitly specified - you get a
|
||||
* {@link DirContextAdapter} object). This object will then be passed to the
|
||||
* <code>search</code> and <code>listBindings</code> operations are automatically
|
||||
* transformed to DirContext objects (when using the {@link DefaultDirObjectFactory} -
|
||||
* which is typically the case, unless something else has been explicitly specified - you
|
||||
* get a {@link DirContextAdapter} object). This object will then be passed to the
|
||||
* ContextMapper implementation for transformation to the desired bean.
|
||||
* <p>
|
||||
* ContextMapper implementations are typically stateless and thus reusable; they
|
||||
* are ideal for implementing mapping logic in one place.
|
||||
* ContextMapper implementations are typically stateless and thus reusable; they are ideal
|
||||
* for implementing mapping logic in one place.
|
||||
* <p>
|
||||
* Alternatively, consider using an {@link AttributesMapper} in stead.
|
||||
*
|
||||
*
|
||||
* @see LdapTemplate#search(Name, String, ContextMapper)
|
||||
* @see LdapTemplate#listBindings(Name, ContextMapper)
|
||||
* @see LdapTemplate#lookup(Name, ContextMapper)
|
||||
@@ -46,22 +45,19 @@ import javax.naming.directory.SearchResult;
|
||||
* @see DefaultDirObjectFactory
|
||||
* @see DirContextAdapter
|
||||
* @see AbstractContextMapper
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface ContextMapper<T> {
|
||||
|
||||
/**
|
||||
* Map a single LDAP Context to an object. The supplied Object
|
||||
* <code>ctx</code> is the object from a single {@link SearchResult},
|
||||
* {@link Binding}, or a lookup operation.
|
||||
*
|
||||
* @param ctx
|
||||
* the context to map to an object. Typically this will be a
|
||||
* {@link DirContextAdapter} instance, unless a project specific
|
||||
* <code>DirObjectFactory</code> has been specified on the
|
||||
* <code>ContextSource</code>.
|
||||
* Map a single LDAP Context to an object. The supplied Object <code>ctx</code> is the
|
||||
* object from a single {@link SearchResult}, {@link Binding}, or a lookup operation.
|
||||
* @param ctx the context to map to an object. Typically this will be a
|
||||
* {@link DirContextAdapter} instance, unless a project specific
|
||||
* <code>DirObjectFactory</code> has been specified on the <code>ContextSource</code>.
|
||||
* @return an object built from the data in the context.
|
||||
* @throws NamingException if an error occurs.
|
||||
*/
|
||||
T mapFromContext(Object ctx) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -22,23 +22,21 @@ import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* A CollectingNameClassPairCallbackHandler to wrap a ContextMapper. That is,
|
||||
* the found object is extracted from each {@link Binding}, and then passed to
|
||||
* the specified ContextMapper for translation.
|
||||
*
|
||||
* A CollectingNameClassPairCallbackHandler to wrap a ContextMapper. That is, the found
|
||||
* object is extracted from each {@link Binding}, and then passed to the specified
|
||||
* ContextMapper for translation.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
public class ContextMapperCallbackHandler<T> extends
|
||||
CollectingNameClassPairCallbackHandler<T> {
|
||||
public class ContextMapperCallbackHandler<T> extends CollectingNameClassPairCallbackHandler<T> {
|
||||
|
||||
private ContextMapper<T> mapper;
|
||||
|
||||
/**
|
||||
* Constructs a new instance wrapping the supplied {@link ContextMapper}.
|
||||
*
|
||||
* @param mapper
|
||||
* the mapper to be called for each entry.
|
||||
* @param mapper the mapper to be called for each entry.
|
||||
*/
|
||||
public ContextMapperCallbackHandler(ContextMapper<T> mapper) {
|
||||
Assert.notNull(mapper, "Mapper must not be empty");
|
||||
@@ -46,11 +44,9 @@ public class ContextMapperCallbackHandler<T> extends
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the NameClassPair to a {@link Binding} and pass its object to
|
||||
* the ContextMapper.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* a Binding instance.
|
||||
* Cast the NameClassPair to a {@link Binding} and pass its object to the
|
||||
* ContextMapper.
|
||||
* @param nameClassPair a Binding instance.
|
||||
* @return the Object returned from the mapper.
|
||||
* @throws NamingException if an error occurs.
|
||||
* @throws ObjectRetrievalException if the object of the nameClassPair is null.
|
||||
@@ -63,9 +59,9 @@ public class ContextMapperCallbackHandler<T> extends
|
||||
Binding binding = (Binding) nameClassPair;
|
||||
Object object = binding.getObject();
|
||||
if (object == null) {
|
||||
throw new ObjectRetrievalException(
|
||||
"Binding did not contain any object.");
|
||||
throw new ObjectRetrievalException("Binding did not contain any object.");
|
||||
}
|
||||
return mapper.mapFromContext(object);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,22 +22,19 @@ import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* A <code>ContextSource</code> is responsible for configuring and creating
|
||||
* <code>DirContext</code> instances. It is typically used from
|
||||
* {@link LdapTemplate} to acquiring contexts for LDAP operations, but may be
|
||||
* used standalone to perform LDAP authentication.
|
||||
*
|
||||
* <code>DirContext</code> instances. It is typically used from {@link LdapTemplate} to
|
||||
* acquiring contexts for LDAP operations, but may be used standalone to perform LDAP
|
||||
* authentication.
|
||||
*
|
||||
* @see org.springframework.ldap.core.LdapTemplate
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface ContextSource {
|
||||
|
||||
/**
|
||||
* Gets a read-only <code>DirContext</code>. The returned
|
||||
* <code>DirContext</code> must be possible to perform read-only operations
|
||||
* on.
|
||||
*
|
||||
* Gets a read-only <code>DirContext</code>. The returned <code>DirContext</code> must
|
||||
* be possible to perform read-only operations on.
|
||||
* @return A DirContext instance, never null.
|
||||
* @throws NamingException if some error occurs creating an DirContext.
|
||||
*/
|
||||
@@ -45,27 +42,23 @@ public interface ContextSource {
|
||||
|
||||
/**
|
||||
* Gets a read-write <code>DirContext</code> instance.
|
||||
*
|
||||
* @return A <code>DirContext</code> instance, never <code>null</code>.
|
||||
* @throws NamingException if some error occurs creating an
|
||||
* <code>DirContext</code>.
|
||||
* @throws NamingException if some error occurs creating an <code>DirContext</code>.
|
||||
*/
|
||||
DirContext getReadWriteContext() throws NamingException;
|
||||
|
||||
/**
|
||||
* Gets a <code>DirContext</code> instance authenticated using the supplied
|
||||
* principal and credentials. Typically to be used for plain authentication
|
||||
* purposes. <strong>Note</strong> that this method will never make use
|
||||
* of native Java LDAP pooling, even though this instance is configured to do so.
|
||||
* This is to force password changes in the target directory to take effect
|
||||
* as soon as possible.
|
||||
*
|
||||
* @param principal The principal (typically a distinguished name of a user
|
||||
* in the LDAP tree) to use for authentication.
|
||||
* Gets a <code>DirContext</code> instance authenticated using the supplied principal
|
||||
* and credentials. Typically to be used for plain authentication purposes.
|
||||
* <strong>Note</strong> that this method will never make use of native Java LDAP
|
||||
* pooling, even though this instance is configured to do so. This is to force
|
||||
* password changes in the target directory to take effect as soon as possible.
|
||||
* @param principal The principal (typically a distinguished name of a user in the
|
||||
* LDAP tree) to use for authentication.
|
||||
* @param credentials The credentials to use for authentication.
|
||||
* @return an authenticated <code>DirContext</code> instance, never
|
||||
* <code>null</code>.
|
||||
* @return an authenticated <code>DirContext</code> instance, never <code>null</code>.
|
||||
* @since 1.3
|
||||
*/
|
||||
DirContext getContext(String principal, String credentials) throws NamingException;
|
||||
|
||||
}
|
||||
@@ -18,13 +18,14 @@ package org.springframework.ldap.core;
|
||||
import java.io.StringReader;
|
||||
|
||||
/**
|
||||
* A factory for creating DnParser instances. The actual implementation of
|
||||
* DnParser is generated using javacc and should not be constructed directly.
|
||||
*
|
||||
* A factory for creating DnParser instances. The actual implementation of DnParser is
|
||||
* generated using javacc and should not be constructed directly.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @deprecated {@link DistinguishedName} and associated classes are deprecated as of 2.0.
|
||||
*/
|
||||
public final class DefaultDnParserFactory {
|
||||
|
||||
/**
|
||||
* Not to be instantiated.
|
||||
*/
|
||||
@@ -34,12 +35,11 @@ public final class DefaultDnParserFactory {
|
||||
|
||||
/**
|
||||
* Create a new DnParser instance.
|
||||
*
|
||||
* @param string
|
||||
* the DN String to be parsed.
|
||||
* @param string the DN String to be parsed.
|
||||
* @return a new DnParser instance for parsing the supplied DN string.
|
||||
*/
|
||||
public static DnParser createDnParser(String string) {
|
||||
return new DnParserImpl(new StringReader(string));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ import org.springframework.util.Assert;
|
||||
* @since 3.1
|
||||
*/
|
||||
class DefaultLdapClient implements LdapClient {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(DefaultLdapClient.class);
|
||||
|
||||
private static final boolean DONT_RETURN_OBJ_FLAG = false;
|
||||
@@ -151,13 +152,13 @@ class DefaultLdapClient implements LdapClient {
|
||||
*/
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
return new DefaultLdapClientBuilder(this.contextSource, this.searchControlsSupplier);
|
||||
return new DefaultLdapClientBuilder(this.contextSource, this.searchControlsSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore {@link PartialResultException}s.
|
||||
*
|
||||
* @param ignorePartialResultException whether to ignore {@link PartialResultException}s
|
||||
* @param ignorePartialResultException whether to ignore
|
||||
* {@link PartialResultException}s
|
||||
*/
|
||||
void setIgnorePartialResultException(boolean ignorePartialResultException) {
|
||||
this.ignorePartialResultException = ignorePartialResultException;
|
||||
@@ -165,24 +166,23 @@ class DefaultLdapClient implements LdapClient {
|
||||
|
||||
/**
|
||||
* Ignore {@link NameNotFoundException}s.
|
||||
*
|
||||
* @param ignoreNameNotFoundException whether to ignore {@link NameNotFoundException}s
|
||||
*/
|
||||
void setIgnoreNameNotFoundException(boolean ignoreNameNotFoundException) {
|
||||
this.ignoreNameNotFoundException = ignoreNameNotFoundException;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore {@link SizeLimitExceededException}s.
|
||||
*
|
||||
* @param ignoreSizeLimitExceededException whether to ignore {@link SizeLimitExceededException}s
|
||||
* @param ignoreSizeLimitExceededException whether to ignore
|
||||
* {@link SizeLimitExceededException}s
|
||||
*/
|
||||
void setIgnoreSizeLimitExceededException(boolean ignoreSizeLimitExceededException) {
|
||||
this.ignoreSizeLimitExceededException = ignoreSizeLimitExceededException;
|
||||
}
|
||||
|
||||
private final class DefaultListSpec implements ListSpec {
|
||||
|
||||
private final Name name;
|
||||
|
||||
private DefaultListSpec(Name name) {
|
||||
@@ -202,9 +202,11 @@ class DefaultLdapClient implements LdapClient {
|
||||
NamingEnumeration<NameClassPair> results = computeWithReadOnlyContext(executor);
|
||||
return DefaultLdapClient.this.toStream(results, mapper::mapFromNameClassPair);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultListBindingsSpec implements ListBindingsSpec {
|
||||
|
||||
private final Name name;
|
||||
|
||||
private DefaultListBindingsSpec(Name name) {
|
||||
@@ -238,9 +240,11 @@ class DefaultLdapClient implements LdapClient {
|
||||
NamingEnumeration<Binding> results = computeWithReadOnlyContext(executor);
|
||||
return DefaultLdapClient.this.toStream(results, function(mapper));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultAuthenticateSpec implements AuthenticateSpec {
|
||||
|
||||
LdapClient.SearchSpec search = new DefaultSearchSpec();
|
||||
|
||||
char[] password;
|
||||
@@ -277,14 +281,17 @@ class DefaultLdapClient implements LdapClient {
|
||||
String password = (this.password != null) ? new String(this.password) : null;
|
||||
ctx = contextSource.getContext(identification.get(0).getAbsoluteName().toString(), password);
|
||||
return mapper.mapWithContext(ctx, identification.get(0));
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
this.password = null;
|
||||
closeContext(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultSearchSpec implements SearchSpec {
|
||||
|
||||
LdapQuery query = LdapQueryBuilder.query().filter("(objectClass=*)");
|
||||
|
||||
SearchControls controls;
|
||||
@@ -373,12 +380,17 @@ class DefaultLdapClient implements LdapClient {
|
||||
}
|
||||
return controls;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultBindSpec implements BindSpec {
|
||||
|
||||
private final Name name;
|
||||
|
||||
private Object obj;
|
||||
|
||||
private Attributes attributes;
|
||||
|
||||
private boolean rebind = false;
|
||||
|
||||
private DefaultBindSpec(Name name) {
|
||||
@@ -409,15 +421,20 @@ class DefaultLdapClient implements LdapClient {
|
||||
public void execute() {
|
||||
if (this.rebind) {
|
||||
runWithReadWriteContext((ctx) -> ctx.rebind(this.name, this.obj, this.attributes));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
runWithReadWriteContext((ctx) -> ctx.bind(this.name, this.obj, this.attributes));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultModifySpec implements ModifySpec {
|
||||
|
||||
private final DirContextOperations entry;
|
||||
|
||||
private Name name;
|
||||
|
||||
private ModificationItem[] items;
|
||||
|
||||
private DefaultModifySpec(DirContextOperations entry) {
|
||||
@@ -455,7 +472,8 @@ class DefaultLdapClient implements LdapClient {
|
||||
if (this.items.length > 0) {
|
||||
runWithReadWriteContext((ctx) -> ctx.modifyAttributes(this.name, this.items));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
catch (Throwable t) {
|
||||
if (renamed) {
|
||||
// attempt to change the name back
|
||||
runWithReadWriteContext((ctx) -> ctx.rename(this.name, this.entry.getDn()));
|
||||
@@ -463,10 +481,13 @@ class DefaultLdapClient implements LdapClient {
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final class DefaultUnbindSpec implements UnbindSpec {
|
||||
|
||||
private final Name name;
|
||||
|
||||
private boolean recursive = false;
|
||||
|
||||
private DefaultUnbindSpec(Name name) {
|
||||
@@ -502,20 +523,24 @@ class DefaultLdapClient implements LdapClient {
|
||||
if (DefaultLdapClient.this.logger.isDebugEnabled()) {
|
||||
DefaultLdapClient.this.logger.debug("Entry " + name + " deleted");
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
closeNamingEnumeration(bindings);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
<T> T computeWithReadOnlyContext(ContextExecutor<T> executor) {
|
||||
DirContext context = this.contextSource.getReadOnlyContext();
|
||||
try {
|
||||
return executor.executeWithContext(context);
|
||||
} catch (NamingException ex) {
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
this.namingExceptionHandler.accept(ex);
|
||||
return null;
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
closeContext(context);
|
||||
}
|
||||
}
|
||||
@@ -524,9 +549,11 @@ class DefaultLdapClient implements LdapClient {
|
||||
DirContext context = this.contextSource.getReadWriteContext();
|
||||
try {
|
||||
runnable.run(context);
|
||||
} catch (NamingException ex) {
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
this.namingExceptionHandler.accept(ex);
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
closeContext(context);
|
||||
}
|
||||
}
|
||||
@@ -545,7 +572,8 @@ class DefaultLdapClient implements LdapClient {
|
||||
public boolean hasMoreElements() {
|
||||
try {
|
||||
return enumeration.hasMore();
|
||||
} catch (NamingException ex) {
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
namingExceptionHandler.accept(ex);
|
||||
return false;
|
||||
}
|
||||
@@ -555,7 +583,8 @@ class DefaultLdapClient implements LdapClient {
|
||||
public T nextElement() {
|
||||
try {
|
||||
return enumeration.next();
|
||||
} catch (NamingException ex) {
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
namingExceptionHandler.accept(ex);
|
||||
throw new NoSuchElementException("no such element", ex);
|
||||
}
|
||||
@@ -589,7 +618,8 @@ class DefaultLdapClient implements LdapClient {
|
||||
throw LdapUtils.convertLdapException(ex);
|
||||
};
|
||||
|
||||
private <S extends NameClassPair, T> T toObject(NamingEnumeration<S> results, NamingExceptionFunction<? super S, T> mapper) {
|
||||
private <S extends NameClassPair, T> T toObject(NamingEnumeration<S> results,
|
||||
NamingExceptionFunction<? super S, T> mapper) {
|
||||
try {
|
||||
Enumeration<S> enumeration = enumeration(results);
|
||||
Function<? super S, T> function = mapper.wrap(this.namingExceptionHandler);
|
||||
@@ -601,12 +631,14 @@ class DefaultLdapClient implements LdapClient {
|
||||
throw new IncorrectResultSizeDataAccessException(1);
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
closeNamingEnumeration(results);
|
||||
}
|
||||
}
|
||||
|
||||
private <S extends NameClassPair, T> List<T> toList(NamingEnumeration<S> results, NamingExceptionFunction<? super S, T> mapper) {
|
||||
private <S extends NameClassPair, T> List<T> toList(NamingEnumeration<S> results,
|
||||
NamingExceptionFunction<? super S, T> mapper) {
|
||||
if (results == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -621,20 +653,22 @@ class DefaultLdapClient implements LdapClient {
|
||||
}
|
||||
}
|
||||
return mapped;
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
closeNamingEnumeration(results);
|
||||
}
|
||||
}
|
||||
|
||||
private <S extends NameClassPair, T> Stream<T> toStream(NamingEnumeration<S> results, NamingExceptionFunction<? super S, T> mapper) {
|
||||
private <S extends NameClassPair, T> Stream<T> toStream(NamingEnumeration<S> results,
|
||||
NamingExceptionFunction<? super S, T> mapper) {
|
||||
if (results == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
Enumeration<S> enumeration = enumeration(results);
|
||||
Function<? super S, T> function = mapper.wrap(this.namingExceptionHandler);
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(enumeration.asIterator(), Spliterator.ORDERED), false)
|
||||
.map(function::apply).filter(Objects::nonNull)
|
||||
.onClose(() -> closeNamingEnumeration(results));
|
||||
return StreamSupport
|
||||
.stream(Spliterators.spliteratorUnknownSize(enumeration.asIterator(), Spliterator.ORDERED), false)
|
||||
.map(function::apply).filter(Objects::nonNull).onClose(() -> closeNamingEnumeration(results));
|
||||
}
|
||||
|
||||
private void closeContext(DirContext ctx) {
|
||||
@@ -660,22 +694,27 @@ class DefaultLdapClient implements LdapClient {
|
||||
}
|
||||
|
||||
interface ContextRunnable {
|
||||
|
||||
void run(DirContext ctx) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
interface NamingExceptionFunction<S, T> {
|
||||
|
||||
T apply(S element) throws NamingException;
|
||||
|
||||
default Function<S, T> wrap(Consumer<NamingException> handler) {
|
||||
return (s) -> {
|
||||
try {
|
||||
return apply(s);
|
||||
} catch (NamingException ex) {
|
||||
}
|
||||
catch (NamingException ex) {
|
||||
handler.accept(ex);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.function.Supplier;
|
||||
import javax.naming.directory.SearchControls;
|
||||
|
||||
class DefaultLdapClientBuilder implements LdapClient.Builder {
|
||||
|
||||
private ContextSource contextSource;
|
||||
|
||||
private Supplier<SearchControls> searchControlsSupplier = () -> {
|
||||
@@ -22,10 +23,10 @@ class DefaultLdapClientBuilder implements LdapClient.Builder {
|
||||
|
||||
private boolean ignoreSizeLimitExceededException = true;
|
||||
|
||||
DefaultLdapClientBuilder() {}
|
||||
DefaultLdapClientBuilder() {
|
||||
}
|
||||
|
||||
DefaultLdapClientBuilder(ContextSource contextSource,
|
||||
Supplier<SearchControls> searchControlsSupplier) {
|
||||
DefaultLdapClientBuilder(ContextSource contextSource, Supplier<SearchControls> searchControlsSupplier) {
|
||||
this.contextSource = contextSource;
|
||||
this.searchControlsSupplier = searchControlsSupplier;
|
||||
}
|
||||
@@ -88,4 +89,5 @@ class DefaultLdapClientBuilder implements LdapClient.Builder {
|
||||
client.setIgnoreNameNotFoundException(this.ignoreNameNotFoundException);
|
||||
return client;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,26 +20,21 @@ import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* The default NameClassPairMapper implementation. This implementation simply
|
||||
* takes the Name string from the supplied NameClassPair and returns it as
|
||||
* result.
|
||||
*
|
||||
* The default NameClassPairMapper implementation. This implementation simply takes the
|
||||
* Name string from the supplied NameClassPair and returns it as result.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DefaultNameClassPairMapper implements NameClassPairMapper<String> {
|
||||
|
||||
/**
|
||||
* Gets the Name from the supplied NameClassPair and returns it as the
|
||||
* result.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair to transform.
|
||||
* Gets the Name from the supplied NameClassPair and returns it as the result.
|
||||
* @param nameClassPair the NameClassPair to transform.
|
||||
* @return the Name string from the NameClassPair.
|
||||
*/
|
||||
@Override
|
||||
public String mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException {
|
||||
public String mapFromNameClassPair(NameClassPair nameClassPair) throws NamingException {
|
||||
|
||||
return nameClassPair.getName();
|
||||
}
|
||||
|
||||
@@ -46,38 +46,37 @@ import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Adapter that implements the interesting methods of the DirContext interface.
|
||||
* In particular it contains utility methods for getting and setting attributes.
|
||||
* Using the
|
||||
* Adapter that implements the interesting methods of the DirContext interface. In
|
||||
* particular it contains utility methods for getting and setting attributes. Using the
|
||||
* {@link org.springframework.ldap.core.support.DefaultDirObjectFactory} in your
|
||||
* <code>ContextSource</code> (which is the default) you will receive instances
|
||||
* of this class from searches and lookups. This can be particularly useful when
|
||||
* updating data, since this class implements
|
||||
* {@link AttributeModificationsAware}, providing a
|
||||
* {@link #getModificationItems()} method. When in update mode, an object of
|
||||
* this class keeps track of the changes made to its attributes, making them
|
||||
* available as an array of <code>ModificationItem</code> objects, suitable as
|
||||
* input to {@link LdapTemplate#modifyAttributes(DirContextOperations)}.
|
||||
* <code>ContextSource</code> (which is the default) you will receive instances of this
|
||||
* class from searches and lookups. This can be particularly useful when updating data,
|
||||
* since this class implements {@link AttributeModificationsAware}, providing a
|
||||
* {@link #getModificationItems()} method. When in update mode, an object of this class
|
||||
* keeps track of the changes made to its attributes, making them available as an array of
|
||||
* <code>ModificationItem</code> objects, suitable as input to
|
||||
* {@link LdapTemplate#modifyAttributes(DirContextOperations)}.
|
||||
*
|
||||
* <p>
|
||||
* This class is aware of the specifics of {@link Name} instances with regards
|
||||
* to equality when working with attribute values. This comes in very handy
|
||||
* when working with e.g. security groups and modifications of them. If
|
||||
* {@link Name} instances are supplied to one of the Attribute manipulation
|
||||
* methods (e.g. {@link #addAttributeValue(String, Object)},
|
||||
* {@link #removeAttributeValue(String, Object)}, {@link #setAttributeValue(String, Object)},
|
||||
* or {@link #setAttributeValues(String, Object[])}), the produced modifications
|
||||
* will be calculated using {@link Name} equality. This means that if an the <code>member</code>
|
||||
* has a value of <code>"cn=John Doe,ou=People"</code>, and we call
|
||||
* <code>addAttributeValue("member", LdapUtils.newLdapName("CN=John Doe,OU=People")</code>,
|
||||
* this will <strong>not</strong> be considered a modification since the two DN
|
||||
* strings represent the same distinguished name (case and spacing between attributes is
|
||||
* disregarded).
|
||||
* This class is aware of the specifics of {@link Name} instances with regards to equality
|
||||
* when working with attribute values. This comes in very handy when working with e.g.
|
||||
* security groups and modifications of them. If {@link Name} instances are supplied to
|
||||
* one of the Attribute manipulation methods (e.g.
|
||||
* {@link #addAttributeValue(String, Object)},
|
||||
* {@link #removeAttributeValue(String, Object)},
|
||||
* {@link #setAttributeValue(String, Object)}, or
|
||||
* {@link #setAttributeValues(String, Object[])}), the produced modifications will be
|
||||
* calculated using {@link Name} equality. This means that if an the <code>member</code>
|
||||
* has a value of <code>"cn=John Doe,ou=People"</code>, and we call
|
||||
* <code>addAttributeValue("member", LdapUtils.newLdapName("CN=John Doe,OU=People")</code>,
|
||||
* this will <strong>not</strong> be considered a modification since the two DN strings
|
||||
* represent the same distinguished name (case and spacing between attributes is
|
||||
* disregarded).
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that this is not a complete implementation of DirContext. Several
|
||||
* methods are not relevant for the intended usage of this class, so they
|
||||
* throw UnsupportOperationException.
|
||||
* Note that this is not a complete implementation of DirContext. Several methods are not
|
||||
* relevant for the intended usage of this class, so they throw
|
||||
* UnsupportOperationException.
|
||||
* </p>
|
||||
*
|
||||
* @see #setAttributeValue(String, Object)
|
||||
@@ -89,7 +88,6 @@ import java.util.TreeSet;
|
||||
* @see #removeAttributeValue(String, Object)
|
||||
* @see #setUpdateMode(boolean)
|
||||
* @see #isUpdateMode()
|
||||
*
|
||||
* @author Magnus Robertsson
|
||||
* @author Andreas Ronge
|
||||
* @author Adam Skogman
|
||||
@@ -102,6 +100,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
private static final String EMPTY_STRING = "";
|
||||
|
||||
private static final boolean ORDER_DOESNT_MATTER = false;
|
||||
|
||||
private static final String NOT_IMPLEMENTED = "Not implemented.";
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(DirContextAdapter.class);
|
||||
@@ -127,8 +126,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Create a new DirContextAdapter from the supplied DN String.
|
||||
* @param dnString the DN string. Must be syntactically correct, or an
|
||||
* exception will be thrown.
|
||||
* @param dnString the DN string. Must be syntactically correct, or an exception will
|
||||
* be thrown.
|
||||
*/
|
||||
public DirContextAdapter(String dnString) {
|
||||
this(LdapUtils.newLdapName(dnString));
|
||||
@@ -136,7 +135,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Create a new adapter from the supplied dn.
|
||||
*
|
||||
* @param dn the dn.
|
||||
*/
|
||||
public DirContextAdapter(Name dn) {
|
||||
@@ -145,7 +143,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Create a new adapter from the supplied attributes and dn.
|
||||
*
|
||||
* @param attrs the attributes.
|
||||
* @param dn the dn.
|
||||
*/
|
||||
@@ -155,7 +152,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Create a new adapter from the supplied attributes, dn, and base.
|
||||
*
|
||||
* @param attrs the attributes.
|
||||
* @param dn the dn.
|
||||
* @param base the base name.
|
||||
@@ -165,16 +161,13 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new adapter from the supplied attributes, dn, base, and referral
|
||||
* url.
|
||||
* Create a new adapter from the supplied attributes, dn, base, and referral url.
|
||||
* @param attrs the attributes.
|
||||
* @param dn the dn.
|
||||
* @param base the base.
|
||||
* @param referralUrl the referral url (if this instance results from a
|
||||
* referral).
|
||||
* @param referralUrl the referral url (if this instance results from a referral).
|
||||
*/
|
||||
public DirContextAdapter(Attributes attrs, Name dn, Name base,
|
||||
String referralUrl) {
|
||||
public DirContextAdapter(Attributes attrs, Name dn, Name base, String referralUrl) {
|
||||
if (attrs != null) {
|
||||
this.originalAttrs = new NameAwareAttributes(attrs);
|
||||
}
|
||||
@@ -205,7 +198,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Constructor for cloning an existing adapter.
|
||||
*
|
||||
* @param main The adapter to be copied.
|
||||
*/
|
||||
protected DirContextAdapter(DirContextAdapter main) {
|
||||
@@ -216,10 +208,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the update mode. The update mode should be <code>false</code> for a
|
||||
* new entry and <code>true</code> for an existing entry that is being
|
||||
* updated.
|
||||
*
|
||||
* Sets the update mode. The update mode should be <code>false</code> for a new entry
|
||||
* and <code>true</code> for an existing entry that is being updated.
|
||||
* @param mode Update mode.
|
||||
*/
|
||||
public void setUpdateMode(boolean mode) {
|
||||
@@ -255,8 +245,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
try {
|
||||
while (attributesEnumeration.hasMore()) {
|
||||
Attribute oneAttribute = attributesEnumeration
|
||||
.next();
|
||||
Attribute oneAttribute = attributesEnumeration.next();
|
||||
tmpList.add(oneAttribute.getID());
|
||||
}
|
||||
}
|
||||
@@ -317,28 +306,27 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect all modifications for the changed attribute. If no changes have
|
||||
* been made, return immediately. If modifications have been made, and the
|
||||
* original size as well as the updated size of the attribute is 1, replace
|
||||
* the attribute. If the size of the updated attribute is 0, remove the
|
||||
* attribute. Otherwise, the attribute is a multi-value attribute; if it's
|
||||
* an ordered one it should be replaced in its entirety to preserve the new
|
||||
* ordering, if not all modifications to the original value (removals and
|
||||
* additions) will be collected individually.
|
||||
*
|
||||
* Collect all modifications for the changed attribute. If no changes have been made,
|
||||
* return immediately. If modifications have been made, and the original size as well
|
||||
* as the updated size of the attribute is 1, replace the attribute. If the size of
|
||||
* the updated attribute is 0, remove the attribute. Otherwise, the attribute is a
|
||||
* multi-value attribute; if it's an ordered one it should be replaced in its entirety
|
||||
* to preserve the new ordering, if not all modifications to the original value
|
||||
* (removals and additions) will be collected individually.
|
||||
* @param changedAttr the value of the changed attribute.
|
||||
* @param modificationList the list in which to add the modifications.
|
||||
* @throws NamingException if thrown by called Attribute methods.
|
||||
*/
|
||||
private void collectModifications(NameAwareAttribute changedAttr,
|
||||
List<ModificationItem> modificationList) throws NamingException {
|
||||
private void collectModifications(NameAwareAttribute changedAttr, List<ModificationItem> modificationList)
|
||||
throws NamingException {
|
||||
NameAwareAttribute currentAttribute = originalAttrs.get(changedAttr.getID());
|
||||
if(currentAttribute != null && changedAttr.hasValuesAsNames()) {
|
||||
if (currentAttribute != null && changedAttr.hasValuesAsNames()) {
|
||||
try {
|
||||
currentAttribute.initValuesAsNames();
|
||||
} catch(IllegalArgumentException e) {
|
||||
log.warn("Incompatible attributes; changed attribute has Name values but " +
|
||||
"original cannot be converted to this");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
log.warn("Incompatible attributes; changed attribute has Name values but "
|
||||
+ "original cannot be converted to this");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,29 +334,23 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
// No changes
|
||||
return;
|
||||
}
|
||||
else if (currentAttribute != null && currentAttribute.size() == 1
|
||||
&& changedAttr.size() == 1) {
|
||||
else if (currentAttribute != null && currentAttribute.size() == 1 && changedAttr.size() == 1) {
|
||||
// Replace single-vale attribute.
|
||||
modificationList.add(new ModificationItem(
|
||||
DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
}
|
||||
else if (changedAttr.size() == 0 && currentAttribute != null) {
|
||||
// Attribute has been removed.
|
||||
modificationList.add(new ModificationItem(
|
||||
DirContext.REMOVE_ATTRIBUTE, changedAttr));
|
||||
modificationList.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, changedAttr));
|
||||
}
|
||||
else if ((currentAttribute == null || currentAttribute.size() == 0)
|
||||
&& changedAttr.size() > 0) {
|
||||
else if ((currentAttribute == null || currentAttribute.size() == 0) && changedAttr.size() > 0) {
|
||||
// Attribute has been added.
|
||||
modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE,
|
||||
changedAttr));
|
||||
modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, changedAttr));
|
||||
}
|
||||
else if (changedAttr.size() > 0 && changedAttr.isOrdered()) {
|
||||
// This is a multivalue attribute and it is ordered - the original
|
||||
// value should be replaced with the new values so that the ordering
|
||||
// is preserved.
|
||||
modificationList.add(new ModificationItem(
|
||||
DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
}
|
||||
else if (changedAttr.size() > 0) {
|
||||
// Change of multivalue Attribute. Collect additions and removals
|
||||
@@ -380,24 +362,21 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
// This means that the attributes are not equal, but the
|
||||
// actual values are the same - thus the order must have
|
||||
// changed. This should result in a REPLACE_ATTRIBUTE operation.
|
||||
myModifications.add(new ModificationItem(
|
||||
DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
myModifications.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr));
|
||||
}
|
||||
|
||||
modificationList.addAll(myModifications);
|
||||
}
|
||||
}
|
||||
|
||||
private void collectModifications(Attribute originalAttr,
|
||||
Attribute changedAttr, List<ModificationItem> modificationList)
|
||||
throws NamingException {
|
||||
private void collectModifications(Attribute originalAttr, Attribute changedAttr,
|
||||
List<ModificationItem> modificationList) throws NamingException {
|
||||
|
||||
Attribute originalClone = (Attribute) originalAttr.clone();
|
||||
Attribute addedValuesAttribute = new NameAwareAttribute(originalAttr
|
||||
.getID());
|
||||
Attribute addedValuesAttribute = new NameAwareAttribute(originalAttr.getID());
|
||||
|
||||
NamingEnumeration<?> allValues = changedAttr.getAll();
|
||||
while(allValues.hasMoreElements()) {
|
||||
while (allValues.hasMoreElements()) {
|
||||
Object attributeValue = allValues.nextElement();
|
||||
if (!originalClone.remove(attributeValue)) {
|
||||
addedValuesAttribute.add(attributeValue);
|
||||
@@ -407,28 +386,25 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
// We have now traversed and removed all values from the original that
|
||||
// were also present in the new values. The remaining values in the
|
||||
// original must be the ones that were removed.
|
||||
if(originalClone.size() > 0 && originalClone.size() == originalAttr.size()) {
|
||||
if (originalClone.size() > 0 && originalClone.size() == originalAttr.size()) {
|
||||
// This is actually a complete replacement of the attribute values.
|
||||
// Fall back to REPLACE
|
||||
modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
|
||||
addedValuesAttribute));
|
||||
} else {
|
||||
modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, addedValuesAttribute));
|
||||
}
|
||||
else {
|
||||
if (originalClone.size() > 0) {
|
||||
modificationList.add(new ModificationItem(
|
||||
DirContext.REMOVE_ATTRIBUTE, originalClone));
|
||||
modificationList.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, originalClone));
|
||||
}
|
||||
|
||||
if (addedValuesAttribute.size() > 0) {
|
||||
modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE,
|
||||
addedValuesAttribute));
|
||||
modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, addedValuesAttribute));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if the attribute is empty. It is empty if a == null, size ==
|
||||
* 0 or get() == null or an exception if thrown when accessing the get
|
||||
* method
|
||||
* returns true if the attribute is empty. It is empty if a == null, size == 0 or
|
||||
* get() == null or an exception if thrown when accessing the get method
|
||||
*/
|
||||
private boolean isEmptyAttribute(Attribute a) {
|
||||
try {
|
||||
@@ -440,21 +416,18 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the existing attribute <code>name</code> with the values on the
|
||||
* array <code>values</code>. The order of the array must be the same order
|
||||
* as the existing multivalued attribute.
|
||||
* Compare the existing attribute <code>name</code> with the values on the array
|
||||
* <code>values</code>. The order of the array must be the same order as the existing
|
||||
* multivalued attribute.
|
||||
* <p>
|
||||
* Also handles the case where the values have been reset to the original
|
||||
* values after a previous change. For example, changing
|
||||
* <code>[a,b,c]</code> to <code>[a,b]</code> and then back to
|
||||
* <code>[a,b,c]</code> again must result in this method returning
|
||||
* <code>true</code> so the first change can be overwritten with the latest
|
||||
* change.
|
||||
*
|
||||
* Also handles the case where the values have been reset to the original values after
|
||||
* a previous change. For example, changing <code>[a,b,c]</code> to <code>[a,b]</code>
|
||||
* and then back to <code>[a,b,c]</code> again must result in this method returning
|
||||
* <code>true</code> so the first change can be overwritten with the latest change.
|
||||
* @param name Name of the original multi-valued attribute.
|
||||
* @param values Array of values to check if they have been changed.
|
||||
* @return true if there has been a change compared to original attribute,
|
||||
* or a previous update
|
||||
* @return true if there has been a change compared to original attribute, or a
|
||||
* previous update
|
||||
*/
|
||||
private boolean isChanged(String name, Object[] values, boolean orderMatters) {
|
||||
|
||||
@@ -533,9 +506,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Checks if an entry has a specific attribute.
|
||||
*
|
||||
*
|
||||
* This method simply calls exists(String) with the attribute name.
|
||||
*
|
||||
* @param attr the attribute to check.
|
||||
* @return true if attribute exists in entry.
|
||||
*/
|
||||
@@ -544,9 +516,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the attribute exists in this entry, either it was read or it
|
||||
* has been added and update() has been called.
|
||||
*
|
||||
* Checks if the attribute exists in this entry, either it was read or it has been
|
||||
* added and update() has been called.
|
||||
* @param attrId id of the attribute to check.
|
||||
* @return true if the attribute exists in the entry.
|
||||
*/
|
||||
@@ -621,8 +592,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void addAttributeValue(String name, Object value,
|
||||
boolean addIfDuplicateExists) {
|
||||
public void addAttributeValue(String name, Object value, boolean addIfDuplicateExists) {
|
||||
if (!updateMode && value != null) {
|
||||
Attribute attr = originalAttrs.get(name);
|
||||
if (attr == null) {
|
||||
@@ -697,8 +667,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setAttributeValues(String name, Object[] values,
|
||||
boolean orderMatters) {
|
||||
public void setAttributeValues(String name, Object[] values, boolean orderMatters) {
|
||||
Attribute a = new NameAwareAttribute(name, orderMatters);
|
||||
|
||||
for (int i = 0; values != null && i < values.length; i++) {
|
||||
@@ -806,7 +775,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Set the supplied attribute.
|
||||
*
|
||||
* @param attribute the attribute to set.
|
||||
*/
|
||||
public void setAttribute(Attribute attribute) {
|
||||
@@ -820,7 +788,6 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
|
||||
/**
|
||||
* Get all attributes.
|
||||
*
|
||||
* @return all attributes.
|
||||
*/
|
||||
public Attributes getAttributes() {
|
||||
@@ -850,8 +817,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Attributes getAttributes(Name name, String[] attrIds)
|
||||
throws NamingException {
|
||||
public Attributes getAttributes(Name name, String[] attrIds) throws NamingException {
|
||||
return getAttributes(name.toString(), attrIds);
|
||||
}
|
||||
|
||||
@@ -859,8 +825,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Attributes getAttributes(String name, String[] attrIds)
|
||||
throws NamingException {
|
||||
public Attributes getAttributes(String name, String[] attrIds) throws NamingException {
|
||||
if (StringUtils.hasLength(name)) {
|
||||
throw new NameNotFoundException();
|
||||
}
|
||||
@@ -881,8 +846,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void modifyAttributes(Name name, int modOp, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void modifyAttributes(Name name, int modOp, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -890,8 +854,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void modifyAttributes(String name, int modOp, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void modifyAttributes(String name, int modOp, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -899,8 +862,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -908,8 +870,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void modifyAttributes(String name, ModificationItem[] mods)
|
||||
throws NamingException {
|
||||
public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -917,8 +878,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void bind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void bind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -926,8 +886,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void bind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void bind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -935,8 +894,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void rebind(Name name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void rebind(Name name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -944,8 +902,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void rebind(String name, Object obj, Attributes attrs)
|
||||
throws NamingException {
|
||||
public void rebind(String name, Object obj, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -953,8 +910,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DirContext createSubcontext(Name name, Attributes attrs)
|
||||
throws NamingException {
|
||||
public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -962,8 +918,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DirContext createSubcontext(String name, Attributes attrs)
|
||||
throws NamingException {
|
||||
public DirContext createSubcontext(String name, Attributes attrs) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -987,8 +942,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DirContext getSchemaClassDefinition(Name name)
|
||||
throws NamingException {
|
||||
public DirContext getSchemaClassDefinition(Name name) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -996,8 +950,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public DirContext getSchemaClassDefinition(String name)
|
||||
throws NamingException {
|
||||
public DirContext getSchemaClassDefinition(String name) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -1005,8 +958,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes,
|
||||
String[] attributesToReturn) throws NamingException {
|
||||
public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes, String[] attributesToReturn)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -1023,7 +976,23 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes)
|
||||
public NamingEnumeration<SearchResult> search(Name name, Attributes matchingAttributes) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(String name, Attributes matchingAttributes) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(Name name, String filter, SearchControls cons)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
@@ -1032,7 +1001,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(String name, Attributes matchingAttributes)
|
||||
public NamingEnumeration<SearchResult> search(String name, String filter, SearchControls cons)
|
||||
throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
@@ -1041,7 +1010,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(Name name, String filter,
|
||||
public NamingEnumeration<SearchResult> search(Name name, String filterExpr, Object[] filterArgs,
|
||||
SearchControls cons) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
@@ -1050,29 +1019,11 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(String name, String filter,
|
||||
public NamingEnumeration<SearchResult> search(String name, String filterExpr, Object[] filterArgs,
|
||||
SearchControls cons) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(Name name, String filterExpr,
|
||||
Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public NamingEnumeration<SearchResult> search(String name, String filterExpr,
|
||||
Object[] filterArgs, SearchControls cons) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -1261,8 +1212,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String composeName(String name, String prefix)
|
||||
throws NamingException {
|
||||
public String composeName(String name, String prefix) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -1270,8 +1220,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public Object addToEnvironment(String propName, Object propVal)
|
||||
throws NamingException {
|
||||
public Object addToEnvironment(String propName, Object propVal) throws NamingException {
|
||||
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
@@ -1304,7 +1253,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
*/
|
||||
@Override
|
||||
public String getNameInNamespace() {
|
||||
if(base.size() == 0) {
|
||||
if (base.size() == 0) {
|
||||
return dn.toString();
|
||||
}
|
||||
|
||||
@@ -1312,7 +1261,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
LdapName result = (LdapName) dn.clone();
|
||||
result.addAll(0, base);
|
||||
return result.toString();
|
||||
} catch (InvalidNameException e) {
|
||||
}
|
||||
catch (InvalidNameException e) {
|
||||
throw new org.springframework.ldap.InvalidNameException(e);
|
||||
}
|
||||
}
|
||||
@@ -1334,8 +1284,7 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
this.dn = LdapUtils.newLdapName(dn);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Not possible to call setDn() on a DirContextAdapter in update mode");
|
||||
throw new IllegalStateException("Not possible to call setDn() on a DirContextAdapter in update mode");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1345,18 +1294,25 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
DirContextAdapter that = (DirContextAdapter) o;
|
||||
|
||||
if (updateMode != that.updateMode) return false;
|
||||
if (base != null ? !base.equals(that.base) : that.base != null) return false;
|
||||
if (dn != null ? !dn.equals(that.dn) : that.dn != null) return false;
|
||||
if (updateMode != that.updateMode)
|
||||
return false;
|
||||
if (base != null ? !base.equals(that.base) : that.base != null)
|
||||
return false;
|
||||
if (dn != null ? !dn.equals(that.dn) : that.dn != null)
|
||||
return false;
|
||||
if (originalAttrs != null ? !originalAttrs.equals(that.originalAttrs) : that.originalAttrs != null)
|
||||
return false;
|
||||
if (referralUrl != null ? !referralUrl.equals(that.referralUrl) : that.referralUrl != null) return false;
|
||||
if (updatedAttrs != null ? !updatedAttrs.equals(that.updatedAttrs) : that.updatedAttrs != null) return false;
|
||||
if (referralUrl != null ? !referralUrl.equals(that.referralUrl) : that.referralUrl != null)
|
||||
return false;
|
||||
if (updatedAttrs != null ? !updatedAttrs.equals(that.updatedAttrs) : that.updatedAttrs != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1417,7 +1373,8 @@ public class DirContextAdapter implements DirContextOperations {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void appendAttributeValue(StringBuilder builder, String attributeID, Object value, int index) throws NamingException {
|
||||
private void appendAttributeValue(StringBuilder builder, String attributeID, Object value, int index)
|
||||
throws NamingException {
|
||||
if (index > 0) {
|
||||
builder.append(", ");
|
||||
}
|
||||
|
||||
@@ -23,75 +23,68 @@ import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for DirContextAdapter.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @see DirContextAdapter
|
||||
*/
|
||||
public interface DirContextOperations extends DirContext, LdapDataEntry,
|
||||
AttributeModificationsAware {
|
||||
public interface DirContextOperations extends DirContext, LdapDataEntry, AttributeModificationsAware {
|
||||
|
||||
/**
|
||||
* Gets the update mode. An entry in update mode will keep track of its
|
||||
* modifications so that they can be retrieved using
|
||||
* {@link AttributeModificationsAware#getModificationItems()}. The update
|
||||
* mode should be <code>true</code> for a new entry and <code>true</code>
|
||||
* for an existing entry that is being updated.
|
||||
*
|
||||
* Gets the update mode. An entry in update mode will keep track of its modifications
|
||||
* so that they can be retrieved using
|
||||
* {@link AttributeModificationsAware#getModificationItems()}. The update mode should
|
||||
* be <code>true</code> for a new entry and <code>true</code> for an existing entry
|
||||
* that is being updated.
|
||||
* @return update mode.
|
||||
*/
|
||||
boolean isUpdateMode();
|
||||
|
||||
/**
|
||||
* Creates a String array of the names of the attributes which have been
|
||||
* changed.
|
||||
*
|
||||
* If this is a new entry, all set entries will be in the list. If this is
|
||||
* an updated entry, only changed and removed entries will be in the array.
|
||||
*
|
||||
* Creates a String array of the names of the attributes which have been changed.
|
||||
*
|
||||
* If this is a new entry, all set entries will be in the list. If this is an updated
|
||||
* entry, only changed and removed entries will be in the array.
|
||||
* @return Array of String
|
||||
*/
|
||||
String[] getNamesOfModifiedAttributes();
|
||||
|
||||
/**
|
||||
* Update the attributes.This will mean that the getters (
|
||||
* <code>getStringAttribute</code> methods) will return the updated values,
|
||||
* and the modifications will be forgotten (i.e.
|
||||
* {@link AttributeModificationsAware#getModificationItems()} will return an
|
||||
* empty array.
|
||||
* <code>getStringAttribute</code> methods) will return the updated values, and the
|
||||
* modifications will be forgotten (i.e.
|
||||
* {@link AttributeModificationsAware#getModificationItems()} will return an empty
|
||||
* array.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Set the dn of this entry.
|
||||
*
|
||||
* @param dn the dn.
|
||||
*/
|
||||
void setDn(Name dn);
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Context#getNameInNamespace()
|
||||
*/
|
||||
String getNameInNamespace();
|
||||
|
||||
/**
|
||||
* If this instance results from a referral, this method returns the url of
|
||||
* the referred server.
|
||||
*
|
||||
* @return The url of the referred server, e.g.
|
||||
* <code>ldap://localhost:389</code>, or the empty string if this is not a
|
||||
* referral.
|
||||
* If this instance results from a referral, this method returns the url of the
|
||||
* referred server.
|
||||
* @return The url of the referred server, e.g. <code>ldap://localhost:389</code>, or
|
||||
* the empty string if this is not a referral.
|
||||
* @since 1.3
|
||||
*/
|
||||
String getReferralUrl();
|
||||
|
||||
/**
|
||||
* Checks whether this instance results from a referral.
|
||||
*
|
||||
* @return <code>true</code> if this instance results from a referral,
|
||||
* <code>false</code> otherwise.
|
||||
* @since 1.3
|
||||
*/
|
||||
boolean isReferral();
|
||||
|
||||
}
|
||||
|
||||
@@ -20,32 +20,27 @@ import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface to be called in search by {@link LdapTemplate} before and after the
|
||||
* actual search and enumeration traversal. Implementations may be used to apply
|
||||
* search controls on the <code>Context</code> and retrieve the results of
|
||||
* such controls afterwards.
|
||||
*
|
||||
* Interface to be called in search by {@link LdapTemplate} before and after the actual
|
||||
* search and enumeration traversal. Implementations may be used to apply search controls
|
||||
* on the <code>Context</code> and retrieve the results of such controls afterwards.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
public interface DirContextProcessor {
|
||||
|
||||
/**
|
||||
* Perform pre-processing on the supplied DirContext.
|
||||
*
|
||||
* @param ctx
|
||||
* the <code>DirContext</code> instance.
|
||||
* @throws NamingException
|
||||
* if thrown by the underlying operation.
|
||||
* @param ctx the <code>DirContext</code> instance.
|
||||
* @throws NamingException if thrown by the underlying operation.
|
||||
*/
|
||||
void preProcess(DirContext ctx) throws NamingException;
|
||||
|
||||
/**
|
||||
* Perform post-processing on the supplied <code>DirContext</code>.
|
||||
*
|
||||
* @param ctx
|
||||
* the <code>DirContext</code> instance.
|
||||
* @throws NamingException
|
||||
* if thrown by the underlying operation.
|
||||
* @param ctx the <code>DirContext</code> instance.
|
||||
* @throws NamingException if thrown by the underlying operation.
|
||||
*/
|
||||
void postProcess(DirContext ctx) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -18,17 +18,18 @@ package org.springframework.ldap.core;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Helper interface to be able to get hold of the target <code>DirContext</code>
|
||||
* from proxies created by <code>ContextSource</code> proxies.
|
||||
*
|
||||
* Helper interface to be able to get hold of the target <code>DirContext</code> from
|
||||
* proxies created by <code>ContextSource</code> proxies.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface DirContextProxy {
|
||||
|
||||
/**
|
||||
* Get the target <code>DirContext</code> of the proxy.
|
||||
*
|
||||
* @return the target <code>DirContext</code>.
|
||||
*/
|
||||
DirContext getTargetContext();
|
||||
|
||||
}
|
||||
|
||||
@@ -38,18 +38,18 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link Name} corresponding to an LDAP path. A
|
||||
* Distinguished Name manipulation implementation is included in JDK1.5
|
||||
* (LdapName), but not in prior releases.
|
||||
*
|
||||
* A <code>DistinguishedName</code> is particularly useful when building or
|
||||
* modifying an LDAP path dynamically, as escaping will be taken care of.
|
||||
*
|
||||
* A path is split into several names. The {@link Name} interface specifies that
|
||||
* the most significant part be in position 0.
|
||||
* Default implementation of a {@link Name} corresponding to an LDAP path. A Distinguished
|
||||
* Name manipulation implementation is included in JDK1.5 (LdapName), but not in prior
|
||||
* releases.
|
||||
*
|
||||
* A <code>DistinguishedName</code> is particularly useful when building or modifying an
|
||||
* LDAP path dynamically, as escaping will be taken care of.
|
||||
*
|
||||
* A path is split into several names. The {@link Name} interface specifies that the most
|
||||
* significant part be in position 0.
|
||||
* <p>
|
||||
* Example:
|
||||
*
|
||||
*
|
||||
* <dl>
|
||||
* <dt>The path</dt>
|
||||
* <dd>uid=adam.skogman, ou=People, ou=EU</dd>
|
||||
@@ -61,49 +61,46 @@ import java.util.ListIterator;
|
||||
* <dd>uid=adam.skogman</dd>
|
||||
* </dl>
|
||||
* <p>
|
||||
* <code>Name</code> instances, and consequently <code>DistinguishedName</code>
|
||||
* instances are naturally mutable, which is useful when constructing
|
||||
* DistinguishedNames. Example:
|
||||
*
|
||||
* <code>Name</code> instances, and consequently <code>DistinguishedName</code> instances
|
||||
* are naturally mutable, which is useful when constructing DistinguishedNames. Example:
|
||||
*
|
||||
* <pre>
|
||||
* DistinguishedName path = new DistinguishedName("dc=jayway,dc=se");
|
||||
* path.add("ou", "People");
|
||||
* path.add("uid", "adam.skogman");
|
||||
* String dn = path.toString();
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* will render <code>uid=adam.skogman,ou=People,dc=jayway,dc=se</code>.
|
||||
* <p>
|
||||
* <b>NOTE:</b> The fact that DistinguishedName instances are mutable needs to
|
||||
* be taken into careful account, as this means that they may be modified
|
||||
* involuntarily. This means that whenever a <code>DistinguishedName</code>
|
||||
* instance is kept for reference (e.g. for identification of a domain entry) or
|
||||
* as a constant, you should consider getting an immutable copy of the instance
|
||||
* using {@link #immutableDistinguishedName()} or
|
||||
* <b>NOTE:</b> The fact that DistinguishedName instances are mutable needs to be taken
|
||||
* into careful account, as this means that they may be modified involuntarily. This means
|
||||
* that whenever a <code>DistinguishedName</code> instance is kept for reference (e.g. for
|
||||
* identification of a domain entry) or as a constant, you should consider getting an
|
||||
* immutable copy of the instance using {@link #immutableDistinguishedName()} or
|
||||
* {@link #immutableDistinguishedName(String)}.
|
||||
* <p>
|
||||
* <b>NB:</b>As of version 1.3 the default toString representation of
|
||||
* DistinguishedName now defaults to a compact one, without spaces between the
|
||||
* respective RDNs. For backward compatibility, set the
|
||||
* {@link #SPACED_DN_FORMAT_PROPERTY} ({@value #SPACED_DN_FORMAT_PROPERTY}) to
|
||||
* <code>true</code>.
|
||||
* <b>NB:</b>As of version 1.3 the default toString representation of DistinguishedName
|
||||
* now defaults to a compact one, without spaces between the respective RDNs. For backward
|
||||
* compatibility, set the {@link #SPACED_DN_FORMAT_PROPERTY}
|
||||
* ({@value #SPACED_DN_FORMAT_PROPERTY}) to <code>true</code>.
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
* @deprecated As of 2.0 it is recommended to use {@link javax.naming.ldap.LdapName} along with
|
||||
* utility methods in {@link LdapUtils} instead.
|
||||
* @deprecated As of 2.0 it is recommended to use {@link javax.naming.ldap.LdapName} along
|
||||
* with utility methods in {@link LdapUtils} instead.
|
||||
* @see javax.naming.ldap.LdapName
|
||||
* @see LdapUtils#newLdapName(javax.naming.Name)
|
||||
* @see LdapUtils#newLdapName(String)
|
||||
* @see org.springframework.ldap.support.LdapUtils#emptyLdapName()
|
||||
*/
|
||||
public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* System property that will be inspected to determine whether
|
||||
* {@link #toString()} will format the DN with spaces after each comma or
|
||||
* use a more compact representation, i.e.:
|
||||
* <code>uid=adam.skogman, ou=People, dc=jayway, dc=se</code> rather than
|
||||
* <code>uid=adam.skogman,ou=People,dc=jayway,dc=se</code>. A value other
|
||||
* System property that will be inspected to determine whether {@link #toString()}
|
||||
* will format the DN with spaces after each comma or use a more compact
|
||||
* representation, i.e.: <code>uid=adam.skogman, ou=People, dc=jayway, dc=se</code>
|
||||
* rather than <code>uid=adam.skogman,ou=People,dc=jayway,dc=se</code>. A value other
|
||||
* than null or blank will trigger the spaced format. Default is the compact
|
||||
* representation.
|
||||
* <p>
|
||||
@@ -119,10 +116,9 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* System property that will be inspected to determine whether creating a
|
||||
* DistinguishedName will convert the keys to <em>lowercase</em>, convert
|
||||
* the keys to <em>uppercase</em>, or leave the keys as they were in the
|
||||
* original String, ie <em>none</em>. Default is to convert the keys to
|
||||
* lowercase.
|
||||
* DistinguishedName will convert the keys to <em>lowercase</em>, convert the keys to
|
||||
* <em>uppercase</em>, or leave the keys as they were in the original String, ie
|
||||
* <em>none</em>. Default is to convert the keys to lowercase.
|
||||
* <p>
|
||||
* Valid values are:
|
||||
* <ul>
|
||||
@@ -144,6 +140,7 @@ public class DistinguishedName implements Name {
|
||||
public static final String KEY_CASE_FOLD_NONE = "none";
|
||||
|
||||
private static final String MANGLED_DOUBLE_QUOTES = "\\\\\"";
|
||||
|
||||
private static final String PROPER_DOUBLE_QUOTES = "\\\"";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DistinguishedName.class);
|
||||
@@ -158,6 +155,7 @@ public class DistinguishedName implements Name {
|
||||
* An empty, unmodifiable DistinguishedName.
|
||||
*/
|
||||
public static final DistinguishedName EMPTY_PATH = new DistinguishedName(Collections.EMPTY_LIST);
|
||||
|
||||
private static final int DEFAULT_BUFFER_SIZE = 256;
|
||||
|
||||
private List names;
|
||||
@@ -171,7 +169,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Construct a new <code>DistinguishedName</code> from a String.
|
||||
*
|
||||
* @param path a String corresponding to a (syntactically) valid LDAP path.
|
||||
*/
|
||||
public DistinguishedName(String path) {
|
||||
@@ -184,9 +181,8 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new <code>DistinguishedName</code> from the supplied
|
||||
* <code>List</code> of {@link LdapRdn} objects.
|
||||
*
|
||||
* Construct a new <code>DistinguishedName</code> from the supplied <code>List</code>
|
||||
* of {@link LdapRdn} objects.
|
||||
* @param list the components that this instance will consist of.
|
||||
*/
|
||||
public DistinguishedName(List list) {
|
||||
@@ -194,12 +190,10 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new <code>DistinguishedName</code> from the supplied
|
||||
* {@link Name}. The parts of the supplied {@link Name} must be
|
||||
* syntactically correct {@link LdapRdn}s.
|
||||
*
|
||||
* @param name the {@link Name} to construct a new
|
||||
* <code>DistinguishedName</code> from.
|
||||
* Construct a new <code>DistinguishedName</code> from the supplied {@link Name}. The
|
||||
* parts of the supplied {@link Name} must be syntactically correct {@link LdapRdn}s.
|
||||
* @param name the {@link Name} to construct a new <code>DistinguishedName</code>
|
||||
* from.
|
||||
*/
|
||||
public DistinguishedName(Name name) {
|
||||
Assert.notNull(name, "name cannot be null");
|
||||
@@ -214,9 +208,8 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the supplied String and make this instance represent the
|
||||
* corresponding distinguished name.
|
||||
*
|
||||
* Parse the supplied String and make this instance represent the corresponding
|
||||
* distinguished name.
|
||||
* @param path the LDAP path to parse.
|
||||
*/
|
||||
protected final void parse(String path) {
|
||||
@@ -235,11 +228,9 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* If path is surrounded by quotes, strip them. JNDI considers forward slash
|
||||
* ('/') special, but LDAP doesn't. {@link CompositeName#toString()} tends
|
||||
* to mangle a {@link Name} with a slash by surrounding it with quotes
|
||||
* ('"').
|
||||
*
|
||||
* If path is surrounded by quotes, strip them. JNDI considers forward slash ('/')
|
||||
* special, but LDAP doesn't. {@link CompositeName#toString()} tends to mangle a
|
||||
* {@link Name} with a slash by surrounding it with quotes ('"').
|
||||
* @param path Path to check and possibly strip.
|
||||
* @return A String with the possibly stripped path.
|
||||
*/
|
||||
@@ -259,7 +250,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Get the {@link LdapRdn} at a specified position.
|
||||
*
|
||||
* @param index the {@link LdapRdn} to retrieve.
|
||||
* @return the {@link LdapRdn} at the requested position.
|
||||
*/
|
||||
@@ -268,10 +258,8 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link LdapRdn} with the specified key. If there are several
|
||||
* {@link Rdn}s with the same key, the first one found (in order of
|
||||
* significance) will be returned.
|
||||
*
|
||||
* Get the {@link LdapRdn} with the specified key. If there are several {@link Rdn}s
|
||||
* with the same key, the first one found (in order of significance) will be returned.
|
||||
* @param key Attribute name of the {@link LdapRdn} to retrieve.
|
||||
* @return the {@link LdapRdn} with the requested key.
|
||||
* @throws IllegalArgumentException if no Rdn matches the given key.
|
||||
@@ -288,10 +276,9 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the {@link LdapRdnComponent} with the specified key
|
||||
* (Attribute value). If there are several Rdns with the same key, the value
|
||||
* of the first one found (in order of significance) will be returned.
|
||||
*
|
||||
* Get the value of the {@link LdapRdnComponent} with the specified key (Attribute
|
||||
* value). If there are several Rdns with the same key, the value of the first one
|
||||
* found (in order of significance) will be returned.
|
||||
* @param key Attribute name of the {@link LdapRdn} to retrieve.
|
||||
* @return the value.
|
||||
* @throws IllegalArgumentException if no Rdn matches the given key.
|
||||
@@ -302,23 +289,20 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Get the name <code>List</code>.
|
||||
*
|
||||
* @return the list of {@link LdapRdn}s that this
|
||||
* <code>DistinguishedName</code> consists of.
|
||||
* @return the list of {@link LdapRdn}s that this <code>DistinguishedName</code>
|
||||
* consists of.
|
||||
*/
|
||||
public List getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the String representation of this <code>DistinguishedName</code>.
|
||||
* Depending on the setting of property
|
||||
* <code>org.springframework.ldap.core.spacedDnFormat</code> a space will be
|
||||
* added after each comma, to make the result more readable. Default is
|
||||
* Get the String representation of this <code>DistinguishedName</code>. Depending on
|
||||
* the setting of property <code>org.springframework.ldap.core.spacedDnFormat</code> a
|
||||
* space will be added after each comma, to make the result more readable. Default is
|
||||
* compact representation, i.e. without any spaces.
|
||||
*
|
||||
* @return a syntactically correct, properly escaped String representation
|
||||
* of the <code>DistinguishedName</code>.
|
||||
* @return a syntactically correct, properly escaped String representation of the
|
||||
* <code>DistinguishedName</code>.
|
||||
* @see #SPACED_DN_FORMAT_PROPERTY
|
||||
*/
|
||||
public String toString() {
|
||||
@@ -332,12 +316,10 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compact String representation of this
|
||||
* <code>DistinguishedName</code>. Add no space after each comma, to make it
|
||||
* compact.
|
||||
*
|
||||
* @return a syntactically correct, properly escaped String representation
|
||||
* of the <code>DistinguishedName</code>.
|
||||
* Get the compact String representation of this <code>DistinguishedName</code>. Add
|
||||
* no space after each comma, to make it compact.
|
||||
* @return a syntactically correct, properly escaped String representation of the
|
||||
* <code>DistinguishedName</code>.
|
||||
*/
|
||||
public String toCompactString() {
|
||||
return format(COMPACT);
|
||||
@@ -345,9 +327,8 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Builds a complete LDAP path, ldap encoded, useful as a DN.
|
||||
*
|
||||
*
|
||||
* Always uses lowercase, always separates with ", " i.e. comma and a space.
|
||||
*
|
||||
* @return the LDAP path.
|
||||
*/
|
||||
public String encode() {
|
||||
@@ -383,9 +364,7 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a complete LDAP path, ldap and url encoded. Separates only with
|
||||
* ",".
|
||||
*
|
||||
* Builds a complete LDAP path, ldap and url encoded. Separates only with ",".
|
||||
* @return the LDAP path, for use in an url.
|
||||
*/
|
||||
public String toUrl() {
|
||||
@@ -402,12 +381,10 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this <code>DistinguishedName</code> path contains another
|
||||
* path.
|
||||
*
|
||||
* Determines if this <code>DistinguishedName</code> path contains another path.
|
||||
* @param path the path to check.
|
||||
* @return <code>true</code> if the supplied path is conained in this
|
||||
* instance, <code>false</code> otherwise.
|
||||
* @return <code>true</code> if the supplied path is conained in this instance,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean contains(DistinguishedName path) {
|
||||
|
||||
@@ -455,15 +432,14 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Add an LDAP path last in this DistinguishedName. E.g.:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* DistinguishedName name1 = new DistinguishedName("c=SE, dc=jayway, dc=se");
|
||||
* DistinguishedName name2 = new DistinguishedName("ou=people");
|
||||
* name1.append(name2);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* will result in <code>ou=people, c=SE, dc=jayway, dc=se</code>
|
||||
*
|
||||
* @param path the path to append.
|
||||
* @return this instance.
|
||||
*/
|
||||
@@ -474,7 +450,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Append a new {@link LdapRdn} using the supplied key and value.
|
||||
*
|
||||
* @param key the key of the {@link LdapRdn}.
|
||||
* @param value the value of the {@link LdapRdn}.
|
||||
* @return this instance.
|
||||
@@ -486,15 +461,14 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Add an LDAP path first in this DistinguishedName. E.g.:
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* DistinguishedName name1 = new DistinguishedName("ou=people");
|
||||
* DistinguishedName name2 = new DistinguishedName("c=SE, dc=jayway, dc=se");
|
||||
* name1.prepend(name2);
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* will result in <code>ou=people, c=SE, dc=jayway, dc=se</code>
|
||||
*
|
||||
* @param path the path to prepend.
|
||||
*/
|
||||
public void prepend(DistinguishedName path) {
|
||||
@@ -506,7 +480,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Remove the first part of this <code>DistinguishedName</code>.
|
||||
*
|
||||
* @return the removed entry.
|
||||
*/
|
||||
public LdapRdn removeFirst() {
|
||||
@@ -514,11 +487,9 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the supplied path from the beginning of this
|
||||
* <code>DistinguishedName</code> if this instance starts with
|
||||
* <code>path</code>. Useful for stripping base path suffix from a
|
||||
* <code>DistinguishedName</code>.
|
||||
*
|
||||
* Remove the supplied path from the beginning of this <code>DistinguishedName</code>
|
||||
* if this instance starts with <code>path</code>. Useful for stripping base path
|
||||
* suffix from a <code>DistinguishedName</code>.
|
||||
* @param path the path to remove from the beginning of this instance.
|
||||
*/
|
||||
public void removeFirst(Name path) {
|
||||
@@ -568,10 +539,10 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare this instance to another object. Note that the comparison is done
|
||||
* in order of significance, so the most significant Rdn is compared first,
|
||||
* then the second and so on.
|
||||
*
|
||||
* Compare this instance to another object. Note that the comparison is done in order
|
||||
* of significance, so the most significant Rdn is compared first, then the second and
|
||||
* so on.
|
||||
*
|
||||
* @see javax.naming.Name#compareTo(java.lang.Object)
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
@@ -590,7 +561,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#getAll()
|
||||
*/
|
||||
public Enumeration getAll() {
|
||||
@@ -605,7 +576,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#get(int)
|
||||
*/
|
||||
public String get(int index) {
|
||||
@@ -615,7 +586,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#getPrefix(int)
|
||||
*/
|
||||
public Name getPrefix(int index) {
|
||||
@@ -629,7 +600,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#getSuffix(int)
|
||||
*/
|
||||
public Name getSuffix(int index) {
|
||||
@@ -647,7 +618,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#startsWith(javax.naming.Name)
|
||||
*/
|
||||
public boolean startsWith(Name name) {
|
||||
@@ -684,14 +655,12 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this <code>DistinguishedName</code> ends with a certian
|
||||
* path.
|
||||
*
|
||||
* Determines if this <code>DistinguishedName</code> ends with a certian path.
|
||||
*
|
||||
* If the argument path is empty (no names in path) this method will return
|
||||
* <code>false</code>.
|
||||
*
|
||||
* @param name The suffix to check for.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public boolean endsWith(Name name) {
|
||||
DistinguishedName path = null;
|
||||
@@ -732,7 +701,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#addAll(javax.naming.Name)
|
||||
*/
|
||||
public Name addAll(Name name) throws InvalidNameException {
|
||||
@@ -741,7 +710,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#addAll(int, javax.naming.Name)
|
||||
*/
|
||||
public Name addAll(int arg0, Name name) throws InvalidNameException {
|
||||
@@ -759,7 +728,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#add(java.lang.String)
|
||||
*/
|
||||
public Name add(String string) throws InvalidNameException {
|
||||
@@ -768,7 +737,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#add(int, java.lang.String)
|
||||
*/
|
||||
public Name add(int index, String string) throws InvalidNameException {
|
||||
@@ -783,7 +752,7 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see javax.naming.Name#remove(int)
|
||||
*/
|
||||
public Object remove(int arg0) throws InvalidNameException {
|
||||
@@ -793,7 +762,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Remove the last part of this <code>DistinguishedName</code>.
|
||||
*
|
||||
* @return the removed {@link LdapRdn}.
|
||||
*/
|
||||
public LdapRdn removeLast() {
|
||||
@@ -802,7 +770,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Add a new {@link LdapRdn} using the supplied key and value.
|
||||
*
|
||||
* @param key the key of the {@link LdapRdn}.
|
||||
* @param value the value of the {@link LdapRdn}.
|
||||
*/
|
||||
@@ -812,7 +779,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Add the supplied {@link LdapRdn} last in the list of Rdns.
|
||||
*
|
||||
* @param rdn the {@link LdapRdn} to add.
|
||||
*/
|
||||
public void add(LdapRdn rdn) {
|
||||
@@ -821,7 +787,6 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Add the supplied {@link LdapRdn} att the specified index.
|
||||
*
|
||||
* @param idx the index at which to add the LdapRdn.
|
||||
* @param rdn the LdapRdn to add.
|
||||
*/
|
||||
@@ -830,10 +795,9 @@ public class DistinguishedName implements Name {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an immutable copy of this instance. It will not be possible to add
|
||||
* or remove any Rdns to or from the returned instance, and the respective
|
||||
* Rdns will also be immutable in turn.
|
||||
*
|
||||
* Return an immutable copy of this instance. It will not be possible to add or remove
|
||||
* any Rdns to or from the returned instance, and the respective Rdns will also be
|
||||
* immutable in turn.
|
||||
* @return a copy of this instance backed by an immutable list.
|
||||
* @since 1.2
|
||||
*/
|
||||
@@ -849,13 +813,12 @@ public class DistinguishedName implements Name {
|
||||
|
||||
/**
|
||||
* Create an immutable DistinguishedName instance, suitable as a constant.
|
||||
*
|
||||
* @param dnString the DN string to parse.
|
||||
* @return an immutable DistinguishedName corresponding to the supplied DN
|
||||
* string.
|
||||
* @return an immutable DistinguishedName corresponding to the supplied DN string.
|
||||
* @since 1.3
|
||||
*/
|
||||
public static final DistinguishedName immutableDistinguishedName(String dnString) {
|
||||
return new DistinguishedName(dnString).immutableDistinguishedName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ import java.beans.PropertyEditorSupport;
|
||||
|
||||
/**
|
||||
* Property editor for use with {@link DistinguishedName} instances. The
|
||||
* {@link #setAsText(String)} method sets the value as an <i>immutable</i>
|
||||
* instance of a DistinguishedName.
|
||||
*
|
||||
* {@link #setAsText(String)} method sets the value as an <i>immutable</i> instance of a
|
||||
* DistinguishedName.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @since 1.2
|
||||
* @deprecated {@link DistinguishedName} and associated classes are deprecated as of 2.0.
|
||||
@@ -30,6 +30,7 @@ public class DistinguishedNameEditor extends PropertyEditorSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#setAsText(java.lang.String)
|
||||
*/
|
||||
public void setAsText(String text) throws IllegalArgumentException {
|
||||
@@ -43,6 +44,7 @@ public class DistinguishedNameEditor extends PropertyEditorSupport {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.beans.PropertyEditorSupport#getAsText()
|
||||
*/
|
||||
public String getAsText() {
|
||||
|
||||
@@ -17,23 +17,22 @@ package org.springframework.ldap.core;
|
||||
|
||||
/**
|
||||
* A parser for RFC2253-compliant Distinguished Names.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @deprecated {@link DistinguishedName} and associated classes are deprecated as of 2.0.
|
||||
*/
|
||||
public interface DnParser {
|
||||
|
||||
/**
|
||||
* Parse a full Distinguished Name.
|
||||
*
|
||||
* @return the <code>DistinguishedName</code> corresponding to the parsed
|
||||
* stream.
|
||||
* @return the <code>DistinguishedName</code> corresponding to the parsed stream.
|
||||
*/
|
||||
public DistinguishedName dn() throws ParseException;
|
||||
|
||||
/**
|
||||
* Parse a Relative Distinguished Name.
|
||||
*
|
||||
* @return the next rdn on the stream.
|
||||
*/
|
||||
public LdapRdn rdn() throws ParseException;
|
||||
|
||||
}
|
||||
|
||||
@@ -21,57 +21,57 @@ import javax.naming.directory.Attributes;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility that helps with reading all attribute values from Active Directory using <em>Incremental Retrieval of
|
||||
* Multi-valued Properties</em>.
|
||||
* Utility that helps with reading all attribute values from Active Directory using
|
||||
* <em>Incremental Retrieval of Multi-valued Properties</em>.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @since 1.3.2
|
||||
* @see <a href="https://tools.ietf.org/html/draft-kashi-incremental-00">Incremental Retrieval of Multi-valued Properties</a>
|
||||
* @see <a href="https://tools.ietf.org/html/draft-kashi-incremental-00">Incremental
|
||||
* Retrieval of Multi-valued Properties</a>
|
||||
* @see org.springframework.ldap.core.support.DefaultIncrementalAttributesMapper
|
||||
*/
|
||||
public interface IncrementalAttributesMapper<T extends IncrementalAttributesMapper> extends AttributesMapper<T> {
|
||||
|
||||
/**
|
||||
* Get all of the collected values for the specified attribute.
|
||||
*
|
||||
* @param attributeName the attribute to get values for.
|
||||
* @return the collected values for the specified attribute. Will be <code>null</code>
|
||||
* if the requested attribute has not been returned by the server (attribute did not exist).
|
||||
* if the requested attribute has not been returned by the server (attribute did not
|
||||
* exist).
|
||||
*/
|
||||
List<Object> getValues(String attributeName);
|
||||
|
||||
/**
|
||||
* Get all collected values for all managed attributes as an Attributes instance.
|
||||
*
|
||||
* @return an Attributes instance populated with all collected values.
|
||||
*/
|
||||
Attributes getCollectedAttributes();
|
||||
|
||||
/**
|
||||
* Check whether another query iteration is required to get all values for all attributes.
|
||||
*
|
||||
* @return <code>true</code> if there are more values for at least one of the managed attributes,
|
||||
* <code>false</code> otherwise.
|
||||
* Check whether another query iteration is required to get all values for all
|
||||
* attributes.
|
||||
* @return <code>true</code> if there are more values for at least one of the managed
|
||||
* attributes, <code>false</code> otherwise.
|
||||
*/
|
||||
boolean hasMore();
|
||||
|
||||
/**
|
||||
* Get properly formatted attributes for use in the next query. The attribute names included will
|
||||
* include Range specifiers as needed and only the attributes that have not been retrieved in full
|
||||
* will be included.
|
||||
*
|
||||
* Get properly formatted attributes for use in the next query. The attribute names
|
||||
* included will include Range specifiers as needed and only the attributes that have
|
||||
* not been retrieved in full will be included.
|
||||
* @return an array of Strings to be used as input to e.g.
|
||||
* {@link org.springframework.ldap.core.LdapTemplate#lookup(javax.naming.Name, String[], org.springframework.ldap.core.AttributesMapper)}
|
||||
* in the next iteration.
|
||||
* {@link org.springframework.ldap.core.LdapTemplate#lookup(javax.naming.Name, String[], org.springframework.ldap.core.AttributesMapper)}
|
||||
* in the next iteration.
|
||||
*/
|
||||
String[] getAttributesForLookup();
|
||||
|
||||
/**
|
||||
* Goes through all of the attributes to record their values and figure out whether a new query iteration
|
||||
* is needed to get more values.
|
||||
*
|
||||
* Goes through all of the attributes to record their values and figure out whether a
|
||||
* new query iteration is needed to get more values.
|
||||
* @param attributes attributes from a SearchResult.
|
||||
* @return this instance.
|
||||
* @throws javax.naming.NamingException
|
||||
*/
|
||||
T mapFromAttributes(Attributes attributes) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ import javax.naming.NamingException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
final class IterableNamingEnumeration<T> implements NamingEnumeration<T> {
|
||||
|
||||
private final Iterator<T> iterator;
|
||||
|
||||
IterableNamingEnumeration(Iterable<T> iterable) {
|
||||
@@ -37,4 +38,5 @@ final class IterableNamingEnumeration<T> implements NamingEnumeration<T> {
|
||||
public T nextElement() {
|
||||
return next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,29 +21,28 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Extends {@link javax.naming.directory.BasicAttribute} to add support for
|
||||
* options as defined in RFC2849.
|
||||
* Extends {@link javax.naming.directory.BasicAttribute} to add support for options as
|
||||
* defined in RFC2849.
|
||||
* <p>
|
||||
* While uncommon, options can be used to specify additional descriptors for
|
||||
* the attribute. Options are backed by a {@link java.util.HashSet} of
|
||||
* While uncommon, options can be used to specify additional descriptors for the
|
||||
* attribute. Options are backed by a {@link java.util.HashSet} of
|
||||
* {@link java.lang.String}.
|
||||
*
|
||||
*
|
||||
* @author Keith Barlow
|
||||
*
|
||||
*/
|
||||
public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
private static final long serialVersionUID = -5263905906016179429L;
|
||||
|
||||
|
||||
/**
|
||||
* Holds the attributes options.
|
||||
*/
|
||||
protected Set<String> options = new HashSet<String>();
|
||||
|
||||
|
||||
/**
|
||||
* Creates an unordered attribute with the specified ID.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
*/
|
||||
public LdapAttribute(String id) {
|
||||
super(id);
|
||||
@@ -51,8 +50,7 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Creates an unordered attribute with the specified ID and value.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param value Attribute value.
|
||||
*/
|
||||
public LdapAttribute(String id, Object value) {
|
||||
@@ -61,10 +59,10 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Creates an unordered attribute with the specified ID, value, and options.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param value Attribute value.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute options.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute
|
||||
* options.
|
||||
*/
|
||||
public LdapAttribute(String id, Object value, Collection<String> options) {
|
||||
super(id, value);
|
||||
@@ -73,8 +71,7 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Creates an attribute with the specified ID whose values may be ordered.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param ordered boolean indicating whether or not the attributes values are ordered.
|
||||
*/
|
||||
public LdapAttribute(String id, boolean ordered) {
|
||||
@@ -83,9 +80,9 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Creates an attribute with the specified ID and options whose values may be ordered.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute options.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute
|
||||
* options.
|
||||
* @param ordered boolean indicating whether or not the attributes values are ordered.
|
||||
*/
|
||||
public LdapAttribute(String id, Collection<String> options, boolean ordered) {
|
||||
@@ -95,8 +92,7 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Creates an attribute with the specified ID and value whose values may be ordered.
|
||||
*
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param value Attribute value.
|
||||
* @param ordered boolean indicating whether or not the attributes values are ordered.
|
||||
*/
|
||||
@@ -105,11 +101,12 @@ public class LdapAttribute extends BasicAttribute {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an attribute with the specified ID, value, and options whose values may be ordered.
|
||||
*
|
||||
* Creates an attribute with the specified ID, value, and options whose values may be
|
||||
* ordered.
|
||||
* @param id {@link java.lang.String} ID of the attribute.
|
||||
* @param value Attribute value.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute options.
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} attribute
|
||||
* options.
|
||||
* @param ordered boolean indicating whether or not the attributes values are ordered.
|
||||
*/
|
||||
public LdapAttribute(String id, Object value, Collection<String> options, boolean ordered) {
|
||||
@@ -119,106 +116,96 @@ public class LdapAttribute extends BasicAttribute {
|
||||
|
||||
/**
|
||||
* Get options.
|
||||
*
|
||||
* @return returns a {@link java.util.Set} of {@link java.lang.String}
|
||||
*/
|
||||
public Set<String> getOptions() {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set options.
|
||||
*
|
||||
* @param options {@link java.util.Set} of {@link java.lang.String}
|
||||
*/
|
||||
public void setOptions(Set<String> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an option.
|
||||
*
|
||||
* @param option {@link java.lang.String} option.
|
||||
* @return boolean indication successful addition of option.
|
||||
*/
|
||||
public boolean addOption(String option) {
|
||||
return this.options.add(option);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add all values in the collection to the options.
|
||||
*
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} values.
|
||||
* @return boolean indication successful addition of options.
|
||||
*/
|
||||
public boolean addAllOptions(Collection<String> options) {
|
||||
return this.options.addAll(options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clears all stored options.
|
||||
*/
|
||||
public void clearOptions() {
|
||||
this.options.clear();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks for existence of a particular option on the set.
|
||||
*
|
||||
* @param option {@link java.lang.String} option.
|
||||
* @return boolean indicating result.
|
||||
*/
|
||||
public boolean contains(String option) {
|
||||
return this.options.contains(option);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks for existence of a series of options on the set.
|
||||
*
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} options.
|
||||
* @return boolean indicating result.
|
||||
*/
|
||||
public boolean containsAll(Collection<String> options) {
|
||||
return this.options.containsAll(options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the presence of options.
|
||||
*
|
||||
* @return boolean indicating result.
|
||||
*/
|
||||
public boolean hasOptions() {
|
||||
return !options.isEmpty();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes an option from the the set.
|
||||
*
|
||||
* @param option {@link java.lang.String} option.
|
||||
* @return boolean indicating successful removal of option.
|
||||
*/
|
||||
public boolean removeOption(String option) {
|
||||
return this.options.remove(option);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all options listed in the supplied set.
|
||||
*
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} options.
|
||||
* @return boolean indicating successful removal of options.
|
||||
*/
|
||||
public boolean removeAllOptions(Collection<String> options) {
|
||||
return this.options.removeAll(options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes any options not on the set of supplied options.
|
||||
*
|
||||
* @param options {@link java.util.Collection} of {@link java.lang.String} options.
|
||||
* @return boolean indicating successful retention of options.
|
||||
*/
|
||||
public boolean retainAllOptions(Collection<String> options) {
|
||||
return this.options.retainAll(options);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -30,45 +30,58 @@ import javax.naming.ldap.LdapName;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Extends {@link javax.naming.directory.BasicAttributes} to add specialized support
|
||||
* for DNs.
|
||||
* Extends {@link javax.naming.directory.BasicAttributes} to add specialized support for
|
||||
* DNs.
|
||||
* <p>
|
||||
* While DNs appear to be and can be treated as attributes, they have a special
|
||||
* meaning in that they define the address to which the object is bound. DNs must
|
||||
* conform to special formatting rules and are typically required to be handled
|
||||
* separately from other attributes.
|
||||
* While DNs appear to be and can be treated as attributes, they have a special meaning in
|
||||
* that they define the address to which the object is bound. DNs must conform to special
|
||||
* formatting rules and are typically required to be handled separately from other
|
||||
* attributes.
|
||||
* <p>
|
||||
* This class makes this distinction between the DN and other
|
||||
* attributes prominent and apparent.
|
||||
*
|
||||
* This class makes this distinction between the DN and other attributes prominent and
|
||||
* apparent.
|
||||
*
|
||||
* @author Keith Barlow
|
||||
*
|
||||
*/
|
||||
public class LdapAttributes extends BasicAttributes {
|
||||
|
||||
private static final long serialVersionUID = 97903297123869138L;
|
||||
|
||||
|
||||
private static Logger log = LoggerFactory.getLogger(LdapAttributes.class);
|
||||
|
||||
private static final String SAFE_CHAR = "[\\p{ASCII}&&[^\\x00\\x0A\\x0D]]"; //Any ASCII except NUL, LF, and CR
|
||||
|
||||
private static final String SAFE_INIT_CHAR = "[\\p{ASCII}&&[^ \\x00\\x0A\\x0D\\x3A\\x3C]]"; //Any ASCII except NUL, LF, CR, SPACE, colon, and less-than
|
||||
|
||||
private static final String SAFE_CHAR = "[\\p{ASCII}&&[^\\x00\\x0A\\x0D]]"; // Any
|
||||
// ASCII
|
||||
// except
|
||||
// NUL,
|
||||
// LF, and
|
||||
// CR
|
||||
|
||||
private static final String SAFE_INIT_CHAR = "[\\p{ASCII}&&[^ \\x00\\x0A\\x0D\\x3A\\x3C]]"; // Any
|
||||
// ASCII
|
||||
// except
|
||||
// NUL,
|
||||
// LF,
|
||||
// CR,
|
||||
// SPACE,
|
||||
// colon,
|
||||
// and
|
||||
// less-than
|
||||
|
||||
/**
|
||||
* Distinguished name to which the object is bound.
|
||||
*/
|
||||
protected LdapName dn = LdapUtils.emptyLdapName();
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public LdapAttributes() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for specifying whether or not the object is case sensitive.
|
||||
*
|
||||
* @param ignoreCase boolean indicator.
|
||||
*/
|
||||
public LdapAttributes(boolean ignoreCase) {
|
||||
@@ -77,10 +90,10 @@ public class LdapAttributes extends BasicAttributes {
|
||||
|
||||
/**
|
||||
* Returns the distinguished name to which the object is bound.
|
||||
*
|
||||
* @return {@link org.springframework.ldap.core.DistinguishedName} specifying the name to which the object is bound.
|
||||
* @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}.
|
||||
* use {@link #getName()} instead.
|
||||
* @return {@link org.springframework.ldap.core.DistinguishedName} specifying the name
|
||||
* to which the object is bound.
|
||||
* @deprecated {@link DistinguishedName and associated classes and methods are
|
||||
* deprecated as of 2.0}. use {@link #getName()} instead.
|
||||
*/
|
||||
public DistinguishedName getDN() {
|
||||
return new DistinguishedName(dn);
|
||||
@@ -88,7 +101,6 @@ public class LdapAttributes extends BasicAttributes {
|
||||
|
||||
/**
|
||||
* Returns the distinguished name to which the object is bound.
|
||||
*
|
||||
* @return {@link LdapName} specifying the name to which the object is bound.
|
||||
*/
|
||||
public LdapName getName() {
|
||||
@@ -97,10 +109,10 @@ public class LdapAttributes extends BasicAttributes {
|
||||
|
||||
/**
|
||||
* Sets the distinguished name of the object.
|
||||
*
|
||||
* @param dn {@link org.springframework.ldap.core.DistinguishedName} specifying the name to which the object is bound.
|
||||
* @deprecated {@link DistinguishedName and associated classes and methods are deprecated as of 2.0}.
|
||||
* use {@link #setName(javax.naming.Name)} instead.
|
||||
* @param dn {@link org.springframework.ldap.core.DistinguishedName} specifying the
|
||||
* name to which the object is bound.
|
||||
* @deprecated {@link DistinguishedName and associated classes and methods are
|
||||
* deprecated as of 2.0}. use {@link #setName(javax.naming.Name)} instead.
|
||||
*/
|
||||
public void setDN(DistinguishedName dn) {
|
||||
this.dn = LdapUtils.newLdapName(dn);
|
||||
@@ -109,54 +121,59 @@ public class LdapAttributes extends BasicAttributes {
|
||||
public void setName(Name name) {
|
||||
this.dn = LdapUtils.newLdapName(name);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object in LDIF format.
|
||||
*
|
||||
* @return {@link java.lang.String} formated to RFC2849 LDIF specifications.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
|
||||
LdapName dn = getName();
|
||||
|
||||
|
||||
if (!dn.toString().matches(SAFE_INIT_CHAR + SAFE_CHAR + "*")) {
|
||||
sb.append("dn:: " + LdapEncoder.printBase64Binary(dn.toString().getBytes()) + "\n");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sb.append("dn: " + getDN() + "\n");
|
||||
}
|
||||
|
||||
|
||||
NamingEnumeration<Attribute> attributes = getAll();
|
||||
|
||||
|
||||
while (attributes.hasMore()) {
|
||||
Attribute attribute = attributes.next();
|
||||
NamingEnumeration<?> values = attribute.getAll();
|
||||
|
||||
|
||||
while (values.hasMore()) {
|
||||
Object value = values.next();
|
||||
|
||||
|
||||
if (value instanceof String) {
|
||||
sb.append(attribute.getID() + ": " + (String) value + "\n");
|
||||
|
||||
} else if (value instanceof byte[]) {
|
||||
|
||||
}
|
||||
else if (value instanceof byte[]) {
|
||||
sb.append(attribute.getID() + ":: " + LdapEncoder.printBase64Binary((byte[]) value) + "\n");
|
||||
|
||||
} else if (value instanceof URI) {
|
||||
}
|
||||
else if (value instanceof URI) {
|
||||
sb.append(attribute.getID() + ":< " + (URI) value + "\n");
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else {
|
||||
sb.append(attribute.getID() + ": " + value + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (NamingException e) {
|
||||
|
||||
}
|
||||
catch (NamingException e) {
|
||||
log.error("Error formating attributes for output.", e);
|
||||
sb = new StringBuilder();
|
||||
}
|
||||
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,38 +43,30 @@ import org.springframework.ldap.query.LdapQueryBuilder;
|
||||
public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Start building a request for all children of the
|
||||
* given {@code name}.
|
||||
*
|
||||
* Start building a request for all children of the given {@code name}.
|
||||
* @param name the distinguished name to find children for
|
||||
* @return a spec for specifying the list parameters
|
||||
*/
|
||||
ListSpec list(String name);
|
||||
|
||||
/**
|
||||
* Start building a request for all children of the
|
||||
* given {@code name}.
|
||||
*
|
||||
* Start building a request for all children of the given {@code name}.
|
||||
* @param name the distinguished name to find children for
|
||||
* @return a spec for specifying the list parameters
|
||||
*/
|
||||
ListSpec list(Name name);
|
||||
|
||||
/**
|
||||
* Start building a request for all children of the
|
||||
* given {@code name}. The result will include the object bound to
|
||||
* the name.
|
||||
*
|
||||
* Start building a request for all children of the given {@code name}. The result
|
||||
* will include the object bound to the name.
|
||||
* @param name the distinguished name to find children for
|
||||
* @return a spec for specifying the list parameters
|
||||
*/
|
||||
ListBindingsSpec listBindings(String name);
|
||||
|
||||
/**
|
||||
* Start building a request for all children of the
|
||||
* given {@code name}. The result will include the object bound to
|
||||
* the name.
|
||||
*
|
||||
* Start building a request for all children of the given {@code name}. The result
|
||||
* will include the object bound to the name.
|
||||
* @param name the distinguished name to find children for
|
||||
* @return a spec for specifying the list parameters
|
||||
*/
|
||||
@@ -82,67 +74,62 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Start building a search request.
|
||||
*
|
||||
* @return a spec for specifying the search parameters
|
||||
*/
|
||||
SearchSpec search();
|
||||
|
||||
/**
|
||||
* Start building an authentication request.
|
||||
*
|
||||
* @return a spec for specifying the authentication parameters
|
||||
*/
|
||||
AuthenticateSpec authenticate();
|
||||
|
||||
/**
|
||||
* Start building a bind request, using the given {@code name}
|
||||
* as the identifier.
|
||||
*
|
||||
* Start building a bind request, using the given {@code name} as the identifier.
|
||||
* @return a spec for specifying the bind parameters
|
||||
*/
|
||||
BindSpec bind(String name);
|
||||
|
||||
/**
|
||||
* Start building a bind or rebind request, using the given {@code name}
|
||||
* as the identifier.
|
||||
*
|
||||
* Start building a bind or rebind request, using the given {@code name} as the
|
||||
* identifier.
|
||||
* @return a spec for specifying the bind parameters
|
||||
*/
|
||||
BindSpec bind(Name name);
|
||||
|
||||
/**
|
||||
* Start building a request to modify name or attributes of an entry, using the given {@code name}
|
||||
* as the identifier.
|
||||
* Start building a request to modify name or attributes of an entry, using the given
|
||||
* {@code name} as the identifier.
|
||||
*
|
||||
* <p>
|
||||
* Note that a {@link #modify(Name)} is different from a rebind in that
|
||||
* entries are changed instead of removed and recreated.
|
||||
* Note that a {@link #modify(Name)} is different from a rebind in that entries are
|
||||
* changed instead of removed and recreated.
|
||||
*
|
||||
* <p>
|
||||
* A change in name uses LDAP's {@link DirContext#rename} function.
|
||||
* A change in attributes uses LDAP's {@link DirContext#modifyAttributes} function.
|
||||
* The {@code rename} action is optimistically performed before the {@code modify} function.
|
||||
* A rollback of the name is attempted in the event that attribute modification fails.
|
||||
*
|
||||
* A change in name uses LDAP's {@link DirContext#rename} function. A change in
|
||||
* attributes uses LDAP's {@link DirContext#modifyAttributes} function. The
|
||||
* {@code rename} action is optimistically performed before the {@code modify}
|
||||
* function. A rollback of the name is attempted in the event that attribute
|
||||
* modification fails.
|
||||
* @param name the name of the entry to modify
|
||||
* @return a spec for specifying the modify parameters
|
||||
*/
|
||||
ModifySpec modify(String name);
|
||||
|
||||
/**
|
||||
* Start building a request to modify name or attributes of an entry, using the given {@code name}
|
||||
* as the identifier.
|
||||
* Start building a request to modify name or attributes of an entry, using the given
|
||||
* {@code name} as the identifier.
|
||||
*
|
||||
* <p>
|
||||
* Note that a {@link #modify(Name)} is different from a rebind in that
|
||||
* entries are changed instead of removed and recreated.
|
||||
* Note that a {@link #modify(Name)} is different from a rebind in that entries are
|
||||
* changed instead of removed and recreated.
|
||||
*
|
||||
* <p>
|
||||
* A change in name uses LDAP's {@link DirContext#rename} function.
|
||||
* A change in attributes uses LDAP's {@link DirContext#modifyAttributes} function.
|
||||
* The {@code rename} action is optimistically performed before the {@code modify} function.
|
||||
* A rollback of the name is attempted in the event that attribute modification fails.
|
||||
*
|
||||
* A change in name uses LDAP's {@link DirContext#rename} function. A change in
|
||||
* attributes uses LDAP's {@link DirContext#modifyAttributes} function. The
|
||||
* {@code rename} action is optimistically performed before the {@code modify}
|
||||
* function. A rollback of the name is attempted in the event that attribute
|
||||
* modification fails.
|
||||
* @param name the name of the entry to modify
|
||||
* @return a spec for specifying the modify parameters
|
||||
*/
|
||||
@@ -150,7 +137,6 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Start building a request to remove the {@code name} entry.
|
||||
*
|
||||
* @param name the name of the entry to remove
|
||||
* @return a spec for specifying the unbind parameters
|
||||
*/
|
||||
@@ -158,19 +144,17 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Start building a request to remove the {@code name} entry.
|
||||
*
|
||||
* @param name the name of the entry to remove
|
||||
* @return a spec for specifying the unbind parameters
|
||||
*/
|
||||
UnbindSpec unbind(Name name);
|
||||
|
||||
/**
|
||||
* Return a builder to create a new {@code LdapClient} whose settings are
|
||||
* replicated from the current {@code LdapClient}.
|
||||
* Return a builder to create a new {@code LdapClient} whose settings are replicated
|
||||
* from the current {@code LdapClient}.
|
||||
*/
|
||||
Builder mutate();
|
||||
|
||||
|
||||
// Static, factory methods
|
||||
|
||||
/**
|
||||
@@ -189,7 +173,6 @@ public interface LdapClient {
|
||||
return new DefaultLdapClientBuilder();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A mutable builder for creating an {@link LdapClient}.
|
||||
*/
|
||||
@@ -202,8 +185,8 @@ public interface LdapClient {
|
||||
Builder contextSource(ContextSource contextSource);
|
||||
|
||||
/**
|
||||
* Use this {@link Supplier} to generate a {@link SearchControls}.
|
||||
* It should generate a new {@link SearchControls} on each call.
|
||||
* Use this {@link Supplier} to generate a {@link SearchControls}. It should
|
||||
* generate a new {@link SearchControls} on each call.
|
||||
* @param searchControlsSupplier the {@link Supplier} to use
|
||||
* @return the {@link Builder} for further customizations
|
||||
*/
|
||||
@@ -212,7 +195,6 @@ public interface LdapClient {
|
||||
/**
|
||||
* Whether to ignore the {@link org.springframework.ldap.PartialResultException}.
|
||||
* Defaults to {@code true}.
|
||||
*
|
||||
* @param ignore whether to ignore the {@link PartialResultException}
|
||||
* @return the {@link LdapClient.Builder} for further customizations
|
||||
*/
|
||||
@@ -221,16 +203,15 @@ public interface LdapClient {
|
||||
/**
|
||||
* Whether to ignore the {@link org.springframework.ldap.NameNotFoundException}.
|
||||
* Defaults to {@code true}.
|
||||
*
|
||||
* @param ignore whether to ignore the {@link NameNotFoundException}
|
||||
* @return the {@link LdapClient.Builder} for further customizations
|
||||
*/
|
||||
Builder ignoreNameNotFoundException(boolean ignore);
|
||||
|
||||
/**
|
||||
* Whether to ignore the {@link org.springframework.ldap.SizeLimitExceededException}.
|
||||
* Defaults to {@code true}.
|
||||
*
|
||||
* Whether to ignore the
|
||||
* {@link org.springframework.ldap.SizeLimitExceededException}. Defaults to
|
||||
* {@code true}.
|
||||
* @param ignore whether to ignore the {@link SizeLimitExceededException}
|
||||
* @return the {@link LdapClient.Builder} for further customizations
|
||||
*/
|
||||
@@ -238,7 +219,8 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Apply the given {@code Consumer} to this builder instance.
|
||||
* <p>This can be useful for applying pre-packaged customizations.
|
||||
* <p>
|
||||
* This can be useful for applying pre-packaged customizations.
|
||||
* @param builderConsumer the consumer to apply
|
||||
*/
|
||||
Builder apply(Consumer<Builder> builderConsumer);
|
||||
@@ -252,97 +234,100 @@ public interface LdapClient {
|
||||
* Build the {@link LdapClient} instance.
|
||||
*/
|
||||
LdapClient build();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #list} request.
|
||||
*/
|
||||
interface ListSpec {
|
||||
|
||||
/**
|
||||
* Return the entry's children as a list of mapped results
|
||||
*
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search result
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search
|
||||
* result
|
||||
* @return the entry's children or an empty list
|
||||
*/
|
||||
<T> List<T> toList(NameClassPairMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Return the entry's children as a stream of mapped results. Note that
|
||||
* the {@link Stream} must be closed when done reading from it.
|
||||
*
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search result
|
||||
* Return the entry's children as a stream of mapped results. Note that the
|
||||
* {@link Stream} must be closed when done reading from it.
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search
|
||||
* result
|
||||
* @return the entry's children or an empty stream
|
||||
*/
|
||||
<T> Stream<T> toStream(NameClassPairMapper<T> mapper);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #listBindings} request.
|
||||
*/
|
||||
interface ListBindingsSpec {
|
||||
|
||||
/**
|
||||
* Return the entry's children as a list of mapped results
|
||||
*
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search result
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search
|
||||
* result
|
||||
* @return the entry's children or an empty list
|
||||
*/
|
||||
<T> List<T> toList(NameClassPairMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Return the entry's children as a list of mapped results
|
||||
*
|
||||
* @param mapper the {@link ContextMapper} strategy to mapping each search result
|
||||
* @return the entry's children or an empty list
|
||||
*/
|
||||
<T> List<T> toList(ContextMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Return the entry's children as a stream of mapped results. Note that
|
||||
* the {@link Stream} must be closed when done reading from it.
|
||||
*
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search result
|
||||
* Return the entry's children as a stream of mapped results. Note that the
|
||||
* {@link Stream} must be closed when done reading from it.
|
||||
* @param mapper the {@link NameClassPairMapper} strategy to mapping each search
|
||||
* result
|
||||
* @return the entry's children or an empty stream
|
||||
*/
|
||||
<T> Stream<T> toStream(NameClassPairMapper<T> mapper);
|
||||
|
||||
/**
|
||||
* Return the entry's children as a stream of mapped results. Note that
|
||||
* the {@link Stream} must be closed when done reading from it.
|
||||
*
|
||||
* Return the entry's children as a stream of mapped results. Note that the
|
||||
* {@link Stream} must be closed when done reading from it.
|
||||
* @param mapper the {@link ContextMapper} strategy to mapping each search result
|
||||
* @return the entry's children or an empty stream
|
||||
*/
|
||||
<T> Stream<T> toStream(ContextMapper<T> mapper);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #search} request.
|
||||
*/
|
||||
interface SearchSpec {
|
||||
|
||||
/**
|
||||
* The name to search for. This is a convenience method for
|
||||
* creating an {@link LdapQuery} based only on the {@code name}.
|
||||
*
|
||||
* The name to search for. This is a convenience method for creating an
|
||||
* {@link LdapQuery} based only on the {@code name}.
|
||||
* @param name the name to search for
|
||||
* @return the {@link SearchSpec} for further configuration
|
||||
*/
|
||||
SearchSpec name(String name);
|
||||
|
||||
/**
|
||||
* The name to search for. This is a convenience method for
|
||||
* creating an {@link LdapQuery} based only on the {@code name}.
|
||||
*
|
||||
* The name to search for. This is a convenience method for creating an
|
||||
* {@link LdapQuery} based only on the {@code name}.
|
||||
* @param name the name to search for
|
||||
* @return the {@link SearchSpec} for further configuration
|
||||
*/
|
||||
SearchSpec name(Name name);
|
||||
|
||||
/**
|
||||
* The no-filter query to execute. Or, that is, the filter is {@code (objectclass=*)}.
|
||||
*
|
||||
* <p>This is helpful when searching by name and needing to customize the {@link SearchControls} or the
|
||||
* returned attribute set.
|
||||
* The no-filter query to execute. Or, that is, the filter is
|
||||
* {@code (objectclass=*)}.
|
||||
*
|
||||
* <p>
|
||||
* This is helpful when searching by name and needing to customize the
|
||||
* {@link SearchControls} or the returned attribute set.
|
||||
* @param consumer the consumer to alter a default query
|
||||
* @return the {@link SearchSpec} for further configuration
|
||||
*/
|
||||
@@ -350,7 +335,6 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* The query to execute.
|
||||
*
|
||||
* @param query the query to execute
|
||||
* @return the {@link SearchSpec} for further configuration
|
||||
*/
|
||||
@@ -364,22 +348,21 @@ public interface LdapClient {
|
||||
/**
|
||||
* Expect at most one search result, mapped by the given strategy.
|
||||
*
|
||||
* <p>Returns {@code null} if no result is found.
|
||||
*
|
||||
* <p>
|
||||
* Returns {@code null} if no result is found.
|
||||
* @param mapper the {@link ContextMapper} strategy to use to map the result
|
||||
* @return the single search result, or {@code null} if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> O toObject(ContextMapper<O> mapper);
|
||||
|
||||
/**
|
||||
* Expect at most one search result, mapped by the given strategy.
|
||||
*
|
||||
* @param mapper the {@link AttributesMapper} strategy to use to map the result
|
||||
* @return the single search result, or {@code null} if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> O toObject(AttributesMapper<O> mapper);
|
||||
|
||||
@@ -390,21 +373,19 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Return a list of search results, each mapped by the given strategy.
|
||||
*
|
||||
* @param mapper the {@link ContextMapper} strategy to use to map the result
|
||||
* @return the single search result, or empty list if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> List<O> toList(ContextMapper<O> mapper);
|
||||
|
||||
/**
|
||||
* Return a list of search results, each mapped by the given strategy.
|
||||
*
|
||||
* @param mapper the {@link AttributesMapper} strategy to use to map the result
|
||||
* @return the single search result, or empty list if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> List<O> toList(AttributesMapper<O> mapper);
|
||||
|
||||
@@ -415,32 +396,31 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Return a stream of search results, each mapped by the given strategy.
|
||||
*
|
||||
* @param mapper the {@link ContextMapper} strategy to use to map the result
|
||||
* @return the single search result, or empty stream if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> Stream<O> toStream(ContextMapper<O> mapper);
|
||||
|
||||
/**
|
||||
* Return a stream of search results, each mapped by the given strategy.
|
||||
*
|
||||
* @param mapper the {@link AttributesMapper} strategy to use to map the result
|
||||
* @return the single search result, or empty stream if none was found
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the result
|
||||
* set contains more than one result
|
||||
* @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the
|
||||
* result set contains more than one result
|
||||
*/
|
||||
<O> Stream<O> toStream(AttributesMapper<O> mapper);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #authenticate} request.
|
||||
*/
|
||||
interface AuthenticateSpec {
|
||||
|
||||
/**
|
||||
* The query to authenticate
|
||||
*
|
||||
* @param query the query to authenticate
|
||||
* @return the {@link AuthenticateSpec} for further configuration
|
||||
*/
|
||||
@@ -448,7 +428,6 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* The password to use
|
||||
*
|
||||
* @param password the password to use
|
||||
* @return the {@link AuthenticateSpec} for further configuration
|
||||
*/
|
||||
@@ -456,32 +435,34 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Authenticate the query against the provided password
|
||||
*
|
||||
* @throws org.springframework.ldap.AuthenticationException if authentication fails or the query returns no results
|
||||
* @throws org.springframework.ldap.AuthenticationException if authentication
|
||||
* fails or the query returns no results
|
||||
*/
|
||||
void execute();
|
||||
|
||||
/**
|
||||
* Authenticate the query against the provided password.
|
||||
*
|
||||
* @param mapper a strategy for mapping the query results against another datasource
|
||||
* @throws org.springframework.ldap.AuthenticationException if authentication fails or the query returns no results
|
||||
* @param mapper a strategy for mapping the query results against another
|
||||
* datasource
|
||||
* @throws org.springframework.ldap.AuthenticationException if authentication
|
||||
* fails or the query returns no results
|
||||
*/
|
||||
<T> T execute(AuthenticatedLdapEntryContextMapper<T> mapper);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #bind} request.
|
||||
*/
|
||||
interface BindSpec {
|
||||
|
||||
/**
|
||||
* The object to associate with this binding.
|
||||
*
|
||||
* <p>
|
||||
* Note that this object is encoded into a set of attributes. If the object is
|
||||
* of type {@link DirContext}, then it will be converted into attributes via
|
||||
* Note that this object is encoded into a set of attributes. If the object is of
|
||||
* type {@link DirContext}, then it will be converted into attributes via
|
||||
* {@link DirContext#getAttributes}.
|
||||
*
|
||||
* @param object the object to associate
|
||||
* @return the {@link BindSpec} for further configuration
|
||||
*/
|
||||
@@ -498,9 +479,8 @@ public interface LdapClient {
|
||||
* Replace any existing binding with this one (equivalent to "rebind").
|
||||
*
|
||||
* <p>
|
||||
* If {@code false}, then bind will throw a {@link NameAlreadyBoundException} if the entry
|
||||
* already exists.
|
||||
*
|
||||
* If {@code false}, then bind will throw a {@link NameAlreadyBoundException} if
|
||||
* the entry already exists.
|
||||
* @param replaceExisting whether to replace any existing entry
|
||||
* @return the {@link BindSpec} for further configuration
|
||||
*/
|
||||
@@ -508,19 +488,20 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* Bind the name, object, and attributes together
|
||||
*
|
||||
* @throws NameAlreadyBoundException if {@code name} is already bound and {@link #replaceExisting} is {@code false}
|
||||
* @throws NameAlreadyBoundException if {@code name} is already bound and
|
||||
* {@link #replaceExisting} is {@code false}
|
||||
*/
|
||||
void execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #modify} request.
|
||||
*/
|
||||
interface ModifySpec {
|
||||
|
||||
/**
|
||||
* The new name for this entry.
|
||||
*
|
||||
* @param name the new name
|
||||
* @return the {@link ModifySpec} for further configuration
|
||||
*/
|
||||
@@ -528,7 +509,6 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* The new name for this entry.
|
||||
*
|
||||
* @param name the new name
|
||||
* @return the {@link ModifySpec} for further configuration
|
||||
*/
|
||||
@@ -536,7 +516,6 @@ public interface LdapClient {
|
||||
|
||||
/**
|
||||
* The attribute modifications to apply to this entry
|
||||
*
|
||||
* @param modifications the attribute modifications
|
||||
* @return the {@link ModifySpec} for further configuration
|
||||
*/
|
||||
@@ -546,15 +525,16 @@ public interface LdapClient {
|
||||
* Modify the name and attributes for this entry
|
||||
*/
|
||||
void execute();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The specifications for the {@link #unbind} request.
|
||||
*/
|
||||
interface UnbindSpec {
|
||||
|
||||
/**
|
||||
* Delete all children related to this entry
|
||||
*
|
||||
* @param recursive whether to delete all children as well
|
||||
* @return the {@link UnbindSpec} for further configuration
|
||||
*/
|
||||
@@ -564,5 +544,7 @@ public interface LdapClient {
|
||||
* Delete the entry
|
||||
*/
|
||||
void execute();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,34 +22,36 @@ import javax.naming.directory.DirContext;
|
||||
import javax.naming.ldap.LdapName;
|
||||
|
||||
/**
|
||||
* Wrapper class to handle the full identification of an LDAP entry. An LDAP
|
||||
* entry is identified by its Distinguished Name, in Spring LDAP represented by
|
||||
* the {@link DistinguishedName} class. A Distinguished Name can be absolute -
|
||||
* i.e. complete including the very root (base) of the LDAP tree - or relative -
|
||||
* i.e relative to the base LDAP path of the current LDAP connection (specified
|
||||
* as <code>base</code> to the {@link ContextSource}).
|
||||
* Wrapper class to handle the full identification of an LDAP entry. An LDAP entry is
|
||||
* identified by its Distinguished Name, in Spring LDAP represented by the
|
||||
* {@link DistinguishedName} class. A Distinguished Name can be absolute - i.e. complete
|
||||
* including the very root (base) of the LDAP tree - or relative - i.e relative to the
|
||||
* base LDAP path of the current LDAP connection (specified as <code>base</code> to the
|
||||
* {@link ContextSource}).
|
||||
* <p>
|
||||
* The different representations are needed on different occasions, e.g. the
|
||||
* relative DN is typically what is needed to perform lookups and searches in
|
||||
* the LDAP tree, whereas the absolute DN is needed when authenticating and when
|
||||
* an LDAP entry is referred to in e.g. a group. This wrapper class contains
|
||||
* both of these representations.
|
||||
*
|
||||
* The different representations are needed on different occasions, e.g. the relative DN
|
||||
* is typically what is needed to perform lookups and searches in the LDAP tree, whereas
|
||||
* the absolute DN is needed when authenticating and when an LDAP entry is referred to in
|
||||
* e.g. a group. This wrapper class contains both of these representations.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public class LdapEntryIdentification {
|
||||
|
||||
private final LdapName relativeDn;
|
||||
|
||||
private final LdapName absoluteDn;
|
||||
|
||||
/**
|
||||
* Construct an LdapEntryIdentification instance.
|
||||
* @param absoluteDn the absolute DN of the identified entry, e.g. as
|
||||
* returned by {@link DirContext#getNameInNamespace()}.
|
||||
* @param relativeDn the DN of the identified entry relative to the base
|
||||
* LDAP path, e.g. as returned by {@link DirContextOperations#getDn()}.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are deprecated as of 2.0.
|
||||
* use {@link #LdapEntryIdentification(javax.naming.ldap.LdapName, javax.naming.ldap.LdapName)} instead.
|
||||
* @param absoluteDn the absolute DN of the identified entry, e.g. as returned by
|
||||
* {@link DirContext#getNameInNamespace()}.
|
||||
* @param relativeDn the DN of the identified entry relative to the base LDAP path,
|
||||
* e.g. as returned by {@link DirContextOperations#getDn()}.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are
|
||||
* deprecated as of 2.0. use
|
||||
* {@link #LdapEntryIdentification(javax.naming.ldap.LdapName, javax.naming.ldap.LdapName)}
|
||||
* instead.
|
||||
*/
|
||||
public LdapEntryIdentification(DistinguishedName absoluteDn, DistinguishedName relativeDn) {
|
||||
Assert.notNull(absoluteDn, "Absolute DN must not be null");
|
||||
@@ -60,10 +62,10 @@ public class LdapEntryIdentification {
|
||||
|
||||
/**
|
||||
* Construct an LdapEntryIdentification instance.
|
||||
* @param absoluteDn the absolute DN of the identified entry, e.g. as
|
||||
* returned by {@link DirContext#getNameInNamespace()}.
|
||||
* @param relativeDn the DN of the identified entry relative to the base
|
||||
* LDAP path, e.g. as returned by {@link DirContextOperations#getDn()}.
|
||||
* @param absoluteDn the absolute DN of the identified entry, e.g. as returned by
|
||||
* {@link DirContext#getNameInNamespace()}.
|
||||
* @param relativeDn the DN of the identified entry relative to the base LDAP path,
|
||||
* e.g. as returned by {@link DirContextOperations#getDn()}.
|
||||
* @since 2.0
|
||||
*/
|
||||
public LdapEntryIdentification(LdapName absoluteDn, LdapName relativeDn) {
|
||||
@@ -74,8 +76,8 @@ public class LdapEntryIdentification {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DN of the identified entry relative to the base LDAP path, e.g.
|
||||
* as returned by {@link DirContextOperations#getDn()}.
|
||||
* Get the DN of the identified entry relative to the base LDAP path, e.g. as returned
|
||||
* by {@link DirContextOperations#getDn()}.
|
||||
* @return the relative DN.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -94,11 +96,11 @@ public class LdapEntryIdentification {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DN of the identified entry relative to the base LDAP path, e.g.
|
||||
* as returned by {@link DirContextOperations#getDn()}.
|
||||
* Get the DN of the identified entry relative to the base LDAP path, e.g. as returned
|
||||
* by {@link DirContextOperations#getDn()}.
|
||||
* @return the relative DN.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are deprecated as of 2.0.
|
||||
* use {@link #getRelativeName()} instead.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are
|
||||
* deprecated as of 2.0. use {@link #getRelativeName()} instead.
|
||||
*/
|
||||
public DistinguishedName getRelativeDn() {
|
||||
return new DistinguishedName(relativeDn);
|
||||
@@ -108,8 +110,8 @@ public class LdapEntryIdentification {
|
||||
* Get the absolute DN of the identified entry, e.g. as returned by
|
||||
* {@link DirContext#getNameInNamespace()}.
|
||||
* @return the absolute DN.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are deprecated as of 2.0.
|
||||
* use {@link #getAbsoluteName()} instead.
|
||||
* @deprecated {@link DistinguishedName} and associated classes and methods are
|
||||
* deprecated as of 2.0. use {@link #getAbsoluteName()} instead.
|
||||
*/
|
||||
public DistinguishedName getAbsoluteDn() {
|
||||
return new DistinguishedName(absoluteDn);
|
||||
@@ -127,4 +129,5 @@ public class LdapEntryIdentification {
|
||||
public int hashCode() {
|
||||
return absoluteDn.hashCode() ^ relativeDn.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ public class LdapEntryIdentificationContextMapper implements ContextMapper<LdapE
|
||||
|
||||
public LdapEntryIdentification mapFromContext(Object ctx) {
|
||||
DirContextOperations adapter = (DirContextOperations) ctx;
|
||||
return new LdapEntryIdentification(
|
||||
LdapUtils.newLdapName(adapter.getNameInNamespace()),
|
||||
return new LdapEntryIdentification(LdapUtils.newLdapName(adapter.getNameInNamespace()),
|
||||
LdapUtils.newLdapName(adapter.getDn()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,15 +31,17 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* Datatype for a LDAP name, a part of a path.
|
||||
*
|
||||
*
|
||||
* The name: uid=adam.skogman Key: uid Value: adam.skogman
|
||||
*
|
||||
*
|
||||
* @author Adam Skogman
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @deprecated {@link DistinguishedName} and associated classes are deprecated as of 2.0.
|
||||
*/
|
||||
public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
private static final long serialVersionUID = 5681397547245228750L;
|
||||
|
||||
private static final int DEFAULT_BUFFER_SIZE = 100;
|
||||
|
||||
private Map<String, LdapRdnComponent> components = new LinkedHashMap<String, LdapRdnComponent>();
|
||||
@@ -52,7 +54,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Parse the supplied string and construct this instance accordingly.
|
||||
*
|
||||
* @param string the string to parse.
|
||||
*/
|
||||
public LdapRdn(String string) {
|
||||
@@ -72,7 +73,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Construct an LdapRdn using the supplied key and value.
|
||||
*
|
||||
* @param key the attribute name.
|
||||
* @param value the attribute value.
|
||||
*/
|
||||
@@ -82,7 +82,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Add an LdapRdnComponent to this LdapRdn.
|
||||
*
|
||||
* @param rdnComponent the LdapRdnComponent to add.s
|
||||
*/
|
||||
public void addComponent(LdapRdnComponent rdnComponent) {
|
||||
@@ -91,7 +90,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Gets all components in this LdapRdn.
|
||||
*
|
||||
* @return the List of all LdapRdnComponents composing this LdapRdn.
|
||||
*/
|
||||
public List getComponents() {
|
||||
@@ -100,12 +98,11 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Gets the first LdapRdnComponent of this LdapRdn.
|
||||
*
|
||||
* @return The first LdapRdnComponent of this LdapRdn.
|
||||
* @throws IndexOutOfBoundsException if there are no components in this Rdn.
|
||||
*/
|
||||
public LdapRdnComponent getComponent() {
|
||||
if(components.size() == 0) {
|
||||
if (components.size() == 0) {
|
||||
throw new IndexOutOfBoundsException("No components");
|
||||
}
|
||||
|
||||
@@ -114,13 +111,12 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Get the LdapRdnComponent at index <code>idx</code>.
|
||||
*
|
||||
* @param idx the 0-based index of the component to get.
|
||||
* @return the LdapRdnComponent at index <code>idx</code>.
|
||||
* @throws IndexOutOfBoundsException if there are no components in this Rdn.
|
||||
*/
|
||||
public LdapRdnComponent getComponent(int idx) {
|
||||
if(idx >= components.size()) {
|
||||
if (idx >= components.size()) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
@@ -129,7 +125,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Get a properly rfc2253-encoded String representation of this LdapRdn.
|
||||
*
|
||||
* @return an escaped String corresponding to this LdapRdn.
|
||||
* @throws IndexOutOfBoundsException if there are no components in this Rdn.
|
||||
*/
|
||||
@@ -151,7 +146,6 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Get a String representation of this LdapRdn for use in urls.
|
||||
*
|
||||
* @return a String representation of this LdapRdn for use in urls.
|
||||
*/
|
||||
public String encodeUrl() {
|
||||
@@ -169,27 +163,25 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/**
|
||||
* Compare this LdapRdn to another object.
|
||||
*
|
||||
* @param obj the object to compare to.
|
||||
* @throws ClassCastException if the supplied object is not an LdapRdn
|
||||
* instance.
|
||||
* @throws ClassCastException if the supplied object is not an LdapRdn instance.
|
||||
*/
|
||||
public int compareTo(Object obj) {
|
||||
LdapRdn that = (LdapRdn) obj;
|
||||
|
||||
if(this.components.size() != that.components.size()) {
|
||||
if (this.components.size() != that.components.size()) {
|
||||
return this.components.size() - that.components.size();
|
||||
}
|
||||
|
||||
Set<Map.Entry<String,LdapRdnComponent>> theseEntries = this.components.entrySet();
|
||||
Set<Map.Entry<String, LdapRdnComponent>> theseEntries = this.components.entrySet();
|
||||
for (Map.Entry<String, LdapRdnComponent> oneEntry : theseEntries) {
|
||||
LdapRdnComponent thatEntry = that.components.get(oneEntry.getKey());
|
||||
if(thatEntry == null) {
|
||||
if (thatEntry == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int compared = oneEntry.getValue().compareTo(thatEntry);
|
||||
if(compared != 0) {
|
||||
if (compared != 0) {
|
||||
return compared;
|
||||
}
|
||||
}
|
||||
@@ -199,7 +191,7 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
@@ -209,13 +201,13 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
LdapRdn that = (LdapRdn) obj;
|
||||
|
||||
if(this.components.size() != that.components.size()) {
|
||||
if (this.components.size() != that.components.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<Map.Entry<String,LdapRdnComponent>> theseEntries = this.components.entrySet();
|
||||
Set<Map.Entry<String, LdapRdnComponent>> theseEntries = this.components.entrySet();
|
||||
for (Map.Entry<String, LdapRdnComponent> oneEntry : theseEntries) {
|
||||
if(!oneEntry.getValue().equals(that.components.get(oneEntry.getKey()))) {
|
||||
if (!oneEntry.getValue().equals(that.components.get(oneEntry.getKey()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -225,7 +217,7 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
@@ -234,7 +226,7 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
@@ -242,11 +234,9 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of this LdapRdn. Note that if this Rdn is multi-value the
|
||||
* first value will be returned. E.g. for the Rdn
|
||||
* <code>cn=john doe+sn=doe</code>, the return value would be
|
||||
* <code>john doe</code>.
|
||||
*
|
||||
* Get the value of this LdapRdn. Note that if this Rdn is multi-value the first value
|
||||
* will be returned. E.g. for the Rdn <code>cn=john doe+sn=doe</code>, the return
|
||||
* value would be <code>john doe</code>.
|
||||
* @return the (first) value of this LdapRdn.
|
||||
* @throws IndexOutOfBoundsException if there are no components in this Rdn.
|
||||
*/
|
||||
@@ -255,11 +245,9 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key of this LdapRdn. Note that if this Rdn is multi-value the
|
||||
* first key will be returned. E.g. for the Rdn
|
||||
* <code>cn=john doe+sn=doe</code>, the return value would be
|
||||
* <code>cn</code>.
|
||||
*
|
||||
* Get the key of this LdapRdn. Note that if this Rdn is multi-value the first key
|
||||
* will be returned. E.g. for the Rdn <code>cn=john doe+sn=doe</code>, the return
|
||||
* value would be <code>cn</code>.
|
||||
* @return the (first) key of this LdapRdn.
|
||||
* @throws IndexOutOfBoundsException if there are no components in this Rdn.
|
||||
*/
|
||||
@@ -268,13 +256,10 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the LdapComponent with the specified key (Attribute
|
||||
* name).
|
||||
*
|
||||
* Get the value of the LdapComponent with the specified key (Attribute name).
|
||||
* @param key the key
|
||||
* @return the value.
|
||||
* @throws IllegalArgumentException if there is no component with the
|
||||
* specified key.
|
||||
* @throws IllegalArgumentException if there is no component with the specified key.
|
||||
*/
|
||||
public String getValue(String key) {
|
||||
for (Iterator iter = components.values().iterator(); iter.hasNext();) {
|
||||
@@ -288,21 +273,23 @@ public class LdapRdn implements Serializable, Comparable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an immutable copy of this instance. It will not be possible to add
|
||||
* or remove components or modify the keys and values of these components.
|
||||
*
|
||||
* Create an immutable copy of this instance. It will not be possible to add or remove
|
||||
* components or modify the keys and values of these components.
|
||||
* @return an immutable copy of this instance.
|
||||
* @since 1.3
|
||||
*/
|
||||
public LdapRdn immutableLdapRdn() {
|
||||
Map<String, LdapRdnComponent> mapWithImmutableRdns = new LinkedHashMap<String, LdapRdnComponent>(components.size());
|
||||
Map<String, LdapRdnComponent> mapWithImmutableRdns = new LinkedHashMap<String, LdapRdnComponent>(
|
||||
components.size());
|
||||
for (Iterator iterator = components.values().iterator(); iterator.hasNext();) {
|
||||
LdapRdnComponent rdnComponent = (LdapRdnComponent) iterator.next();
|
||||
mapWithImmutableRdns.put(rdnComponent.getKey(), rdnComponent.immutableLdapRdnComponent());
|
||||
}
|
||||
Map<String, LdapRdnComponent> unmodifiableMapOfImmutableRdns = Collections.unmodifiableMap(mapWithImmutableRdns);
|
||||
Map<String, LdapRdnComponent> unmodifiableMapOfImmutableRdns = Collections
|
||||
.unmodifiableMap(mapWithImmutableRdns);
|
||||
LdapRdn immutableRdn = new LdapRdn();
|
||||
immutableRdn.components = unmodifiableMapOfImmutableRdns;
|
||||
return immutableRdn;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,14 +26,15 @@ import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
* Represents part of an LdapRdn. As specified in RFC2253 an LdapRdn may be
|
||||
* composed of several attributes, separated by "+". An
|
||||
* LdapRdnComponent represents one of these attributes.
|
||||
*
|
||||
* Represents part of an LdapRdn. As specified in RFC2253 an LdapRdn may be composed of
|
||||
* several attributes, separated by "+". An LdapRdnComponent represents one of
|
||||
* these attributes.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @deprecated {@link DistinguishedName} and associated classes are deprecated as of 2.0.
|
||||
*/
|
||||
public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -3296747972616243038L;
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(LdapRdnComponent.class);
|
||||
@@ -46,7 +47,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Constructs an LdapRdnComponent without decoding the value.
|
||||
*
|
||||
* @param key the Attribute name.
|
||||
* @param value the Attribute value.
|
||||
*/
|
||||
@@ -57,15 +57,13 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
/**
|
||||
* Constructs an LdapRdnComponent, optionally decoding the value.
|
||||
* <p>
|
||||
* Depending on the value of the "key case fold" System property, the keys
|
||||
* will be lowercased, uppercased, or preserve their original case. Default
|
||||
* is to convert them to lowercase.
|
||||
*
|
||||
* Depending on the value of the "key case fold" System property, the keys will be
|
||||
* lowercased, uppercased, or preserve their original case. Default is to convert them
|
||||
* to lowercase.
|
||||
* @param key the Attribute name.
|
||||
* @param value the Attribute value.
|
||||
* @param decodeValue if <code>true</code> the value is decoded (typically
|
||||
* used when a DN is parsed from a String), otherwise the value is used as
|
||||
* specified.
|
||||
* @param decodeValue if <code>true</code> the value is decoded (typically used when a
|
||||
* DN is parsed from a String), otherwise the value is used as specified.
|
||||
* @see DistinguishedName#KEY_CASE_FOLD_PROPERTY
|
||||
*/
|
||||
public LdapRdnComponent(String key, String value, boolean decodeValue) {
|
||||
@@ -75,16 +73,18 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
String caseFold = System.getProperty(DistinguishedName.KEY_CASE_FOLD_PROPERTY);
|
||||
if (!StringUtils.hasText(caseFold) || caseFold.equals(DistinguishedName.KEY_CASE_FOLD_LOWER)) {
|
||||
this.key = key.toLowerCase();
|
||||
} else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_UPPER)) {
|
||||
}
|
||||
else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_UPPER)) {
|
||||
this.key = key.toUpperCase();
|
||||
} else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_NONE)) {
|
||||
}
|
||||
else if (caseFold.equals(DistinguishedName.KEY_CASE_FOLD_NONE)) {
|
||||
this.key = key;
|
||||
} else {
|
||||
LOG
|
||||
.warn("\"" + caseFold + "\" invalid property value for " + DistinguishedName.KEY_CASE_FOLD_PROPERTY
|
||||
+ "; expected \"" + DistinguishedName.KEY_CASE_FOLD_LOWER + "\", \""
|
||||
+ DistinguishedName.KEY_CASE_FOLD_UPPER + "\", or \""
|
||||
+ DistinguishedName.KEY_CASE_FOLD_NONE + "\"");
|
||||
}
|
||||
else {
|
||||
LOG.warn("\"" + caseFold + "\" invalid property value for " + DistinguishedName.KEY_CASE_FOLD_PROPERTY
|
||||
+ "; expected \"" + DistinguishedName.KEY_CASE_FOLD_LOWER + "\", \""
|
||||
+ DistinguishedName.KEY_CASE_FOLD_UPPER + "\", or \"" + DistinguishedName.KEY_CASE_FOLD_NONE
|
||||
+ "\"");
|
||||
this.key = key.toLowerCase();
|
||||
}
|
||||
if (decodeValue) {
|
||||
@@ -97,7 +97,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Get the key (Attribute name) of this component.
|
||||
*
|
||||
* @return the key.
|
||||
*/
|
||||
public String getKey() {
|
||||
@@ -106,7 +105,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Set the key (Attribute name) of this component.
|
||||
*
|
||||
* @param key the key.
|
||||
* @deprecated Using this method changes the internal state of surrounding
|
||||
* DistinguishedName instance. This should be avoided.
|
||||
@@ -118,7 +116,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Get the (Attribute) value of this component.
|
||||
*
|
||||
* @return the value.
|
||||
*/
|
||||
public String getValue() {
|
||||
@@ -127,7 +124,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Set the (Attribute) value of this component.
|
||||
*
|
||||
* @param value the value.
|
||||
* @deprecated Using this method changes the internal state of surrounding
|
||||
* DistinguishedName instance. This should be avoided.
|
||||
@@ -139,7 +135,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Encode key and value to ldap.
|
||||
*
|
||||
* @return Properly ldap escaped rdn.
|
||||
*/
|
||||
protected String encodeLdap() {
|
||||
@@ -154,7 +149,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
public String toString() {
|
||||
@@ -170,7 +165,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Get a String representation of this instance for use in URLs.
|
||||
*
|
||||
* @return a properly URL encoded representation of this instancs.
|
||||
*/
|
||||
public String encodeUrl() {
|
||||
@@ -187,7 +181,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
@@ -196,7 +190,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
@@ -206,8 +200,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
LdapRdnComponent that = (LdapRdnComponent) obj;
|
||||
// It's safe to compare directly against key and value,
|
||||
// because they are validated not to be null on instance creation.
|
||||
return this.key.equalsIgnoreCase(that.key)
|
||||
&& this.value.equalsIgnoreCase(that.value);
|
||||
return this.key.equalsIgnoreCase(that.key) && this.value.equalsIgnoreCase(that.value);
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -217,7 +210,6 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
|
||||
/**
|
||||
* Compare this instance to the supplied object.
|
||||
*
|
||||
* @param obj the object to compare to.
|
||||
* @throws ClassCastException if the object is not possible to cast to an
|
||||
* LdapRdnComponent.
|
||||
@@ -228,17 +220,17 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
// It's safe to compare directly against key and value,
|
||||
// because they are validated not to be null on instance creation.
|
||||
int keyCompare = this.key.toLowerCase().compareTo(that.key.toLowerCase());
|
||||
if(keyCompare == 0) {
|
||||
if (keyCompare == 0) {
|
||||
return this.value.toLowerCase().compareTo(that.value.toLowerCase());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return keyCompare;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an immutable copy of this instance. It will not be possible to
|
||||
* modify the key or the value of the returned instance.
|
||||
*
|
||||
* Create an immutable copy of this instance. It will not be possible to modify the
|
||||
* key or the value of the returned instance.
|
||||
* @return an immutable copy of this instance.
|
||||
* @since 1.3
|
||||
*/
|
||||
@@ -247,6 +239,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
}
|
||||
|
||||
private static class ImmutableLdapRdnComponent extends LdapRdnComponent {
|
||||
|
||||
private static final long serialVersionUID = -7099970046426346567L;
|
||||
|
||||
public ImmutableLdapRdnComponent(String key, String value) {
|
||||
@@ -260,5 +253,7 @@ public class LdapRdnComponent implements Comparable, Serializable {
|
||||
public void setValue(String value) {
|
||||
throw new UnsupportedOperationException("SetKey not supported for this immutable LdapRdnComponent");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,23 +56,21 @@ import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
/**
|
||||
* Executes core LDAP functionality and helps to avoid common errors, relieving
|
||||
* the user of the burden of looking up contexts, looping through
|
||||
* NamingEnumerations and closing contexts.
|
||||
* Executes core LDAP functionality and helps to avoid common errors, relieving the user
|
||||
* of the burden of looking up contexts, looping through NamingEnumerations and closing
|
||||
* contexts.
|
||||
* <p>
|
||||
* <b>Note for Active Directory (AD) users:</b> AD servers are apparently unable
|
||||
* to handle referrals automatically, which causes a
|
||||
* <code>PartialResultException</code> to be thrown whenever a referral is
|
||||
* encountered in a search. To avoid this, set the
|
||||
* <code>ignorePartialResultException</code> property to <code>true</code>.
|
||||
* There is currently no way of manually handling these referrals in the form of
|
||||
* <code>ReferralException</code>, i.e. either you get the exception (and your
|
||||
* results are lost) or all referrals are ignored (if the server is unable to
|
||||
* handle them properly. Neither is there any simple way to get notified that a
|
||||
* <b>Note for Active Directory (AD) users:</b> AD servers are apparently unable to handle
|
||||
* referrals automatically, which causes a <code>PartialResultException</code> to be
|
||||
* thrown whenever a referral is encountered in a search. To avoid this, set the
|
||||
* <code>ignorePartialResultException</code> property to <code>true</code>. There is
|
||||
* currently no way of manually handling these referrals in the form of
|
||||
* <code>ReferralException</code>, i.e. either you get the exception (and your results are
|
||||
* lost) or all referrals are ignored (if the server is unable to handle them properly.
|
||||
* Neither is there any simple way to get notified that a
|
||||
* <code>PartialResultException</code> has been ignored (other than in the log).
|
||||
*
|
||||
*
|
||||
* @see org.springframework.ldap.core.ContextSource
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Ulrik Sandberg
|
||||
*/
|
||||
@@ -110,7 +108,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
|
||||
/**
|
||||
* Constructor to setup instance directly.
|
||||
*
|
||||
* @param contextSource the ContextSource to use.
|
||||
*/
|
||||
public LdapTemplate(ContextSource contextSource) {
|
||||
@@ -118,9 +115,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ContextSource. Call this method when the default constructor has
|
||||
* been used.
|
||||
*
|
||||
* Set the ContextSource. Call this method when the default constructor has been used.
|
||||
* @param contextSource the ContextSource.
|
||||
*/
|
||||
public void setContextSource(ContextSource contextSource) {
|
||||
@@ -137,7 +132,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
|
||||
/**
|
||||
* Set the ObjectDirectoryMapper instance to use.
|
||||
*
|
||||
* @param odm the ObejctDirectoryMapper to use.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -147,7 +141,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
|
||||
/**
|
||||
* Get the ContextSource.
|
||||
*
|
||||
* @return the ContextSource.
|
||||
*/
|
||||
public ContextSource getContextSource() {
|
||||
@@ -155,18 +148,15 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether <code>NameNotFoundException</code> should be ignored in
|
||||
* searches. In previous version, <code>NameNotFoundException</code> caused
|
||||
* by the search base not being found was silently ignored. The default
|
||||
* behavior is now to treat this as an error (as it should), and to convert
|
||||
* and re-throw the exception. The ability to revert to the previous
|
||||
* behavior still exists. The only difference is that the incident is in
|
||||
* that case no longer silently ignored, but logged as a warning.
|
||||
*
|
||||
* @param ignore <code>true</code> if <code>NameNotFoundException</code>
|
||||
* should be ignored in searches, <code>false</code> otherwise. Default is
|
||||
* <code>false</code>.
|
||||
*
|
||||
* Specify whether <code>NameNotFoundException</code> should be ignored in searches.
|
||||
* In previous version, <code>NameNotFoundException</code> caused by the search base
|
||||
* not being found was silently ignored. The default behavior is now to treat this as
|
||||
* an error (as it should), and to convert and re-throw the exception. The ability to
|
||||
* revert to the previous behavior still exists. The only difference is that the
|
||||
* incident is in that case no longer silently ignored, but logged as a warning.
|
||||
* @param ignore <code>true</code> if <code>NameNotFoundException</code> should be
|
||||
* ignored in searches, <code>false</code> otherwise. Default is <code>false</code>.
|
||||
*
|
||||
* @since 1.3
|
||||
*/
|
||||
public void setIgnoreNameNotFoundException(boolean ignore) {
|
||||
@@ -174,32 +164,27 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether <code>PartialResultException</code> should be ignored in
|
||||
* searches. AD servers typically have a problem with referrals. Normally a
|
||||
* referral should be followed automatically, but this does not seem to work
|
||||
* with AD servers. The problem manifests itself with a
|
||||
* <code>PartialResultException</code> being thrown when a referral is
|
||||
* encountered by the server. Setting this property to <code>true</code>
|
||||
* Specify whether <code>PartialResultException</code> should be ignored in searches.
|
||||
* AD servers typically have a problem with referrals. Normally a referral should be
|
||||
* followed automatically, but this does not seem to work with AD servers. The problem
|
||||
* manifests itself with a <code>PartialResultException</code> being thrown when a
|
||||
* referral is encountered by the server. Setting this property to <code>true</code>
|
||||
* presents a workaround to this problem by causing
|
||||
* <code>PartialResultException</code> to be ignored, so that the search
|
||||
* method returns normally. Default value of this parameter is
|
||||
* <code>false</code>.
|
||||
*
|
||||
* @param ignore <code>true</code> if <code>PartialResultException</code>
|
||||
* should be ignored in searches, <code>false</code> otherwise. Default is
|
||||
* <code>false</code>.
|
||||
* <code>PartialResultException</code> to be ignored, so that the search method
|
||||
* returns normally. Default value of this parameter is <code>false</code>.
|
||||
* @param ignore <code>true</code> if <code>PartialResultException</code> should be
|
||||
* ignored in searches, <code>false</code> otherwise. Default is <code>false</code>.
|
||||
*/
|
||||
public void setIgnorePartialResultException(boolean ignore) {
|
||||
this.ignorePartialResultException = ignore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether <code>SizeLimitExceededException</code> should be ignored in searches.
|
||||
* This is typically what you want if you specify count limit in your search controls.
|
||||
*
|
||||
* @param ignore <code>true</code> if <code>SizeLimitExceededException</code>
|
||||
* should be ignored in searches, <code>false</code> otherwise. Default is
|
||||
* <code>true</code>.
|
||||
* Specify whether <code>SizeLimitExceededException</code> should be ignored in
|
||||
* searches. This is typically what you want if you specify count limit in your search
|
||||
* controls.
|
||||
* @param ignore <code>true</code> if <code>SizeLimitExceededException</code> should
|
||||
* be ignored in searches, <code>false</code> otherwise. Default is <code>true</code>.
|
||||
* @since 2.0
|
||||
*/
|
||||
public void setIgnoreSizeLimitExceededException(boolean ignore) {
|
||||
@@ -207,13 +192,11 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default scope to be used in searches if not explicitly specified.
|
||||
* Default is {@link javax.naming.directory.SearchControls#SUBTREE_SCOPE}.
|
||||
*
|
||||
* @param defaultSearchScope the default search scope to use in searches.
|
||||
* One of {@link SearchControls#OBJECT_SCOPE},
|
||||
* {@link SearchControls#ONELEVEL_SCOPE},
|
||||
* or {@link SearchControls#SUBTREE_SCOPE}
|
||||
* Set the default scope to be used in searches if not explicitly specified. Default
|
||||
* is {@link javax.naming.directory.SearchControls#SUBTREE_SCOPE}.
|
||||
* @param defaultSearchScope the default search scope to use in searches. One of
|
||||
* {@link SearchControls#OBJECT_SCOPE}, {@link SearchControls#ONELEVEL_SCOPE}, or
|
||||
* {@link SearchControls#SUBTREE_SCOPE}
|
||||
* @since 2.0
|
||||
*/
|
||||
public void setDefaultSearchScope(int defaultSearchScope) {
|
||||
@@ -221,9 +204,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default time limit be used in searches if not explicitly specified.
|
||||
* Default is 0, indicating no time limit.
|
||||
*
|
||||
* Set the default time limit be used in searches if not explicitly specified. Default
|
||||
* is 0, indicating no time limit.
|
||||
* @param defaultTimeLimit the default time limit to use in searches.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -234,7 +216,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
/**
|
||||
* Set the default count limit be used in searches if not explicitly specified.
|
||||
* Default is 0, indicating no count limit.
|
||||
*
|
||||
* @param defaultCountLimit the default count limit to use in searches.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -339,28 +320,25 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search operation, such as a search(), list() or listBindings().
|
||||
* This method handles all the plumbing; getting a readonly context; looping
|
||||
* through the NamingEnumeration and closing the context and enumeration. It
|
||||
* also calls the supplied DirContextProcessor before and after the search,
|
||||
* respectively. This enables custom pre-processing and post-processing,
|
||||
* like for example when handling paged results or other search controls.
|
||||
* Perform a search operation, such as a search(), list() or listBindings(). This
|
||||
* method handles all the plumbing; getting a readonly context; looping through the
|
||||
* NamingEnumeration and closing the context and enumeration. It also calls the
|
||||
* supplied DirContextProcessor before and after the search, respectively. This
|
||||
* enables custom pre-processing and post-processing, like for example when handling
|
||||
* paged results or other search controls.
|
||||
* <p>
|
||||
* The actual list is delegated to the {@link SearchExecutor} and each
|
||||
* {@link NameClassPair} (this might be a NameClassPair or a subclass
|
||||
* thereof) is passed to the CallbackHandler. Any encountered
|
||||
* NamingException will be translated using the NamingExceptionTranslator.
|
||||
*
|
||||
* {@link NameClassPair} (this might be a NameClassPair or a subclass thereof) is
|
||||
* passed to the CallbackHandler. Any encountered NamingException will be translated
|
||||
* using the NamingExceptionTranslator.
|
||||
* @param se the SearchExecutor to use for performing the actual list.
|
||||
* @param handler the NameClassPairCallbackHandler to which each found entry
|
||||
* will be passed.
|
||||
* @param processor DirContextProcessor for custom pre- and post-processing.
|
||||
* Must not be <code>null</code>. If no custom processing should take place,
|
||||
* please use e.g.
|
||||
* @param handler the NameClassPairCallbackHandler to which each found entry will be
|
||||
* passed.
|
||||
* @param processor DirContextProcessor for custom pre- and post-processing. Must not
|
||||
* be <code>null</code>. If no custom processing should take place, please use e.g.
|
||||
* {@link #search(SearchExecutor, NameClassPairCallbackHandler)}.
|
||||
* @throws NamingException if any error occurs. Note that a
|
||||
* NameNotFoundException will be ignored. Instead this is interpreted that
|
||||
* no entries were found.
|
||||
* @throws NamingException if any error occurs. Note that a NameNotFoundException will
|
||||
* be ignored. Instead this is interpreted that no entries were found.
|
||||
*/
|
||||
@Override
|
||||
public void search(SearchExecutor se, NameClassPairCallbackHandler handler, DirContextProcessor processor) {
|
||||
@@ -395,8 +373,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
ex = LdapUtils.convertLdapException(e);
|
||||
}
|
||||
}
|
||||
catch(SizeLimitExceededException e) {
|
||||
if(ignoreSizeLimitExceededException) {
|
||||
catch (SizeLimitExceededException e) {
|
||||
if (ignoreSizeLimitExceededException) {
|
||||
LOG.debug("SizeLimitExceededException encountered and ignored", e);
|
||||
}
|
||||
else {
|
||||
@@ -429,21 +407,19 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search operation, such as a search(), list() or listBindings().
|
||||
* This method handles all the plumbing; getting a readonly context; looping
|
||||
* through the NamingEnumeration and closing the context and enumeration.
|
||||
* Perform a search operation, such as a search(), list() or listBindings(). This
|
||||
* method handles all the plumbing; getting a readonly context; looping through the
|
||||
* NamingEnumeration and closing the context and enumeration.
|
||||
* <p>
|
||||
* The actual list is delegated to the {@link SearchExecutor} and each
|
||||
* {@link NameClassPair} (this might be a NameClassPair or a subclass
|
||||
* thereof) is passed to the CallbackHandler. Any encountered
|
||||
* NamingException will be translated using the NamingExceptionTranslator.
|
||||
*
|
||||
* {@link NameClassPair} (this might be a NameClassPair or a subclass thereof) is
|
||||
* passed to the CallbackHandler. Any encountered NamingException will be translated
|
||||
* using the NamingExceptionTranslator.
|
||||
* @param se the SearchExecutor to use for performing the actual list.
|
||||
* @param handler the NameClassPairCallbackHandler to which each found entry
|
||||
* will be passed.
|
||||
* @throws NamingException if any error occurs. Note that a
|
||||
* NameNotFoundException will be ignored. Instead this is interpreted that
|
||||
* no entries were found.
|
||||
* @param handler the NameClassPairCallbackHandler to which each found entry will be
|
||||
* passed.
|
||||
* @throws NamingException if any error occurs. Note that a NameNotFoundException will
|
||||
* be ignored. Instead this is interpreted that no entries were found.
|
||||
*/
|
||||
@Override
|
||||
public void search(SearchExecutor se, NameClassPairCallbackHandler handler) {
|
||||
@@ -687,7 +663,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> list(String base, NameClassPairMapper<T> mapper) {
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(mapper);
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(
|
||||
mapper);
|
||||
list(base, handler);
|
||||
return handler.getList();
|
||||
}
|
||||
@@ -697,7 +674,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> list(Name base, NameClassPairMapper<T> mapper) {
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(mapper);
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(
|
||||
mapper);
|
||||
list(base, handler);
|
||||
return handler.getList();
|
||||
}
|
||||
@@ -751,7 +729,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> listBindings(String base, NameClassPairMapper<T> mapper) {
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(mapper);
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(
|
||||
mapper);
|
||||
listBindings(base, handler);
|
||||
return handler.getList();
|
||||
}
|
||||
@@ -761,7 +740,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public <T> List<T> listBindings(Name base, NameClassPairMapper<T> mapper) {
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(mapper);
|
||||
CollectingNameClassPairCallbackHandler<T> handler = new MappingCollectingNameClassPairCallbackHandler<T>(
|
||||
mapper);
|
||||
listBindings(base, handler);
|
||||
return handler.getList();
|
||||
}
|
||||
@@ -1098,7 +1078,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
|
||||
/**
|
||||
* Delete all subcontexts including the current one recursively.
|
||||
*
|
||||
* @param ctx The context to use for deleting.
|
||||
* @param name The starting point to delete recursively.
|
||||
* @throws NamingException if any error occurs
|
||||
@@ -1199,9 +1178,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the supplied DirContext if it is not null. Swallow any exceptions,
|
||||
* as this is only for cleanup.
|
||||
*
|
||||
* Close the supplied DirContext if it is not null. Swallow any exceptions, as this is
|
||||
* only for cleanup.
|
||||
* @param ctx the context to close.
|
||||
*/
|
||||
private void closeContext(DirContext ctx) {
|
||||
@@ -1216,9 +1194,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the supplied NamingEnumeration if it is not null. Swallow any
|
||||
* exceptions, as this is only for cleanup.
|
||||
*
|
||||
* Close the supplied NamingEnumeration if it is not null. Swallow any exceptions, as
|
||||
* this is only for cleanup.
|
||||
* @param results the NamingEnumeration to close.
|
||||
*/
|
||||
private void closeNamingEnumeration(NamingEnumeration results) {
|
||||
@@ -1243,9 +1220,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure the returnObjFlag is set in the supplied SearchControls. Set it
|
||||
* and log if it's not set.
|
||||
*
|
||||
* Make sure the returnObjFlag is set in the supplied SearchControls. Set it and log
|
||||
* if it's not set.
|
||||
* @param controls the SearchControls to check.
|
||||
*/
|
||||
private void assureReturnObjFlagSet(SearchControls controls) {
|
||||
@@ -1264,6 +1240,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
* @since 2.0
|
||||
*/
|
||||
public static final class NullDirContextProcessor implements DirContextProcessor {
|
||||
|
||||
public void postProcess(DirContext ctx) {
|
||||
// Do nothing
|
||||
}
|
||||
@@ -1271,16 +1248,17 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public void preProcess(DirContext ctx) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link NameClassPairCallbackHandler} that passes the NameClassPairs
|
||||
* found to a NameClassPairMapper and collects the results in a list.
|
||||
*
|
||||
* A {@link NameClassPairCallbackHandler} that passes the NameClassPairs found to a
|
||||
* NameClassPairMapper and collects the results in a list.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public final static class MappingCollectingNameClassPairCallbackHandler<T> extends
|
||||
CollectingNameClassPairCallbackHandler<T> {
|
||||
public final static class MappingCollectingNameClassPairCallbackHandler<T>
|
||||
extends CollectingNameClassPairCallbackHandler<T> {
|
||||
|
||||
private NameClassPairMapper<T> mapper;
|
||||
|
||||
@@ -1299,6 +1277,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1345,7 +1324,6 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -1356,8 +1334,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
rebind(dn, ctx, null);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"The DirContextOperations instance needs to be properly initialized.");
|
||||
throw new IllegalStateException("The DirContextOperations instance needs to be properly initialized.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1366,8 +1343,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public boolean authenticate(Name base, String filter, String password) {
|
||||
return authenticate(base, filter, password,
|
||||
new NullAuthenticatedLdapEntryContextCallback(),
|
||||
return authenticate(base, filter, password, new NullAuthenticatedLdapEntryContextCallback(),
|
||||
new NullAuthenticationErrorCallback());
|
||||
}
|
||||
|
||||
@@ -1377,8 +1353,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public boolean authenticate(String base, String filter, String password) {
|
||||
return authenticate(LdapUtils.newLdapName(base), filter, password,
|
||||
new NullAuthenticatedLdapEntryContextCallback(),
|
||||
new NullAuthenticationErrorCallback());
|
||||
new NullAuthenticatedLdapEntryContextCallback(), new NullAuthenticationErrorCallback());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1387,7 +1362,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public boolean authenticate(String base, String filter, String password,
|
||||
AuthenticatedLdapEntryContextCallback callback) {
|
||||
return authenticate(LdapUtils.newLdapName(base), filter, password, callback, new NullAuthenticationErrorCallback());
|
||||
return authenticate(LdapUtils.newLdapName(base), filter, password, callback,
|
||||
new NullAuthenticationErrorCallback());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1405,7 +1381,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public boolean authenticate(String base, String filter, String password,
|
||||
AuthenticationErrorCallback errorCallback) {
|
||||
return authenticate(LdapUtils.newLdapName(base), filter, password, new NullAuthenticatedLdapEntryContextCallback(), errorCallback);
|
||||
return authenticate(LdapUtils.newLdapName(base), filter, password,
|
||||
new NullAuthenticatedLdapEntryContextCallback(), errorCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1433,27 +1410,21 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public boolean authenticate(Name base, String filter, String password,
|
||||
final AuthenticatedLdapEntryContextCallback callback, final AuthenticationErrorCallback errorCallback) {
|
||||
|
||||
return authenticate(base,
|
||||
filter,
|
||||
password,
|
||||
getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, null),
|
||||
callback,
|
||||
errorCallback).isSuccess();
|
||||
return authenticate(base, filter, password, getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, null),
|
||||
callback, errorCallback).isSuccess();
|
||||
}
|
||||
|
||||
private AuthenticationStatus authenticate(Name base,
|
||||
String filter,
|
||||
String password,
|
||||
SearchControls searchControls,
|
||||
final AuthenticatedLdapEntryContextCallback callback,
|
||||
final AuthenticationErrorCallback errorCallback) {
|
||||
private AuthenticationStatus authenticate(Name base, String filter, String password, SearchControls searchControls,
|
||||
final AuthenticatedLdapEntryContextCallback callback, final AuthenticationErrorCallback errorCallback) {
|
||||
|
||||
List<LdapEntryIdentification> result = search(base, filter, searchControls, new LdapEntryIdentificationContextMapper());
|
||||
List<LdapEntryIdentification> result = search(base, filter, searchControls,
|
||||
new LdapEntryIdentificationContextMapper());
|
||||
if (result.size() == 0) {
|
||||
String msg = "No results found for search, base: '" + base + "'; filter: '" + filter + "'.";
|
||||
LOG.info(msg);
|
||||
return AuthenticationStatus.EMPTYRESULT;
|
||||
} else if (result.size() > 1) {
|
||||
}
|
||||
else if (result.size() > 1) {
|
||||
String msg = "base: '" + base + "'; filter: '" + filter + "'.";
|
||||
throw new IncorrectResultSizeDataAccessException(msg, 1, result.size());
|
||||
}
|
||||
@@ -1483,29 +1454,27 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public <T> T authenticate(LdapQuery query, String password, AuthenticatedLdapEntryContextMapper<T> mapper) {
|
||||
SearchControls searchControls = searchControlsForQuery(query, RETURN_OBJ_FLAG);
|
||||
ReturningAuthenticatedLdapEntryContext<T> mapperCallback =
|
||||
new ReturningAuthenticatedLdapEntryContext<T>(mapper);
|
||||
CollectingAuthenticationErrorCallback errorCallback =
|
||||
new CollectingAuthenticationErrorCallback();
|
||||
ReturningAuthenticatedLdapEntryContext<T> mapperCallback = new ReturningAuthenticatedLdapEntryContext<T>(
|
||||
mapper);
|
||||
CollectingAuthenticationErrorCallback errorCallback = new CollectingAuthenticationErrorCallback();
|
||||
|
||||
AuthenticationStatus authenticationStatus = authenticate(query.base(),
|
||||
query.filter().encode(),
|
||||
password,
|
||||
searchControls,
|
||||
mapperCallback,
|
||||
errorCallback);
|
||||
AuthenticationStatus authenticationStatus = authenticate(query.base(), query.filter().encode(), password,
|
||||
searchControls, mapperCallback, errorCallback);
|
||||
|
||||
if(errorCallback.hasError()) {
|
||||
if (errorCallback.hasError()) {
|
||||
Exception error = errorCallback.getError();
|
||||
|
||||
if (error instanceof NamingException) {
|
||||
throw (NamingException) error;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new UncategorizedLdapException(error);
|
||||
}
|
||||
} else if(AuthenticationStatus.EMPTYRESULT == authenticationStatus) {
|
||||
}
|
||||
else if (AuthenticationStatus.EMPTYRESULT == authenticationStatus) {
|
||||
throw new EmptyResultDataAccessException(1);
|
||||
} else if(!authenticationStatus.isSuccess()) {
|
||||
}
|
||||
else if (!authenticationStatus.isSuccess()) {
|
||||
throw new AuthenticationException();
|
||||
}
|
||||
|
||||
@@ -1517,9 +1486,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public void authenticate(LdapQuery query, String password) {
|
||||
authenticate(query,
|
||||
password,
|
||||
new NullAuthenticatedLdapEntryContextCallback());
|
||||
authenticate(query, password, new NullAuthenticatedLdapEntryContextCallback());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1527,10 +1494,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
*/
|
||||
@Override
|
||||
public <T> T searchForObject(Name base, String filter, ContextMapper<T> mapper) {
|
||||
return searchForObject(base,
|
||||
filter,
|
||||
getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, ALL_ATTRIBUTES),
|
||||
mapper);
|
||||
return searchForObject(base, filter,
|
||||
getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, ALL_ATTRIBUTES), mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1545,7 +1510,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <T> T searchForObject (Name base, String filter, SearchControls searchControls, ContextMapper<T> mapper) {
|
||||
public <T> T searchForObject(Name base, String filter, SearchControls searchControls, ContextMapper<T> mapper) {
|
||||
List<T> result = search(base, filter, searchControls, mapper);
|
||||
|
||||
if (result.size() == 0) {
|
||||
@@ -1567,9 +1532,9 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
private static final class NullAuthenticatedLdapEntryContextCallback
|
||||
implements AuthenticatedLdapEntryContextCallback, AuthenticatedLdapEntryContextMapper<Object>{
|
||||
public void executeWithContext(DirContext ctx,
|
||||
LdapEntryIdentification ldapEntryIdentification) {
|
||||
implements AuthenticatedLdapEntryContextCallback, AuthenticatedLdapEntryContextMapper<Object> {
|
||||
|
||||
public void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@@ -1577,17 +1542,20 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public Object mapWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class NullAuthenticationErrorCallback
|
||||
implements AuthenticationErrorCallback {
|
||||
private static final class NullAuthenticationErrorCallback implements AuthenticationErrorCallback {
|
||||
|
||||
public void execute(Exception e) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class ReturningAuthenticatedLdapEntryContext<T>
|
||||
implements AuthenticatedLdapEntryContextCallback {
|
||||
|
||||
private final AuthenticatedLdapEntryContextMapper<T> mapper;
|
||||
|
||||
private T collectedObject;
|
||||
@@ -1603,6 +1571,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public void executeWithContext(DirContext ctx, LdapEntryIdentification ldapEntryIdentification) {
|
||||
collectedObject = mapper.mapWithContext(ctx, ldapEntryIdentification);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1611,10 +1580,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public void search(LdapQuery query, NameClassPairCallbackHandler callbackHandler) {
|
||||
SearchControls searchControls = searchControlsForQuery(query, DONT_RETURN_OBJ_FLAG);
|
||||
search(query.base(),
|
||||
query.filter().encode(),
|
||||
searchControls,
|
||||
callbackHandler);
|
||||
search(query.base(), query.filter().encode(), searchControls, callbackHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1624,28 +1590,22 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public <T> List<T> search(LdapQuery query, ContextMapper<T> mapper) {
|
||||
SearchControls searchControls = searchControlsForQuery(query, RETURN_OBJ_FLAG);
|
||||
|
||||
return search(query.base(),
|
||||
query.filter().encode(),
|
||||
searchControls,
|
||||
mapper);
|
||||
return search(query.base(), query.filter().encode(), searchControls, mapper);
|
||||
|
||||
}
|
||||
|
||||
private SearchControls searchControlsForQuery(LdapQuery query, boolean returnObjFlag) {
|
||||
SearchControls searchControls = getDefaultSearchControls(
|
||||
defaultSearchScope,
|
||||
returnObjFlag,
|
||||
query.attributes());
|
||||
SearchControls searchControls = getDefaultSearchControls(defaultSearchScope, returnObjFlag, query.attributes());
|
||||
|
||||
if(query.searchScope() != null) {
|
||||
if (query.searchScope() != null) {
|
||||
searchControls.setSearchScope(query.searchScope().getId());
|
||||
}
|
||||
|
||||
if(query.countLimit() != null) {
|
||||
if (query.countLimit() != null) {
|
||||
searchControls.setCountLimit(query.countLimit());
|
||||
}
|
||||
|
||||
if(query.timeLimit() != null) {
|
||||
if (query.timeLimit() != null) {
|
||||
searchControls.setTimeLimit(query.timeLimit());
|
||||
}
|
||||
return searchControls;
|
||||
@@ -1658,10 +1618,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public <T> List<T> search(LdapQuery query, AttributesMapper<T> mapper) {
|
||||
SearchControls searchControls = searchControlsForQuery(query, DONT_RETURN_OBJ_FLAG);
|
||||
|
||||
return search(query.base(),
|
||||
query.filter().encode(),
|
||||
searchControls,
|
||||
mapper);
|
||||
return search(query.base(), query.filter().encode(), searchControls, mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1684,10 +1641,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public <T> T searchForObject(LdapQuery query, ContextMapper<T> mapper) {
|
||||
SearchControls searchControls = searchControlsForQuery(query, DONT_RETURN_OBJ_FLAG);
|
||||
|
||||
return searchForObject(query.base(),
|
||||
query.filter().encode(),
|
||||
searchControls,
|
||||
mapper);
|
||||
return searchForObject(query.base(), query.filter().encode(), searchControls, mapper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1723,7 +1677,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
String encodedFilter = filter.encode();
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Searching - base=%1$s, finalFilter=%2$s, scope=%3$s", base, filter, searchControls));
|
||||
LOG.debug(
|
||||
String.format("Searching - base=%1$s, finalFilter=%2$s, scope=%3$s", base, filter, searchControls));
|
||||
}
|
||||
|
||||
assureReturnObjFlagSet(searchControls);
|
||||
@@ -1732,9 +1687,11 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
if (results == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(results), Spliterator.ORDERED), false)
|
||||
.map((nameClassPair) -> unchecked(() -> mapper.apply(nameClassPair)))
|
||||
.filter(Objects::nonNull).onClose(() -> closeContextAndNamingEnumeration(ctx, results));
|
||||
return StreamSupport
|
||||
.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(results), Spliterator.ORDERED),
|
||||
false)
|
||||
.map((nameClassPair) -> unchecked(() -> mapper.apply(nameClassPair))).filter(Objects::nonNull)
|
||||
.onClose(() -> closeContextAndNamingEnumeration(ctx, results));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1778,7 +1735,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
Name id = odm.getId(entry);
|
||||
if(id == null) {
|
||||
if (id == null) {
|
||||
id = odm.getCalculatedId(entry);
|
||||
odm.setId(entry, id);
|
||||
}
|
||||
@@ -1804,11 +1761,12 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
Name originalId = odm.getId(entry);
|
||||
Name calculatedId = odm.getCalculatedId(entry);
|
||||
|
||||
if(originalId != null && calculatedId != null && !originalId.equals(calculatedId)) {
|
||||
if (originalId != null && calculatedId != null && !originalId.equals(calculatedId)) {
|
||||
// The DN has changed - remove the original entry and bind the new one
|
||||
// (because other data may have changed as well
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Calculated DN of %s; of entry %s differs from explicitly specified one; %s - moving",
|
||||
LOG.debug(String.format(
|
||||
"Calculated DN of %s; of entry %s differs from explicitly specified one; %s - moving",
|
||||
calculatedId, entry, originalId));
|
||||
}
|
||||
|
||||
@@ -1819,11 +1777,12 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
|
||||
bind(context);
|
||||
odm.setId(entry, calculatedId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// DN is the same, just modify the attributes
|
||||
|
||||
Name id = originalId;
|
||||
if(id == null) {
|
||||
if (id == null) {
|
||||
id = calculatedId;
|
||||
odm.setId(entry, calculatedId);
|
||||
}
|
||||
@@ -1847,7 +1806,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
Name id = odm.getId(entry);
|
||||
if(id == null) {
|
||||
if (id == null) {
|
||||
id = odm.getCalculatedId(entry);
|
||||
}
|
||||
|
||||
@@ -1869,8 +1828,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
@Override
|
||||
public <T> List<T> findAll(Class<T> clazz) {
|
||||
return findAll(LdapUtils.emptyLdapName(),
|
||||
getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, ALL_ATTRIBUTES),
|
||||
clazz);
|
||||
getDefaultSearchControls(defaultSearchScope, RETURN_OBJ_FLAG, ALL_ATTRIBUTES), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1893,7 +1851,8 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug(String.format("Searching - base=%1$s, finalFilter=%2$s, scope=%3$s", base, finalFilter, searchControls));
|
||||
LOG.debug(String.format("Searching - base=%1$s, finalFilter=%2$s, scope=%3$s", base, finalFilter,
|
||||
searchControls));
|
||||
}
|
||||
|
||||
List<T> result = search(localBase, finalFilter.encode(), searchControls, new ContextMapper<T>() {
|
||||
@@ -1955,31 +1914,37 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
private <T> T unchecked(CheckedSupplier<T> supplier) {
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
catch (NameNotFoundException e) {
|
||||
// It is possible to ignore errors caused by base not found
|
||||
if (!ignoreNameNotFoundException) {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
LOG.warn("Base context not found, ignoring: " + e.getMessage());
|
||||
} catch (PartialResultException e) {
|
||||
}
|
||||
catch (PartialResultException e) {
|
||||
// Workaround for AD servers not handling referrals correctly.
|
||||
if (!ignorePartialResultException) {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
LOG.debug("PartialResultException encountered and ignored", e);
|
||||
} catch(SizeLimitExceededException e) {
|
||||
if(!ignoreSizeLimitExceededException) {
|
||||
}
|
||||
catch (SizeLimitExceededException e) {
|
||||
if (!ignoreSizeLimitExceededException) {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
LOG.debug("SizeLimitExceededException encountered and ignored", e);
|
||||
} catch (javax.naming.NamingException e) {
|
||||
}
|
||||
catch (javax.naming.NamingException e) {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private interface CheckedSupplier<T> {
|
||||
|
||||
T get() throws javax.naming.NamingException;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1988,6 +1953,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
* @author Rob Winch
|
||||
*/
|
||||
private enum AuthenticationStatus {
|
||||
|
||||
/**
|
||||
* Authentication was successful
|
||||
*/
|
||||
@@ -2014,5 +1980,7 @@ public class LdapTemplate implements LdapOperations, InitializingBean {
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,8 +43,11 @@ import java.util.Set;
|
||||
public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final boolean orderMatters;
|
||||
|
||||
private final Set<Object> values = new LinkedHashSet<Object>();
|
||||
|
||||
private Map<Name, String> valuesAsNames = new HashMap<Name, String>();
|
||||
|
||||
/**
|
||||
@@ -59,17 +62,17 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
/**
|
||||
* Construct a new instance from the supplied Attribute.
|
||||
*
|
||||
* @param attribute the Attribute to copy.
|
||||
*/
|
||||
public NameAwareAttribute(Attribute attribute) {
|
||||
this(attribute.getID(), attribute.isOrdered());
|
||||
try {
|
||||
NamingEnumeration<?> incomingValues = attribute.getAll();
|
||||
while(incomingValues.hasMore()) {
|
||||
while (incomingValues.hasMore()) {
|
||||
this.add(incomingValues.next());
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
}
|
||||
catch (NamingException e) {
|
||||
throw LdapUtils.convertLdapException(e);
|
||||
}
|
||||
|
||||
@@ -88,7 +91,8 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance with the specified id, no values and order significance as specified.
|
||||
* Construct a new instance with the specified id, no values and order significance as
|
||||
* specified.
|
||||
* @param id the attribute id
|
||||
* @param orderMatters whether order has significance in this attribute.
|
||||
*/
|
||||
@@ -104,7 +108,7 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
@Override
|
||||
public Object get() {
|
||||
if(values.isEmpty()) {
|
||||
if (values.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -134,12 +138,13 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
Name name = LdapUtils.newLdapName((Name) attrVal);
|
||||
String currentValue = valuesAsNames.get(name);
|
||||
String nameAsString = name.toString();
|
||||
if(currentValue == null) {
|
||||
if (currentValue == null) {
|
||||
valuesAsNames.put(name, name.toString());
|
||||
values.add(nameAsString);
|
||||
return true;
|
||||
} else {
|
||||
if(!currentValue.equals(nameAsString)) {
|
||||
}
|
||||
else {
|
||||
if (!currentValue.equals(nameAsString)) {
|
||||
values.remove(currentValue);
|
||||
values.add(nameAsString);
|
||||
}
|
||||
@@ -152,7 +157,7 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
}
|
||||
|
||||
public void initValuesAsNames() {
|
||||
if(hasValuesAsNames()) {
|
||||
if (hasValuesAsNames()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -162,15 +167,20 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
String s = (String) value;
|
||||
try {
|
||||
newValuesAsNames.put(LdapUtils.newLdapName(s), s);
|
||||
} catch (InvalidNameException e) {
|
||||
throw new IllegalArgumentException("This instance has values that are not valid distinguished names; " +
|
||||
"cannot handle Name values", e);
|
||||
}
|
||||
} else if (value instanceof LdapName) {
|
||||
catch (InvalidNameException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"This instance has values that are not valid distinguished names; "
|
||||
+ "cannot handle Name values",
|
||||
e);
|
||||
}
|
||||
}
|
||||
else if (value instanceof LdapName) {
|
||||
newValuesAsNames.put((LdapName) value, value.toString());
|
||||
} else {
|
||||
throw new IllegalArgumentException("This instance has non-string attribute values; " +
|
||||
"cannot handle Name values");
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"This instance has non-string attribute values; " + "cannot handle Name values");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +198,7 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
Name name = LdapUtils.newLdapName((Name) attrval);
|
||||
String removedValue = valuesAsNames.remove(name);
|
||||
if(removedValue != null) {
|
||||
if (removedValue != null) {
|
||||
values.remove(removedValue);
|
||||
|
||||
return true;
|
||||
@@ -221,8 +231,8 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Due to performance reasons it is not advised to iterate over the attribute's values using this method.
|
||||
* Please use the {@link #iterator()} instead.
|
||||
* Due to performance reasons it is not advised to iterate over the attribute's values
|
||||
* using this method. Please use the {@link #iterator()} instead.
|
||||
* </p>
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -232,12 +242,13 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
try {
|
||||
Object value = iterator.next();
|
||||
for(int i = 0; i < ix; i++) {
|
||||
for (int i = 0; i < ix; i++) {
|
||||
value = iterator.next();
|
||||
}
|
||||
|
||||
return value;
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new IndexOutOfBoundsException("No value at index i");
|
||||
}
|
||||
}
|
||||
@@ -248,18 +259,20 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
try {
|
||||
Object value = iterator.next();
|
||||
for(int i = 0; i < ix; i++) {
|
||||
for (int i = 0; i < ix; i++) {
|
||||
value = iterator.next();
|
||||
}
|
||||
iterator.remove();
|
||||
if (value instanceof String) {
|
||||
try {
|
||||
valuesAsNames.remove(new LdapName((String) value));
|
||||
} catch (javax.naming.InvalidNameException ignored) {
|
||||
}
|
||||
catch (javax.naming.InvalidNameException ignored) {
|
||||
}
|
||||
}
|
||||
return value;
|
||||
} catch (NoSuchElementException e) {
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
throw new IndexOutOfBoundsException("No value at index i");
|
||||
}
|
||||
}
|
||||
@@ -288,27 +301,30 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
NameAwareAttribute that = (NameAwareAttribute) o;
|
||||
|
||||
if (id != null ? !id.equals(that.id) : that.id != null) return false;
|
||||
if(this.values.size() != that.values.size()) {
|
||||
if (id != null ? !id.equals(that.id) : that.id != null)
|
||||
return false;
|
||||
if (this.values.size() != that.values.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this.orderMatters != that.orderMatters || this.size() != that.size()) {
|
||||
if (this.orderMatters != that.orderMatters || this.size() != that.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(this.hasValuesAsNames() != that.hasValuesAsNames()) {
|
||||
if (this.hasValuesAsNames() != that.hasValuesAsNames()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<?> myValues = this.values;
|
||||
Set<?> theirValues = that.values;
|
||||
if(this.hasValuesAsNames()) {
|
||||
if (this.hasValuesAsNames()) {
|
||||
// We have Name values - compare these to get
|
||||
// syntactically correct comparison of the values
|
||||
|
||||
@@ -316,19 +332,20 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
theirValues = that.valuesAsNames.keySet();
|
||||
}
|
||||
|
||||
if(orderMatters) {
|
||||
if (orderMatters) {
|
||||
Iterator<?> thisIterator = myValues.iterator();
|
||||
Iterator<?> thatIterator = theirValues.iterator();
|
||||
while(thisIterator.hasNext()) {
|
||||
if(!ObjectUtils.nullSafeEquals(thisIterator.next(), thatIterator.next())) {
|
||||
while (thisIterator.hasNext()) {
|
||||
if (!ObjectUtils.nullSafeEquals(thisIterator.next(), thatIterator.next())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
for (Object value : myValues) {
|
||||
if(!CollectionUtils.contains(theirValues.iterator(), value)) {
|
||||
if (!CollectionUtils.contains(theirValues.iterator(), value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -343,7 +360,7 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
int valuesHash = 7;
|
||||
Set<?> myValues = this.values;
|
||||
if(hasValuesAsNames()) {
|
||||
if (hasValuesAsNames()) {
|
||||
myValues = valuesAsNames.keySet();
|
||||
}
|
||||
|
||||
@@ -357,8 +374,8 @@ public final class NameAwareAttribute implements Attribute, Iterable<Object> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("NameAwareAttribute; id: %s; hasValuesAsNames: %s; orderMatters: %s; values: %s",
|
||||
id, hasValuesAsNames(), orderMatters, values);
|
||||
return String.format("NameAwareAttribute; id: %s; hasValuesAsNames: %s; orderMatters: %s; values: %s", id,
|
||||
hasValuesAsNames(), orderMatters, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.util.Map;
|
||||
* @since 2.0
|
||||
*/
|
||||
public final class NameAwareAttributes implements Attributes {
|
||||
|
||||
private Map<String, NameAwareAttribute> attributes = new HashMap<String, NameAwareAttribute>();
|
||||
|
||||
/**
|
||||
@@ -46,7 +47,7 @@ public final class NameAwareAttributes implements Attributes {
|
||||
*/
|
||||
public NameAwareAttributes(Attributes attributes) {
|
||||
NamingEnumeration<? extends Attribute> allAttributes = attributes.getAll();
|
||||
while(allAttributes.hasMoreElements()) {
|
||||
while (allAttributes.hasMoreElements()) {
|
||||
Attribute attribute = allAttributes.nextElement();
|
||||
put(new NameAwareAttribute(attribute));
|
||||
}
|
||||
@@ -109,12 +110,15 @@ public final class NameAwareAttributes implements Attributes {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
NameAwareAttributes that = (NameAwareAttributes) o;
|
||||
|
||||
if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) return false;
|
||||
if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -128,4 +132,5 @@ public final class NameAwareAttributes implements Attributes {
|
||||
public String toString() {
|
||||
return String.format("NameAwareAttribute; attributes: %s", attributes.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,24 +20,23 @@ import javax.naming.NameClassPair;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* Callback interface used by {@link LdapTemplate} search, list and listBindings
|
||||
* methods. Implementations of this interface perform the actual work of
|
||||
* extracting results from a single <code>NameClassPair</code> (a
|
||||
* <code>NameClassPair</code>, <code>Binding</code> or
|
||||
* <code>SearchResult</code> depending on the search operation) returned by an
|
||||
* LDAP seach operation, such as search(), list(), and listBindings().
|
||||
*
|
||||
* Callback interface used by {@link LdapTemplate} search, list and listBindings methods.
|
||||
* Implementations of this interface perform the actual work of extracting results from a
|
||||
* single <code>NameClassPair</code> (a <code>NameClassPair</code>, <code>Binding</code>
|
||||
* or <code>SearchResult</code> depending on the search operation) returned by an LDAP
|
||||
* seach operation, such as search(), list(), and listBindings().
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface NameClassPairCallbackHandler {
|
||||
|
||||
/**
|
||||
* Handle one entry. This method will be called once for each entry returned
|
||||
* by a search or list.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* the NameClassPair returned from the
|
||||
* <code>NamingEnumeration</code>.
|
||||
* Handle one entry. This method will be called once for each entry returned by a
|
||||
* search or list.
|
||||
* @param nameClassPair the NameClassPair returned from the
|
||||
* <code>NamingEnumeration</code>.
|
||||
* @throws NamingException if an error occurs.
|
||||
*/
|
||||
void handleNameClassPair(NameClassPair nameClassPair) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -21,24 +21,21 @@ import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* Responsible for mapping <code>NameClassPair</code> objects to beans.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface NameClassPairMapper<T> {
|
||||
|
||||
/**
|
||||
* Map <code>NameClassPair</code> to an Object. The supplied
|
||||
* <code>NameClassPair</code> is one of the results from a search
|
||||
* operation (search, list or listBindings). Depending on which search
|
||||
* operation is being performed, the <code>NameClassPair</code> might be a
|
||||
* <code>SearchResult</code>, <code>Binding</code> or
|
||||
* <code>NameClassPair</code>.
|
||||
*
|
||||
* @param nameClassPair
|
||||
* <code>NameClassPair</code> from a search operation.
|
||||
* <code>NameClassPair</code> is one of the results from a search operation (search,
|
||||
* list or listBindings). Depending on which search operation is being performed, the
|
||||
* <code>NameClassPair</code> might be a <code>SearchResult</code>,
|
||||
* <code>Binding</code> or <code>NameClassPair</code>.
|
||||
* @param nameClassPair <code>NameClassPair</code> from a search operation.
|
||||
* @return and Object built from the <code>NameClassPair</code>.
|
||||
* @throws NamingException
|
||||
* if one is encountered in the operation.
|
||||
* @throws NamingException if one is encountered in the operation.
|
||||
*/
|
||||
T mapFromNameClassPair(NameClassPair nameClassPair)
|
||||
throws NamingException;
|
||||
T mapFromNameClassPair(NameClassPair nameClassPair) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package org.springframework.ldap.core;
|
||||
import org.springframework.ldap.NamingException;
|
||||
|
||||
/**
|
||||
* Thrown by a {@link ContextMapperCallbackHandler} when it cannot retrieve an
|
||||
* object from the given <code>Binding</code>.
|
||||
*
|
||||
* Thrown by a {@link ContextMapperCallbackHandler} when it cannot retrieve an object from
|
||||
* the given <code>Binding</code>.
|
||||
*
|
||||
* @author Ulrik Sandberg
|
||||
* @since 1.2
|
||||
*/
|
||||
@@ -29,10 +29,8 @@ public class ObjectRetrievalException extends NamingException {
|
||||
|
||||
/**
|
||||
* Create a new ObjectRetrievalException.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
*
|
||||
* @param msg the detail message
|
||||
*
|
||||
*/
|
||||
public ObjectRetrievalException(String msg) {
|
||||
super(msg);
|
||||
@@ -40,11 +38,8 @@ public class ObjectRetrievalException extends NamingException {
|
||||
|
||||
/**
|
||||
* Create a new ObjectRetrievalException.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message
|
||||
* @param cause
|
||||
* the root cause (if any)
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause (if any)
|
||||
*/
|
||||
public ObjectRetrievalException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
|
||||
@@ -20,9 +20,9 @@ import javax.naming.NamingException;
|
||||
import javax.naming.directory.DirContext;
|
||||
|
||||
/**
|
||||
* Interface for delegating an actual search operation. The typical
|
||||
* implementation of executeSearch would be something like:
|
||||
*
|
||||
* Interface for delegating an actual search operation. The typical implementation of
|
||||
* executeSearch would be something like:
|
||||
*
|
||||
* <pre>
|
||||
* SearchExecutor executor = new SearchExecutor(){
|
||||
* public NamingEnumeration executeSearch(DirContext ctx) throws NamingException{
|
||||
@@ -30,23 +30,19 @@ import javax.naming.directory.DirContext;
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @see org.springframework.ldap.core.LdapTemplate#search(SearchExecutor,
|
||||
* NameClassPairCallbackHandler)
|
||||
*
|
||||
* NameClassPairCallbackHandler)
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*/
|
||||
public interface SearchExecutor {
|
||||
|
||||
/**
|
||||
* Execute the actual search.
|
||||
*
|
||||
* @param ctx
|
||||
* the <code>DirContext</code> on which to work.
|
||||
* @return the <code>NamingEnumeration</code> resulting from the search
|
||||
* operation.
|
||||
* @throws NamingException
|
||||
* if the search results in one.
|
||||
* @param ctx the <code>DirContext</code> on which to work.
|
||||
* @return the <code>NamingEnumeration</code> resulting from the search operation.
|
||||
* @throws NamingException if the search results in one.
|
||||
*/
|
||||
NamingEnumeration executeSearch(DirContext ctx)
|
||||
throws NamingException;
|
||||
NamingEnumeration executeSearch(DirContext ctx) throws NamingException;
|
||||
|
||||
}
|
||||
|
||||
@@ -19,38 +19,32 @@ import org.springframework.ldap.core.ContextMapper;
|
||||
import org.springframework.ldap.core.DirContextOperations;
|
||||
|
||||
/**
|
||||
* Abstract superclass that may be used instead of implementing
|
||||
* {@link ContextMapper} directly. Subclassing from this superclass, the
|
||||
* supplied context will be automatically cast to
|
||||
* <code>DirContextOperations</code>. Note that if you use your own
|
||||
* Abstract superclass that may be used instead of implementing {@link ContextMapper}
|
||||
* directly. Subclassing from this superclass, the supplied context will be automatically
|
||||
* cast to <code>DirContextOperations</code>. Note that if you use your own
|
||||
* <code>DirObjectFactory</code>, this implementation will fail with a
|
||||
* <code>ClassCastException</code>.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractContextMapper<T> implements ContextMapper<T> {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @throws ClassCastException
|
||||
* if a custom <code>DirObjectFactory</code> implementation is
|
||||
* used, causing the objects passed in be anything else than
|
||||
* {@link DirContextOperations} instances.
|
||||
* @throws ClassCastException if a custom <code>DirObjectFactory</code> implementation
|
||||
* is used, causing the objects passed in be anything else than
|
||||
* {@link DirContextOperations} instances.
|
||||
*/
|
||||
public final T mapFromContext(Object ctx) {
|
||||
return doMapFromContext((DirContextOperations) ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a single <code>DirContextOperation</code> to an object. The
|
||||
* supplied instance is the object supplied to
|
||||
* {@link #mapFromContext(Object)} cast to a
|
||||
* Map a single <code>DirContextOperation</code> to an object. The supplied instance
|
||||
* is the object supplied to {@link #mapFromContext(Object)} cast to a
|
||||
* <code>DirContextOperations</code>.
|
||||
*
|
||||
* @param ctx
|
||||
* the context to map to an object.
|
||||
* @param ctx the context to map to an object.
|
||||
* @return an object built from the data in the context.
|
||||
*/
|
||||
protected abstract T doMapFromContext(DirContextOperations ctx);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user