Index: fedd/abac-src/ttg/credential/DiscoveryService.java
===================================================================
--- fedd/abac-src/ttg/credential/DiscoveryService.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/credential/DiscoveryService.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,175 @@
+package com.nailabs.abac.credential;
+
+import java.io.*;
+import java.util.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.util.*;
+import edu.stanford.rt.parser.*;
+import edu.stanford.rt.credential.*;
+ 
+/** 
+ * A service object which encapsulates the functions of a CredentialManager
+ * that are necessary for remote and local discovery.
+ */
+public class DiscoveryService {
+    /** The graphine which performs the actual searches */
+    protected RtmlEngine engine;
+    /** An RTML parser which can be shared for all discovery services */
+    protected static RTParser parser = null;
+    /** AN RTML context which can be shared across all discovery services */
+    protected static RTContext context = null;
+
+    static {
+	try {
+	    parser = new RTParser();
+	    context = new RTContext(parser);
+	} catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+
+    /** Default constructor */
+    public DiscoveryService(String storeFile) {
+	try {
+	    parser = new RTParser();
+	    context = new RTContext(parser);
+	    CredentialStore store = new CredentialStore(parser);
+	    parser.parseCredentialStore
+		(new FileInputStream(new File(storeFile)), context, store);
+	    this.engine = new RtmlEngine(store);
+	} catch (Exception ex) {
+	    //ex.printStackTrace();
+	}
+    }
+
+    /** 
+     * For each result in the map, match the RTML for the domain of the 
+     * rtml credential.
+     */
+    protected String[] soapify(ResultEvidenceMap map) {
+	Object results[] = map.resultSet().toArray();
+	int max = results.length;
+	String[] evidence = new String[max];
+	for(int i = 0; i < max; i++) {
+	    Object obj = map.getResultEvidence(results[i]);
+	    if(obj instanceof RtmlCredential) {
+		RtmlCredential cred = (RtmlCredential)obj;
+		evidence[i] = cred.toXML();
+	    } else {
+		evidence[i] = results[i] + " -" + obj.toString();
+	    }
+	}
+	return evidence;
+    }
+
+    /**
+     * Convert a collection of <CODE>RTMLCredential</CODE> instances into a 
+     * set of their <CODE>CredentialDomain</CODE> instances.
+     */
+    protected String[] soapify(Collection c) {
+	//String[] credentials = new String[c.size()];
+	HashSet credentials = new HashSet(c.size());
+	Iterator results = c.iterator();
+	String output[];
+	int i = 0;
+	
+	while(results.hasNext()) {
+	    Object obj = results.next();
+	    if(obj instanceof RtmlCredential) {
+		RtmlCredential cred = (RtmlCredential)obj;
+		//credentials[i++] = cred.toXML();
+		credentials.add(cred.toXML());
+	    } else {
+		//credentials[i++] = obj.toString();
+		credentials.add(obj.toString());
+	    }
+	}
+	output = new String[credentials.size()];
+	results = credentials.iterator(); 
+	for(i = 0; results.hasNext(); i++) {
+	    output[i] = results.next().toString();
+	}
+	return output;
+    }
+
+    /**
+     * For a specified entity name, return all <code>CredentialDomain</code>
+     * instances which were issued by the entity.
+     */
+    public String[] getCredentialsIssuedBy(String entityName) {
+	Entity e = new RtmlEntity(entityName);
+	return soapify(engine.getCredentialsIssuedBy(e));
+	//return soapify(engine.backwardSearch(e));
+    }
+
+    /**
+     * For the specified role, return all <code>CredentialDomain</code> 
+     * instances which define the specified role (entity.role).
+     */
+    public String[] findCredentialsDefiningRole(String entity, String role) {
+	Entity e = new RtmlEntity(entity);
+	edu.stanford.peer.rbtm.credential.Role r = 
+	    new edu.stanford.peer.rbtm.credential.Role(e, role);
+	Iterator results = engine.findCredentialsDefiningRole(r);
+        HashSet evidence = new HashSet();
+	StringBuffer buff = new StringBuffer("DefiningRole(");
+	buff.append(entity).append(".").append(role).append(") = ");
+        while(results.hasNext()) {
+	    Object result = results.next();
+	    //System.out.println("def result = " + result);
+	    buff.append(result.toString()).append(" ");
+	    evidence.add(result);
+        }
+	System.out.println(buff.toString());
+	return soapify(evidence);
+    }
+
+    /**
+     * For a given entity expression, find the <code>CredentialDomain</code>
+     * instances which define credentials that have the entity expression as 
+     * a subject.
+     */
+    public String[] findCredentialsBySubject(String expr) {
+	EntityExpression ee = null;
+	try {
+	    ee = StaticCredential.getEntityExpression(expr);
+	    ee = RtmlExpression.convert(ee);
+	} catch (Exception cpe) {
+	    cpe.printStackTrace();
+	}
+	Iterator results = engine.findCredentialsBySubject(ee);
+	HashSet evidence = new HashSet();
+	StringBuffer buff = new StringBuffer("BySubject(");
+	buff.append(expr).append(") = ");
+	while(results.hasNext()) {
+	    Object result = results.next();
+	    //System.out.println("subj result = " + result);
+	    buff.append(result).append(" ");
+	    if(!evidence.contains(result)) {
+		evidence.add(result);
+	    }
+	}
+	System.out.println(buff.toString());
+	return soapify(evidence);
+    }
+
+    /**
+     * Add a new <code>CredentialDomain</code> to the underlying 
+     * <code>CredentialStore</code>.
+     * @param xml an xml block which defined a <code>CredentialDomain</code>
+     */
+    public void addCredentialDomain(String xml) {
+	try {
+	    InputStream in = new ByteArrayInputStream(xml.getBytes());
+	    CredentialDomain domain = 
+		parser.parseCredentialDomain(in, context);
+	    synchronized(engine) {
+		engine.addDomain(domain);
+	    }
+	} catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+
+}
