package org.constretto.internal.store.ldap;
import org.constretto.exception.ConstrettoException;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import javax.naming.ldap.LdapName;
/**
* Builder used to build an LdapConfigurationStore by reading LDAP entries from an DirContext
*
* @author <a href=mailto:zapodot@gmail.com>Sondre Eikanger Kvalø</a>
* @link
* @see LdapConfigurationStore
*/
public class LdapConfigurationStoreBuilder {
public static final String NULL_ARGUMENT = "The \"%1$s\" argument can not be null";
private DirContext dirContext;
private LdapConfigurationStore ldapConfigurationStore = new LdapConfigurationStore();
private LdapConfigurationStoreBuilder(final DirContext dirContext) {
this.dirContext = dirContext;
}
/**
* Creates the LdapConfigurationStoreBuilder
*
* @param dirContext the Ldap context to be used for reading configuration entries.
* This class will never ever close or change the DirContext instance provided to it
* @return a LdapConfigurationStoreBuilder to be used for fluently defining the LDAP entries to read
*/
public static LdapConfigurationStoreBuilder usingDirContext(final DirContext dirContext) {
return new LdapConfigurationStoreBuilder(dirContext);
}
private Attributes readAttributesFromLdap(String distinguishedName) {
try {
return dirContext.getAttributes(createName(distinguishedName));
} catch (NamingException e) {
throw new ConstrettoException(String.format("Could not find LDAP attributes for DSN \"%1$s\"",
distinguishedName), e);
}
}
/**
* Add the given LDAP entry identified the DSN (distinguishedName).
*
* @param key an prefix that will be applied as an prefix for all settings from the LDAP entry
* @param distinguishedName the DSN of the LDAP entry
* @param tags the Constretto tags the entry should be valid for
* @return
*/
public LdapConfigurationStoreBuilder addDsnWithKey(final String key,
final String distinguishedName,
String... tags) {
checkStringArgument("distinguishedName", distinguishedName);
ldapConfigurationStore = new LdapConfigurationStore(ldapConfigurationStore,
key,
readAttributesFromLdap(distinguishedName),
tags);
return this;
}
/**
* Add the given LDAP entry identified the DSN (distinguishedName).
*
* @param distinguishedName the DSN of the LDAP entry
* @param tags the Constretto tags the entry should be valid for
* @return
*/
public LdapConfigurationStoreBuilder addDsn(final String distinguishedName, final String... tags) {
checkStringArgument("distinguishedName", distinguishedName);
ldapConfigurationStore = new LdapConfigurationStore(ldapConfigurationStore,
readAttributesFromLdap(distinguishedName),
tags);
return this;
}
/**
* Used to do an search in the Ldap and may thus return multiple entries that will be made available
* as configuration entries
*
* @param searchBase a valid LDAP id to search from (ex.: "dc=constretto,dc=org")
* @param filter a LDAP filter to be applied to the matching entries
* (ex.: "(&(cn=John*)(objectClass=inetOrgPerson))")
* @param keyAttribute name of an attribute that will be used to prefix the configuration settings (ex.: "uid")
* @param tags the tags the returned settings will be made available for in the ConstrettoConfiguration
* @return
*/
public LdapConfigurationStoreBuilder addUsingSearch(final String searchBase,
final String filter,
final String keyAttribute,
final String... tags) {
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
try {
final NamingEnumeration<SearchResult> searchResultNamingEnumeration = dirContext.search(createName(
searchBase), filter, searchControls);
while (searchResultNamingEnumeration.hasMore()) {
final SearchResult result = searchResultNamingEnumeration.next();
final Attributes attributes = result.getAttributes();
final Attribute attribute = attributes.get(keyAttribute);
if (attribute == null) {
throw new ConstrettoException(String.format(
"The LDAP object \"%1$s\" has no attribute value for attribute \"%2$s\"",
result.getName(),
keyAttribute));
}
final String key = attribute.get().toString();
ldapConfigurationStore = new LdapConfigurationStore(ldapConfigurationStore, key, attributes, tags);
}
} catch (NamingException e) {
throw new ConstrettoException(
String.format("An error occurred while searching LDAP using searchBase \"%1$s\" and filter \"%2$s\"",
searchBase,
filter), e);
}
return this;
}
public LdapConfigurationStore done() {
return ldapConfigurationStore;
}
private Name createName(final String distinguishedName) {
try {
return new LdapName(distinguishedName);
} catch (InvalidNameException e) {
throw new IllegalArgumentException(String.format("Provided value \"%1$s\" is not a valid LDAP DSN",
distinguishedName));
}
}
private void checkStringArgument(final String fieldName, final String value) {
if (value == null) {
throw new IllegalArgumentException(String.format(NULL_ARGUMENT, fieldName));
}
}
}