Index: fedd/abac-src/ttg/credential/DDEngine.java
===================================================================
--- fedd/abac-src/ttg/credential/DDEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/credential/DDEngine.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,238 @@
+package com.nailabs.abac.credential;
+
+import com.nailabs.abac.test.RtmlTest;
+
+import edu.stanford.rt.credential.CredentialDomain;
+import edu.stanford.rt.credential.CredentialStore;
+import edu.stanford.rt.credential.HashID;
+import edu.stanford.rt.credential.RTContext;
+
+import edu.stanford.rt.parser.*;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.util.ResultEvidenceMap;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/**
+ * A distributed discovery engine based on the RTML-aware GraphEngine. 
+ */
+public class DDEngine extends RtmlEngine {
+
+    protected RTParser parser;
+
+    protected RTContext context;
+
+    protected Properties lookupMap = new Properties();
+
+    static String PORT_PROPERTY = "com.nailabs.abac.discovery.port";
+
+    /**
+     * The default constructor grabs parameters from the configuration 
+     * HashMap, including [Parser] and [PrepInfo] sections. 
+     */
+    public DDEngine(HashMap config) {
+	super();
+	parser = (RTParser)config.get("DDEParser");
+	context = (RTContext)config.get("DDEContext");
+	lookupMap = (Properties)config.get("PrepInfo");
+	store = (CredentialStore)config.get("DDEStore");
+	try {
+	    if(context == null) {
+			  context = new RTContext(parser);
+	    }
+	    if(store == null) {
+			  store = (CredentialStore)config.get("CredentialStore");
+	    }
+	    if(store == null) {	    
+			  store = new CredentialStore(parser);
+	    }
+	} catch (Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+
+    protected URL createURL(String host, String operation, String expression) {
+	StringBuffer buff = new StringBuffer("http://");
+	buff.append(host).append("?");
+	buff.append(operation).append("=").append(expression);
+	try {
+	    System.out.println("Constructing url = " + buff);
+	    return new URL(buff.toString());
+	}
+	catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+	return null;
+    }
+
+
+    protected Vector parseOutput(URL url) {
+	Vector documents = new Vector();
+	StringWriter out = null;
+
+	try {
+	    URLConnection connection = url.openConnection();
+	    InputStream in = connection.getInputStream();
+	    BufferedReader buffedReader
+		= new BufferedReader(new InputStreamReader(in));
+	    out = new StringWriter();
+	    // grab the first line so we don't have an empty vector item
+	    out.write(buffedReader.readLine());
+	    while(true) {
+		String line = buffedReader.readLine();
+		if(line == null)break;
+		if(line.startsWith("<?xml")) {
+		    documents.add(out.getBuffer().toString());
+		    out = new StringWriter();
+		}
+		out.write(line);
+		out.write("\n");
+	    }
+	    
+	} catch(Exception ex) {
+	    //ex.printStackTrace();
+	}
+	if(out != null) {
+	    documents.add(out.getBuffer().toString());
+	}
+	for(int cnt = 0; cnt < documents.size(); cnt++) {
+	    try {
+		String xml = (String)documents.get(cnt);
+		if(xml.equals("null")) {
+		    documents.remove(cnt--);
+		    continue;
+		}
+		System.out.println("---------begin xml-------");
+		System.out.println(xml);
+		System.out.println("----------end xml--------");
+		InputStream in = new ByteArrayInputStream(xml.getBytes());
+		documents.set
+		    (cnt, (Object) parser.parseCredentialDomain(in,context));
+	    } catch(Exception ex) {
+		ex.printStackTrace();
+		documents.remove(cnt--);
+	    }
+	}
+	return documents;
+    }
+
+    protected String getLocation(EntityExpression expr) {
+	String base;
+	
+        if(expr instanceof Entity) {
+	    base = expr.toString();
+	} else if(expr instanceof edu.stanford.peer.rbtm.credential.Role) {
+	    base = 
+	  ((edu.stanford.peer.rbtm.credential.Role)expr).getBase().toString();
+	} else if(expr instanceof edu.stanford.peer.rbtm.credential.LinkedRole)
+	    {
+	    base = ((edu.stanford.peer.rbtm.credential.LinkedRole)expr).getFirstRole().getBase().toString();
+	} else if(expr instanceof Intersection) {
+	    base = getLocation((EntityExpression)
+			       ((Intersection)expr).getParts().next());
+	} else {
+	    base = new String();
+	}
+	System.out.println("getting url for " + base);
+	return lookupMap.getProperty(base);
+    }
+
+    protected Vector discover(String operation, EntityExpression expr) {
+	URL url = createURL(getLocation(expr), operation, 
+		      RtmlExpression.toString(expr));
+	Vector v = parseOutput(url);
+	Vector results = new Vector(v.size());
+	Iterator domains = v.iterator();
+	while(domains.hasNext()) {
+	    CredentialDomain domain = (CredentialDomain)domains.next();
+	    HashID hash = domain.getHashID();
+	    try {
+		addDomain(domain);	
+		Iterator creds = RtmlEngine.convert(domain).iterator();
+		while(creds.hasNext()) {
+		    RtmlCredential cred = (RtmlCredential)creds.next();
+		    results.add(cred);
+		    System.out.println("-----+Adding " + cred);
+		}
+	    } catch(Exception ex) {
+		System.err.println("Error with credential domain " +
+				   domain.getHashID());
+		ex.printStackTrace();
+	    }
+	}
+	return results;
+    }
+
+    synchronized public Iterator 
+    findCredentialsDefiningRole(edu.stanford.peer.rbtm.credential.Role r) {
+	return discover("Defines", r).iterator();
+    }
+
+    synchronized public Collection getCredentialsIssuedBy(Entity e) {
+	return discover("Issuer", e);
+    }
+
+    synchronized public Iterator findCredentialsBySubject(EntityExpression s) {
+	return discover("Subject", s).iterator();
+    }
+
+    public static void main(String[] args) {
+	if(System.getProperty("edu.stanford.rt.SystemDomain") == null) {
+	    System.setProperty("edu.stanford.rt.SystemDomain",
+			       "../rtml/schemas/SystemSpec.xml");
+	}
+	HashMap conf = new HashMap(6);
+	Properties prepInfo = new Properties();
+	prepInfo.setProperty("SE", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/se-discovery");
+	prepInfo.setProperty("SAdmir!FakeHashKeySAdmir", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/se-discovery");
+	prepInfo.setProperty("US", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/us-discovery");
+	prepInfo.setProperty("USEUCOM", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/us-discovery");
+	prepInfo.setProperty("USSH!FakeHashKeyUSSH", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/us-discovery");
+	prepInfo.setProperty("USN", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/us-discovery");
+	prepInfo.setProperty("RADMSmith", 
+								"wwinsbor1.rv.nailabs.com:8180/demo/us-discovery");
+	conf.put("PrepInfo", prepInfo);
+	Properties rtml = new Properties(System.getProperties());
+	if(rtml.getProperty("DDEStore") == null) {
+	    rtml.setProperty("DDEStore", "test/rtml/dde-client.xml");
+	}
+	conf.put("RTML", rtml);
+	RtmlTest.parseDiscoveryStore(conf);
+	try {
+	    DDEngine engine = new DDEngine(conf);
+	    ResultEvidenceMap map = (ResultEvidenceMap)
+			  engine.backwardSearch(new Role("SAdmir!FakeHashKeySAdmir",
+														"getsSLocs"));
+	    Collection v = map.resultSet();
+	    for(Iterator i = v.iterator(); i.hasNext(); ) {
+			  System.out.println("--------------------");
+			  Object result = i.next();
+			  System.out.println(result.toString());
+			  System.out.println(map.getResultEvidence(result).toString());
+	    }
+		 System.out.println("--------------------");
+		 map = (ResultEvidenceMap)
+			  engine.forwardSearch(new SimpleEntity("USSH!FakeHashKeyUSSH"));
+		 //engine.forwardSearch(new SimpleEntity("SAdmir!FakeHashKeySAdmir"));
+		 //engine.forwardSearch(new Role("US!FakeHashKeyUS","usr"));
+
+	    v = map.resultSet();
+	    for(Iterator i = v.iterator(); i.hasNext(); ) {
+			  System.out.println("--------------------");
+			  Object result = i.next();
+			  System.out.println(result.toString());
+			  System.out.println(map.getResultEvidence(result).toString());
+	    }
+	} catch(Exception ex) {
+	    ex.printStackTrace();
+	}
+    }
+}
