|
@@ -19,12 +19,22 @@ import javax.naming.NamingException;
|
|
|
import javax.naming.NamingEnumeration;
|
|
|
import javax.naming.directory.DirContext;
|
|
|
import javax.naming.directory.SearchControls;
|
|
|
+import javax.naming.directory.SearchResult;
|
|
|
+import javax.naming.directory.Attributes;
|
|
|
+import javax.naming.directory.Attribute;
|
|
|
|
|
|
import org.springframework.dao.DataAccessException;
|
|
|
import org.springframework.util.Assert;
|
|
|
|
|
|
+import java.util.Set;
|
|
|
+import java.util.HashSet;
|
|
|
+
|
|
|
/**
|
|
|
* LDAP equivalent of the Spring JdbcTemplate class.
|
|
|
+ * <p>
|
|
|
+ * This is mainly intended to simplify Ldap access within Acegi Security's
|
|
|
+ * LDAP-related services.
|
|
|
+ * </p>
|
|
|
*
|
|
|
* @author Ben Alex
|
|
|
* @author Luke Taylor
|
|
@@ -36,6 +46,8 @@ public class LdapTemplate {
|
|
|
private InitialDirContextFactory dirContextFactory;
|
|
|
private String userDn = null;
|
|
|
private String password = null;
|
|
|
+ /** Default search scope */
|
|
|
+ private int searchScope = SearchControls.SUBTREE_SCOPE;
|
|
|
|
|
|
public LdapTemplate(InitialDirContextFactory dirContextFactory) {
|
|
|
Assert.notNull(dirContextFactory, "An InitialDirContextFactory is required");
|
|
@@ -52,6 +64,10 @@ public class LdapTemplate {
|
|
|
this.password = password;
|
|
|
}
|
|
|
|
|
|
+ public void setSearchScope(int searchScope) {
|
|
|
+ this.searchScope = searchScope;
|
|
|
+ }
|
|
|
+
|
|
|
public Object execute(LdapCallback callback) throws DataAccessException {
|
|
|
DirContext ctx = null;
|
|
|
|
|
@@ -93,4 +109,57 @@ public class LdapTemplate {
|
|
|
|
|
|
return matches.booleanValue();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Performs a search using the supplied filter and returns the union of the values of the named
|
|
|
+ * attribute found in all entries matched by the search. Note that one directory entry may have several
|
|
|
+ * values for the attribute.
|
|
|
+ *
|
|
|
+ * @param base the DN to search in
|
|
|
+ * @param filter search filter to use
|
|
|
+ * @param params the parameters to substitute in the search filter
|
|
|
+ * @param attributeName the attribute who's values are to be retrieved.
|
|
|
+ * @return the set of values for the attribute as a union of the values found in all the matching entries.
|
|
|
+ */
|
|
|
+ public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params, final String attributeName) {
|
|
|
+
|
|
|
+
|
|
|
+ class LdapSearchCallback implements LdapCallback {
|
|
|
+
|
|
|
+ public Object execute(DirContext ctx) throws NamingException {
|
|
|
+ Set unionOfValues = new HashSet();
|
|
|
+
|
|
|
+ SearchControls ctls = new SearchControls();
|
|
|
+
|
|
|
+ ctls.setSearchScope(searchScope);
|
|
|
+ ctls.setReturningAttributes(new String[] {attributeName});
|
|
|
+
|
|
|
+ NamingEnumeration matchingEntries =
|
|
|
+ ctx.search(base, filter, params, ctls);
|
|
|
+
|
|
|
+ while (matchingEntries.hasMore()) {
|
|
|
+ SearchResult result = (SearchResult) matchingEntries.next();
|
|
|
+ Attributes attrs = result.getAttributes();
|
|
|
+
|
|
|
+ // There should only be one attribute in each matching entry.
|
|
|
+ NamingEnumeration returnedAttributes = attrs.getAll();
|
|
|
+
|
|
|
+ while(returnedAttributes.hasMore()) {
|
|
|
+ Attribute returnedAttribute = (Attribute) returnedAttributes.next();
|
|
|
+ NamingEnumeration attributeValues = returnedAttribute.getAll();
|
|
|
+
|
|
|
+ while(attributeValues.hasMore()) {
|
|
|
+ Object value = attributeValues.next();
|
|
|
+ unionOfValues.add(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return unionOfValues;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (Set)execute(new LdapSearchCallback());
|
|
|
+ }
|
|
|
}
|