/**
Collects data from the ldap for a specific user.  The class also caches all retrieved data for each specified user.
You will need to specify your location's specifics regarding the ldap server, user name, password, etc.
Also, the contents of your ldap may be different than what is specified below.

You may also need to download Sun's Naming services.

JDK 1.3

@author Michael Pell, Solutions Plus, Inc.  www.sol-plus.com
*/


import javax.naming.directory.*;
import java.util.*;
/**
 * Insert the type's description here.
 * Creation date: (12/8/2000 1:45:45 PM)
 * @author: 
 */
public class LdapInterface {

	private String userId = null;
	public final static java.lang.String DEPT = "department";
	public final static java.lang.String LOCATION = "location";
	public final static java.lang.String EMAIL_ADDRESS = "mail";
	public final static java.lang.String MAIL_SERVER = "mailserver";
	public final static java.lang.String FIRST_NAME = "givenname";
	public final static java.lang.String MIDDLE_INITIAL = "middleinitial";
	public final static java.lang.String LAST_NAME = "sn";
	public final static java.lang.String PHONE_NUMBER = "telephonenumber";
	private java.util.Hashtable ldapInfoDict = null;
	public static String[] ATTR_NAMES = {DEPT,LOCATION, EMAIL_ADDRESS, MAIL_SERVER, FIRST_NAME, MIDDLE_INITIAL, LAST_NAME, PHONE_NUMBER};
	private static java.util.Hashtable ForUserDict = null;
/**
 * LdapInterface constructor comment.
 */
private LdapInterface() {
	super();
}
private LdapInterface(String userIdArg)
{

	this();
	this.setUserId(userIdArg);
	this.retrieveLdapInfo();
	this.initAttributes();

}
/**
 * Returns the value for the given attribute.
 * Must use global variables as defined in LdapInterface class.
 * Return false if no value was found or an error occurred.
 * @return String attribute value
 */
public String get(String attributeName ) 
{
	String attributeValue = null;

	try
	{
		attributeValue = (String) this.getLdapInfoDict().get(attributeName);
	}
	catch(Exception e)
	{
		System.out.println(e);
	}
	
	return attributeValue;	
	
}
private static java.util.Hashtable GetForUserDict()
{
	if (ForUserDict == null)
		ForUserDict= new Hashtable();

	return ForUserDict;
}
/**
 * Returns an instance of an LdapInterface for the given userId.
 * Returns null if null or a null string is passed in.
 * @param userId java.lang.String
 */
public static LdapInterface GetInstance(String userIdArg)
{

	if (userIdArg == null || userIdArg.length() < 1)
		return null;

	LdapInterface li = null;

	//check to see if we already have an instance in the cache
	li = (LdapInterface) GetForUserDict().get(userIdArg);

	//if no existing instance, then create one, and add it to the cache
	if (li == null)
	{
		li = new LdapInterface(userIdArg);
		GetForUserDict().put(userIdArg, li);
	}
	
	return li; 

}
private java.util.Hashtable getLdapInfoDict() {

	if (ldapInfoDict == null)
		ldapInfoDict = new Hashtable();
	return ldapInfoDict;
}
public java.lang.String getUserId() {
	return userId;
}
/**
 * Initializes the ldapInfoDict using the result from querying the server via ldap.
 * Creation date: (12/8/2000 1:45:58 PM)
 */
private void initAttributes()
{
	SearchResult sr= this.retrieveLdapInfo(); 
	String entryName= null;
	Attribute attr= null;
	String value= null;
	String desiredValue= null;

	for (int i= 0; i < ATTR_NAMES.length; i++)
	{
		try  //yes, try block inside of for loop
		{
			entryName = (String) ATTR_NAMES[i];
			attr= sr.getAttributes().get(entryName);
			value= attr.toString();
			desiredValue= value.substring(value.indexOf(":") + 2, value.length());
			if (desiredValue.startsWith("+"))
				desiredValue = desiredValue.substring(1, desiredValue.length());
			this.getLdapInfoDict().put(entryName, desiredValue);
			//System.out.println(entryName + " is " + desiredValue);
		}
		catch (Exception e)
		{
			this.getLdapInfoDict().put(entryName, "n/a");
			System.out.println(e);
		}
	}
}
public static void main(String[] args)
{

	String userId= null;
	LdapInterface linull= LdapInterface.GetInstance(userId); 

	
	userId= "mjpell";
	LdapInterface li= LdapInterface.GetInstance(userId);

	for (int i= 0; i < ATTR_NAMES.length; i++)
	{
		String attrName= (String) ATTR_NAMES[i];
		System.out.println(li.get(attrName));
	}

}
/**
 * Returns a string representing the informtion returned from the LDAP call to get user information.
 * Returns null if a problem was encountered, or the user was not found.
 * Creation date: (12/8/2000 1:45:58 PM)
 */
private SearchResult retrieveLdapInfo()
{
	SearchResult ldapInfo = null;

	if (this.getUserId() == null)
		return null;

	try
	{
		Hashtable env= new Hashtable();
		env.put(
			javax.naming.Context.INITIAL_CONTEXT_FACTORY, 
			"com.sun.jndi.ldap.LdapCtxFactory"); 
		env.put(javax.naming.Context.PROVIDER_URL, "ldap://ustest3.d51.lilly.com:389");  //Change this
		env.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
		env.put(javax.naming.Context.SECURITY_PRINCIPAL, "cn=Michael J Pell");  //Change this
		env.put(javax.naming.Context.SECURITY_CREDENTIALS, "mypass");  //Change this
		DirContext ctx= new InitialDirContext(env);

		//try with using SearchControls and a Search scope
		SearchControls ctls= new SearchControls();
		ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
		String filter= "(uid="+ this.getUserId() +")";
		javax.naming.NamingEnumeration answer= ctx.search("", filter, ctls);

		ldapInfo = (SearchResult)answer.nextElement();
		if (answer.hasMoreElements())
		{
			System.out.println("WARNING: multiple results from LDAP Call to get user information!  Chose the first, ignoring the rest");
		}
	}
	catch (Exception e)
	{
		System.out.println(e);
		return null;
	}
	return ldapInfo;

}
private void setLdapInfoDict(java.util.Hashtable newLdapInfoDict) {
	ldapInfoDict = newLdapInfoDict;
}
private void setUserId(java.lang.String newUserId) {
	userId = newUserId;
}
}
