package edu.stanford.peer.rbtm.engine; import java.util.*; import edu.stanford.peer.rbtm.credential.*; import edu.stanford.peer.rbtm.util.*; /* */ public abstract class AbstractProofNode implements ProofNode { /** The EntityExpression this node is about. */ EntityExpression _roleExp; /** The proof _graph this node is in, this reference is used while processing this node */ ProofGraph _graph; /** Nodes that can reach this node directly, evidences are credentials. */ protected HashSet parents; /** Nodes that this node can reach directly, evidecens are credentials. */ protected HashSet children; /** Backward solutions on this node */ protected HashSet backwardSolutions; /** Forward solutions on this node */ protected HashSet forwardSolutions; protected ArrayList backwardListeners; protected ArrayList forwardListeners; AbstractProofNode (ProofGraph graph, EntityExpression re, boolean trackAll) { _graph = graph; _roleExp = re; Debug.debugInfo("A new node is created for " + re); parents = new ResultEvidenceMap(trackAll); children = new ResultEvidenceMap(trackAll); backwardSolutions = new ResultEvidenceMap(trackAll); forwardSolutions = new ResultEvidenceMap(trackAll); backwardListeners = new HashSet(); forwardListeners = new HashSet(); // Call this in constructor instead of process methods, because // we want to record the fact that this node has been reached even // without further processing finishInit(); } /** * This method adds the node itself as both a forward solution and a backward * aolution to itself. If this behaviour is not appropriate, this method * should be overriden. */ protected void finishInit() { ForwardSolution fs = _graph.getForwardSolution(_roleExp); if (fs != null) { forwardSolutionAdded(this, fs); } BackwardSolution bs = _graph.getBackwardSolution(_roleExp); if (bs != null) { backwardSolutionAdded(this, bs); } } public ProofGraph getGraph() { return _graph; } public EntityExpression getRoleExp() { return _roleExp; } public ResultEvidenceMap getForwardSolutions() { return forwardSolutions; } public ResultEvidenceMap getBackwardSolutions() { return backwardSolutions; } // The method that does the work when we visit a node public void forwardProcess() { // first step: go over all credentials that have this as subject Iterator credIt = _graph.findCredentialsBySubject(_roleExp); while (credIt.hasNext()) { StaticCredential credential = (StaticCredential) credIt.next(); ProofNode node = _graph.addForwardNode(credential.getDefinedRole()); node.addParent(this, credential); //_graph.addProofEdge(this, node, credential); } // second step: find partial usage of this EntityExpression /* if (_roleExp instanceof Intersection) { return; } credIt = _graph.findCredentialsByPartialSubject(_roleExp); while (credIt.hasNext()) { StaticCredential credential = (StaticCredential) credIt.next(); ProofNode node = _graph.addForwardNode(credential.getDefinedRole()); int j = ((Intersection) credential.getSubject()).getIndexOf(_roleExp); forward.solutionAdded(new PartialSolution(_roleExp, j)); } */ } public void addBackwardListener(BackwardSolutionListener sl) { backwardListeners.add(sl); propagateBackwardSolutionsTo(sl); } public void addForwardListener(ForwardSolutionListener sl) { forwardListeners.add(sl); propagateForwardSolutionsTo(sl); } /** * Add a node as a parent to this node * @param node: the parent node */ public void addParent(ProofNode node, Object evidence) { if (! parents.contains(node.getRoleExp()) { parents.add(node); addForwardListener(node); } } public void addChild(ProofNode node, Object evidence) { if (children.putResultEvidence(node.getRoleExp(), evidence)) { addBackwardListener(node); } } public void backwardSolutionAdded(ProofNode s, BackwardSolution r) { if (backwardSolutions.putResultEvidence(r, s)) { // when solution r is new Debug.debugInfo("Solution added: " + getRoleExp() + "; " + s.getRoleExp() + "; " + r); propagateBackwardSolution(r); } } public void forwardSolutionAdded(ProofNode s, ForwardSolution r) { /* if (r instanceof PartialSolution) { Intersection re = r.getIntersection(); Integer index = r.getNumber(); HashMap value = (HashMap) partialSols.get(re); if (value == null) { // first piece value = new HashMap(); partialSols.put(re, value); } SmallSet evidences = value.get(index); if (evidences == null) { // A new piece evidences = new SmallSet(s); value.put(index, evidences); if (value.size() == re.getK()) { // have all pieces // Add an edge from current node to re // addEdge(); } } else if (trackAll) { evidences.add(s); } return; } */ if (forwardSolutions.putResultEvidence(r, s)) { Debug.debugInfo("Forward solution added to: " + getRoleExp() + "; " + s.getRoleExp() + "; " + r); propagateForwardSolution(r); } } protected void propagateBackwardSolutionsTo(BackwardSolutionListener listener) { Object[] sols = backwardSolutions.resultSet().toArray(); for (int i=0; i