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);
}
}
}