Index: fedd/abac-src/ttg/process/FrontierManager.java
===================================================================
--- fedd/abac-src/ttg/process/FrontierManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
+++ fedd/abac-src/ttg/process/FrontierManager.java	(revision 8780cbecc6db2bdc2b9ef31eec6e5209ad3bff15)
@@ -0,0 +1,408 @@
+package com.nailabs.abac.process;
+
+import com.nailabs.abac.test.Debug;
+import com.nailabs.abac.credential.RtmlFrontier;
+import edu.stanford.peer.rbtm.credential.*;
+import edu.stanford.peer.rbtm.engine.*;
+import edu.stanford.peer.rbtm.test.*;
+import edu.stanford.peer.rbtm.util.*;
+
+import java.util.*;
+
+/** 
+ * A manager class for frontier functions. Each set of functions should
+ * be unique to a principal. The manager is a singleton object with a method
+ * for obtaining a set of specific frontiers.
+ */
+public class FrontierManager  extends com.nailabs.abac.test.TestEngine 
+    implements java.io.Serializable {
+
+    /** Singleton reference table for sharing frontiers. */
+    static Hashtable frontiers = new Hashtable(5);
+    
+    /** The principal identifier, which is an Entity name */
+    protected Entity self;
+
+    /**
+     * The configuration hashmap. Section name is key and stringified 
+     * line vectors are the values
+     */
+    protected HashMap conf;
+
+    /** The set of issuer traceable credentials */
+    protected HashSet cSuperI = new HashSet();
+
+    /** The set of subject traceable credentials */
+    protected HashSet cSuperS = new HashSet();
+
+    /** The set of subject traceable <emp>roles</emp> */
+    protected HashSet subjectTraces = new HashSet();
+
+    protected HashSet issuerTracesDef = new HashSet();
+
+    protected HashSet issuerTracesAll = new HashSet();
+
+    /** a search engine which uses the <code>oppo()</code> predicate */
+    protected GraphEngine oppoLocal;
+
+    /** a search engine which uses the <code>oppo()</code> predicate */
+    protected GraphEngine oppoFrontier;
+    
+    /** a search engine which uses the <code>sens()</code> predicate */
+    protected GraphEngine sensFrontier;
+    
+    /** a search engine which uses the <code>simp()</code> predicate */
+    protected GraphEngine simpFrontier;
+    
+    /** the acknowledgement policy for this principal entity */
+    protected AckPolicy ackPolicy;
+
+    /** the access control policy for this principal entity */
+    protected ACPolicy acPolicy;
+
+    /** constructor for subclasses */
+    protected FrontierManager() { }
+    
+    /** default constructor, only used internally */
+    protected FrontierManager(HashMap config) {
+        init(config);
+    }
+    
+    /**
+     * initialization is no longer in constructor, so subclasses can
+     * manipulate the configuration hash map.
+     */
+    protected void init(HashMap config) {
+	//int track = TRACK_ALL;
+
+	// (0) get the configurations entity identifier
+	this.self =(Entity) config.get("EntityID");
+
+	// (1) load acknowledgement(ACK) policy
+	ackPolicy = (AckPolicy)config.get("AckPolicy");
+
+	// (2) load access control (AC) policy 
+	acPolicy = (ACPolicy)config.get("AccessControl");
+
+	// (3) load issuer traceable roles
+	issuerTracesAll = (HashSet)config.get("IssuerTracesAll");
+	issuerTracesDef = (HashSet)config.get("IssuerTracesDef");
+
+	// (4) load subject traceale roles
+	subjectTraces = (HashSet)config.get("SubjectTraceable");
+
+	// (5) construct sensitive roles predicate from the ack policy
+	Sens sens = new Sens(ackPolicy.getSensitiveRoles());
+
+	// (6) construct opponent predicate from the issuer traceable roles
+	Oppo oppo = new Oppo(new Vector(issuerTracesDef));
+	oppo.addSubjects(new Vector(issuerTracesAll));
+
+	// (7) construct the frontier functions with their predicates
+	oppoLocal = new GraphEngine();
+	//System.out.println("------> Sensitive Graph");
+	sensFrontier = new GraphEngine(sens);
+	//System.out.println("------> Opponent Graph");
+	oppoFrontier = new GraphEngine(oppo);
+	//System.out.println("------> Simple Graph");
+	simpFrontier = new GraphEngine(new Simp());
+
+	// TBD: Does this really need to be separated into two mutually exclusive
+	//      credential sets?
+	// (8) add policy reachable credentials
+	System.out.println("------> Policy Reachable");
+	HashSet policyReachable = (HashSet)config.get("PolicyReachable");
+	Iterator ci = policyReachable.iterator();
+	while(ci.hasNext()) {
+	    addPolicyReachable((StaticCredential)ci.next());
+	}
+	 
+	// (9) add self reachable credentials
+	System.out.println("------> Self Traceable");
+	HashSet selfReachable = (HashSet)config.get("SelfReachable");
+	Iterator cs = selfReachable.iterator();
+	while(cs.hasNext()) {
+	    addSelfReachable((StaticCredential)cs.next());
+	}
+
+    }
+    public static void addFrontier(HashMap config) {
+	Entity key = (Entity)config.get("EntityID");
+	boolean hasRTML = config.containsKey("RTML");
+	System.out.println("Begin Configuration for " + key);
+	 if(frontiers.contains(key.toString()))
+	     System.out.println("WARNING overwriting frontier manager for " +
+		 	       key);	
+	 FrontierManager frontier = hasRTML? new RtmlFrontier(config): 
+	    new FrontierManager(config);
+	 frontiers.put(key.toString(), frontier);
+	 System.out.println("End Configuration for " + key);
+    } 
+
+    /** public instance accessor method for a specific frontier set */
+    public static FrontierManager getFrontier(Entity self) {
+        System.out.println("self = " + self);
+        FrontierManager instance = 
+            (FrontierManager)frontiers.get(self.toString());
+        return instance;
+    }
+
+    /** public accessor for a list of instance keys */
+    public static Set getFrontiers() { return frontiers.keySet(); }
+
+    /** the unique identifier for this set of frontier functions */
+    public Entity getSelf() { return self; }
+
+    /** Extract the role name from a role expression (e.g. r from <A.r<--S>) */
+    protected RoleName getRoleName(StaticCredential cred) {
+	return getRoleName(cred.getDefinedRole());
+    }
+
+    /** Extract the role name from a role expression (e.g. r from A.r) */
+    protected RoleName getRoleName(EntityExpression expr) {
+	if(expr != null && (expr instanceof Role)) {
+	    return ((Role)expr).getName();
+	}
+	return null;
+    }
+
+    /** adds an issuer traceable credential to the frontier set */
+    public void addSelfReachable(StaticCredential cred) {
+        if(isSubjectTraceable(getRoleName(cred))) {
+            sensFrontier.addCredential(cred);
+            simpFrontier.addCredential(cred);
+            cSuperS.add(cred);
+        }
+    }
+    
+    /** extracts issuer traceable roles from the credntial */
+    public void addPolicyReachable(StaticCredential cred) {
+        if(isIssuerTraceable(getRoleName(cred))) {
+            oppoFrontier.addCredential(cred);
+	    oppoLocal.addCredential(cred);
+            cSuperI.add(cred);
+        }
+    }
+
+
+    /** adds an issuer-traces-all role to this frontier set */
+    public void addIssuerTracesAll(RoleName role) {
+        issuerTracesAll.add(role);
+    }
+
+    /** adds an issuer-traces-def role to this frontier set */
+    public void addIssuerTracesDef(RoleName role) {
+        issuerTracesDef.add(role);
+    }
+
+    /** adds an subject traceable credential to the frontier set */
+    public void addSubjectTraceable(RoleName role) {
+        subjectTraces.add(role);
+    }
+
+    public ResultEvidenceMap getOppoLocal(EntityExpression expr) {
+	//a specialized backward search for the LinkTTNode
+	Debug.rbtmStart();
+        System.out.println("-------BEGIN-LOCAL-SEARCH------------");
+        ResultEvidenceMap map =  oppoLocal.backwardSearch(expr);
+        System.out.println("-------END-LOCAL-SEARCH--------------");
+        Debug.rbtmStop();
+        return map;
+    }
+
+    /** gets the frontier of policy traceable roles */
+    public ResultEvidenceMap getOppoFrontier(EntityExpression expr) {
+        // retrieve solutions AND evidence here
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-OPPO-SEARCH------------");
+        ResultEvidenceMap map =  oppoFrontier.backwardSearch(expr);
+        System.out.println("-------END-OPPO-SEARCH--------------");
+        Debug.rbtmStop();
+        return map;
+    }
+    
+    /** gets the frontier of sensitive roles */
+    public ResultEvidenceMap getSensFrontier(EntityExpression expr) {
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-SENS-SEARCH------------");
+        System.out.println("searching for " + expr);
+        ResultEvidenceMap map = sensFrontier.backwardSearch(expr);
+        System.out.println("map = " + map);
+        System.out.println("--------END-SENS-SEARCH-------------");
+        System.out.flush();
+        Debug.rbtmStop();
+        return map;
+    }
+    
+    /** get the frontier of non-role entity expressions */
+    public ResultEvidenceMap getSimpFrontier(EntityExpression expr) {
+        Debug.rbtmStart();
+        System.out.println("-------BEGIN-SIMP-SEARCH------------");
+        ResultEvidenceMap map = simpFrontier.backwardSearch(expr);
+        System.out.println("--------END-SIMP-SEARCH------------");
+        Debug.rbtmStop();
+        return map;
+    }
+
+    public HashSet getOppoChain(EntityExpression root, EntityExpression leaf) {
+        HashSet results = new HashSet();
+        try {
+            getOppoFrontier(root);
+            Debug.rbtmStart();
+            System.out.println("Getting oppo chain from " + root + " to " + 
+                               leaf);
+            results = oppoFrontier.getChain(root, leaf);
+            Debug.rbtmStop();
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        }
+        Debug.rbtmStop();
+        return results;
+    }
+
+    public HashSet getSensChain(EntityExpression root, EntityExpression leaf) {
+        //if(!getSensFrontier(root).containsResult(leaf)) {
+        //return null; 
+        //}
+        try {
+            getSensFrontier(root);
+            Debug.rbtmStart();
+            System.out.println("---------BEGIN-SENS-CHAIN----------");
+            System.out.println("Getting sens chain from " + root + " to " + 
+                               leaf);
+            HashSet results = sensFrontier.getChain(root, leaf);
+            System.out.println("results = " + results);
+            System.out.println("-----------END-SENS-CHAIN----------\n");
+            Debug.rbtmStop();
+            return results;
+        } catch(Exception ex) {
+            ex.printStackTrace();
+        } 
+        System.out.println("-----------END-SENS-CHAIN----------\n");
+        Debug.rbtmStop();
+        return new HashSet();
+    }
+
+    public HashSet getSimpChain(EntityExpression root, EntityExpression leaf) {
+        System.out.println("Getting simp chain from " + root + " to " + leaf);
+        getSimpFrontier(root);
+        Debug.rbtmStart();
+        HashSet results = simpFrontier.getChain(root, leaf);
+        Debug.rbtmStop();
+        return results;
+    }
+
+    public Iterator getCredentialsDefiningRole(RoleName name) {
+	Iterator i;
+	int count = 0;
+	HashSet results = new HashSet();
+    
+	Debug.rbtmStart();
+	System.out.println("Finding credential defining the role name: "+name);
+	i = oppoFrontier.findCredentialsDefiningRole(name);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	i = sensFrontier.findCredentialsDefiningRole(name);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	Debug.rbtmStop();
+	Debug.debug("process", "\nDefining creds = " + results);
+	return results.iterator();
+    }
+
+    /** accessor for finding credentials which define a specified role */
+    public Iterator getCredentialsDefiningRole(Role role) {
+	Iterator i;
+	int count = 0;
+	HashSet results = new HashSet();
+    
+	Debug.rbtmStart();
+	System.out.println("Finding credential defining the role: <" + 
+			   role.getBase() + "." +  role.getName() + ">" );
+	
+	i = oppoFrontier.findCredentialsDefiningRole(role);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	System.out.println("oppoFrontier = " + oppoFrontier);
+	i = sensFrontier.findCredentialsDefiningRole(role);
+	while(i.hasNext()) {
+	    results.add(i.next());
+	    System.out.println("count = " + ++count);
+	}
+	Debug.debug("process", "\nDefining creds = " + results);
+
+	Debug.rbtmStop();
+	return results.iterator();
+    }
+
+    /** Is the specified credential policy traceable? */
+    public boolean isPolicyTraceable(StaticCredential cred) {
+	return cSuperI.contains(cred);
+    }
+
+    /** Can the specified credential be traced back to this negotiator? */
+    public boolean isSelfReachable(StaticCredential cred) {
+	return cSuperS.contains(cred);
+    }
+
+    public boolean isSubjectTraceable(RoleName role) {
+	return subjectTraces.contains(role);
+    }
+
+    public boolean isIssuerTracesDef(RoleName name) {
+        return (issuerTracesDef.contains(name));
+    }
+
+    public boolean isIssuerTracesAll(RoleName name) {
+        return (issuerTracesAll.contains(name));
+    }
+
+    public boolean isIssuerTraceable(RoleName role) {
+    return (issuerTracesAll.contains(role) || issuerTracesDef.contains(role));
+    }
+
+    public boolean isSensitive(EntityExpression expr) {
+	return sensFrontier.getPredicate().test(expr);
+    }
+    
+    public boolean subjectTracesAll(RoleName name) {
+	return subjectTraces.contains(name);
+    }
+
+    public AckPolicy getAckPolicy() { return ackPolicy; }
+
+    public EntityExpression getAck(EntityExpression expr) {
+	return ackPolicy.requires(expr);
+    }
+    
+    public ACPolicy getACPolicy() { return acPolicy; }
+
+    public EntityExpression getAC(Credential cred) {
+	if(acPolicy == null)return null;
+	return acPolicy.requires(cred);
+    }
+
+    protected void addSensitiveRole(Role name) {
+	Sens sens = (Sens)sensFrontier.getPredicate();
+	sens.addSensCred(name);
+    }
+
+    public String toString() {
+	StringBuffer buff = new StringBuffer("[FrontierManager self = ");
+	buff.append(self);
+	buff.append("\n sens = ").append(sensFrontier);
+	buff.append("\n\n oppo = ").append(oppoFrontier);
+	buff.append("\n\n simp = ").append(simpFrontier);
+	return buff.append("]").toString();
+    }
+
+}
+
+
+
