package com.nailabs.abac.trust; import com.nailabs.abac.trust.*; import com.nailabs.abac.test.*; import java.util.*; /** * This class handles the common functionality of the SimpleTTNode * and the LinkTTNode to be processed as parents of implication * edges. */ public abstract class StandardTTNode extends TargetNode { /** * Keepa track of the number of implication children which have failed. * When this counter reaches the number of implication children then, * failed satisfaction state will be propagated up to the parent. */ protected int implicationFailures = 0; /** * Standard target nodes have implication children. This field is * inherited to all subclasses. */ protected TTGNodeSet implicationChildren = new TTGNodeSet(); public StandardTTNode(TrustTarget target) { super(target); } /** * Records the new state and then propagates it to the parent listeners. * This method is specifically designed to handle failure propagation and * make sure all children have failed before sending the failure up to the * ancestors in the graph. * @param state The new satisfaction state to be propagated. */ public TTGNodeSet receive(TrustTarget source, SatisfactionState state) { if(state.getState() == SatisfactionState.FAILED) { implicationFailures++; //if(++implicationFailures < implicationChildren.size()) { if(!isFailed()) { debug("satisfaction", "partial failure" + implicationFailures + "/" + implicationParents.size()); //bail out for now... return new TTGNodeSet(); } } return super.receive(source, state); } protected boolean isFailed() { if(!Debug.sendFailure()) { debug("satisfaction","failure is turned off!!"); return false; } if(!processor.isFullyProcessed()) { return false; } if(processor.isFullyProcessed() && implicationChildren.size() == 0) { return true; } Iterator i = implicationChildren.values().iterator(); while(i.hasNext()) { TargetNode child = (TargetNode)i.next(); if(child.getSatisfactionValue() != SatisfactionState.FAILED) { return false; } } return true; // all false so we fail here } /** * handle satisfaction state failure propagation */ public void updateProcessingState(ProcessingState state) { getProcessingState().update(state); if(isFailed()) { SatisfactionState failure = new SatisfactionState(SatisfactionState.FAILED); receive(null, failure); } } /** * Adds an implication edge to this node. This creates an implication * edge between parent and child. */ public void addImplicationChild(TargetNode child) { if(child != null) { implicationChildren.add(child); setChanged(); notifyObservers(this); } } }