/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.uchicago.grouperabi;
import edu.internet2.middleware.grouperClient.ws.beans.WsSubject;
import java.io.IOException;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import nsit.Ldap;
/**
* The WsGroup class is missing some convenience methods. This wrapper class
* takes care of that problem
* @author davel
*/
public class Subject {
private WsSubject subject;
private Group parent;
private boolean hasDetails = false;
private LdapLookup ldapc = null;
private String cnetid;
public Subject(String chicagoID){
WsSubject newSubj = new WsSubject();
newSubj.setId(chicagoID);
subject = newSubj;
}
public Subject(WsSubject aSubject, Group parentGroup) {
subject = aSubject;
parent = parentGroup;
}
public Group getGroup() {
return parent;
}
public String getCnetid() {
if(cnetid == null){
if (ldapc == null) {
try {
ldapc = new LdapLookup();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ldapc.provisionSubject(this);
ldapc.close();
ldapc = null;
}
return cnetid;
}
public void setCnetid(String cnetid) {
this.cnetid = cnetid;
}
/**
* package-private method for setting a new parent group
* @param newParent the new parent group
*/
void setGroup(Group newParent){
parent = newParent;
}
/**
* This is the ChicagoID of the person
* @return ChicagoID of the person
*/
public String getId() {
return subject.getId();
}
/**
* This is the person's name
* @return Name of the person
*/
public String getName() {
if (subject.getName() == null) {
if (ldapc == null) {
try {
ldapc = new LdapLookup();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
ldapc.provisionSubject(this);
ldapc.close();
ldapc = null;
}
return subject.getName();
}
/**
* Set the name of the subject -- this does not make any changes in Grouper
* it only is here for convenience of other classes which should probably be refactored
* so this can become a protected or private method
* @param name the name of the subject
*/
public void setName(String name) {
subject.setName(name);
}
/**
* Get the value of the attributes on a subject
* @return String array of attribute values
*/
public String[] getAttributeValues() {
return subject.getAttributeValues();
}
@Override
public boolean equals(Object obj) {
boolean result = false;
if (obj instanceof Subject) {
Subject other = ((Subject) obj);
//subjects are equal when their ChicagoIDs are the same
if (getId().equals(other.getId())) {
result = true;
}
}
return result;
}
@Override
public int hashCode() {
//use the hashCode for the ID as the hashcode for this object
return getId().hashCode();
}
@Override
protected void finalize() throws Throwable {
if (ldapc != null) {
ldapc.close();
}
super.finalize();
}
/**
* Private class for looking up things in LDAP to improve performace for large groups as
* grouper-WS is very slow with large groups & getting all attributes this should be remvoed
* as grouper-ws matures & instead ensure that full subject data is created when the Subject
* object is instantiated
*/
private class LdapLookup {
private Ldap ldapc;
public LdapLookup() throws IOException {
ldapc = new Ldap();
}
/**
* Perform a lookup in LDAP for the user's name
* @param aUser user to lookup
* @return Subject with the data filled in (if available) for chaining
*/
public Subject provisionSubject(Subject aUser) {
SearchControls sc = new SearchControls();
sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
sc.setReturningAttributes(new String[]{"cn", "uid"});
try {
NamingEnumeration ne = ldapc.getContext().search("ou=people,dc=uchicago,dc=edu", "(chicagoid=" + aUser.getId() + ")", sc);
if (ne.hasMore()) {
SearchResult sr = (SearchResult) ne.next();
Attributes a2 = sr.getAttributes();
BasicAttribute cn = (BasicAttribute) a2.get("cn");
BasicAttribute uid = (BasicAttribute) a2.get("uid");
aUser.setCnetid((String)uid.get());
aUser.setName((String) cn.get());
}
} catch (Exception ex) {
}
return aUser;
}
public void close() {
try {
ldapc.closeLdap();
} catch (Exception e) {
//do nothing -- we did our best here
}
}
}
}