1 | package com.nailabs.abac.trust; |
---|
2 | |
---|
3 | import com.nailabs.abac.trust.*; |
---|
4 | import com.nailabs.abac.test.*; |
---|
5 | import java.util.*; |
---|
6 | |
---|
7 | /** |
---|
8 | * This class handles the common functionality of the <CODE>SimpleTTNode</CODE> |
---|
9 | * and the <CODE>LinkTTNode</CODE> to be processed as parents of implication |
---|
10 | * edges. |
---|
11 | */ |
---|
12 | public abstract class StandardTTNode extends TargetNode { |
---|
13 | |
---|
14 | /** |
---|
15 | * Keepa track of the number of implication children which have failed. |
---|
16 | * When this counter reaches the number of implication children then, |
---|
17 | * failed satisfaction state will be propagated up to the parent. |
---|
18 | */ |
---|
19 | protected int implicationFailures = 0; |
---|
20 | |
---|
21 | /** |
---|
22 | * Standard target nodes have implication children. This field is |
---|
23 | * inherited to all subclasses. |
---|
24 | */ |
---|
25 | protected TTGNodeSet implicationChildren = new TTGNodeSet(); |
---|
26 | |
---|
27 | public StandardTTNode(TrustTarget target) { |
---|
28 | super(target); |
---|
29 | } |
---|
30 | |
---|
31 | |
---|
32 | /** |
---|
33 | * Records the new state and then propagates it to the parent listeners. |
---|
34 | * This method is specifically designed to handle failure propagation and |
---|
35 | * make sure all children have failed before sending the failure up to the |
---|
36 | * ancestors in the graph. |
---|
37 | * @param state The new satisfaction state to be propagated. |
---|
38 | */ |
---|
39 | public TTGNodeSet receive(TrustTarget source, SatisfactionState state) { |
---|
40 | if(state.getState() == SatisfactionState.FAILED) { |
---|
41 | implicationFailures++; |
---|
42 | //if(++implicationFailures < implicationChildren.size()) { |
---|
43 | if(!isFailed()) { |
---|
44 | debug("satisfaction", "partial failure" + implicationFailures + |
---|
45 | "/" + implicationParents.size()); |
---|
46 | //bail out for now... |
---|
47 | return new TTGNodeSet(); |
---|
48 | } |
---|
49 | } |
---|
50 | return super.receive(source, state); |
---|
51 | } |
---|
52 | |
---|
53 | protected boolean isFailed() { |
---|
54 | if(!Debug.sendFailure()) { |
---|
55 | debug("satisfaction","failure is turned off!!"); |
---|
56 | return false; |
---|
57 | } |
---|
58 | if(!processor.isFullyProcessed()) { |
---|
59 | return false; |
---|
60 | } |
---|
61 | if(processor.isFullyProcessed() && implicationChildren.size() == 0) { |
---|
62 | return true; |
---|
63 | } |
---|
64 | Iterator i = implicationChildren.values().iterator(); |
---|
65 | while(i.hasNext()) { |
---|
66 | TargetNode child = (TargetNode)i.next(); |
---|
67 | if(child.getSatisfactionValue() != SatisfactionState.FAILED) { |
---|
68 | return false; |
---|
69 | } |
---|
70 | } |
---|
71 | return true; // all false so we fail here |
---|
72 | } |
---|
73 | |
---|
74 | /** |
---|
75 | * handle satisfaction state failure propagation |
---|
76 | */ |
---|
77 | public void updateProcessingState(ProcessingState state) { |
---|
78 | getProcessingState().update(state); |
---|
79 | if(isFailed()) { |
---|
80 | SatisfactionState failure = |
---|
81 | new SatisfactionState(SatisfactionState.FAILED); |
---|
82 | receive(null, failure); |
---|
83 | } |
---|
84 | } |
---|
85 | |
---|
86 | /** |
---|
87 | * Adds an implication edge to this node. This creates an implication |
---|
88 | * edge between parent and child. |
---|
89 | */ |
---|
90 | public void addImplicationChild(TargetNode child) { |
---|
91 | if(child != null) { |
---|
92 | implicationChildren.add(child); |
---|
93 | setChanged(); |
---|
94 | notifyObservers(this); |
---|
95 | } |
---|
96 | } |
---|
97 | |
---|
98 | |
---|
99 | } |
---|