1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.joran.conditional;
15
16 import java.util.List;
17 import java.util.Stack;
18
19 import ch.qos.logback.core.util.EnvUtil;
20 import org.xml.sax.Attributes;
21
22 import ch.qos.logback.core.joran.action.Action;
23 import ch.qos.logback.core.joran.event.SaxEvent;
24 import ch.qos.logback.core.joran.spi.ActionException;
25 import ch.qos.logback.core.joran.spi.InterpretationContext;
26 import ch.qos.logback.core.joran.spi.Interpreter;
27 import ch.qos.logback.core.util.OptionHelper;
28
29 public class IfAction extends Action {
30 private static final String CONDITION_ATTR = "condition";
31
32 public static String MISSING_JANINO_MSG = "Could not find Janino library on the class path. Skipping conditional processing.";
33
34 Stack<IfState> stack = new Stack<IfState>();
35
36 @Override
37 public void begin(InterpretationContext ic, String name, Attributes attributes)
38 throws ActionException {
39
40 IfState state = new IfState();
41 boolean emptyStack = stack.isEmpty();
42 stack.push(state);
43
44 if(!emptyStack) {
45 return;
46 }
47
48 ic.pushObject(this);
49 if(!EnvUtil.isJaninoAvailable()) {
50 addError(MISSING_JANINO_MSG);
51 return;
52 }
53
54 state.active = true;
55 Condition condition = null;
56 String conditionAttribute = attributes.getValue(CONDITION_ATTR);
57
58
59 if (!OptionHelper.isEmpty(conditionAttribute)) {
60 conditionAttribute = OptionHelper.substVars(conditionAttribute, ic, context);
61 PropertyEvalScriptBuilder pesb = new PropertyEvalScriptBuilder(ic);
62 pesb.setContext(context);
63 try {
64 condition = pesb.build(conditionAttribute);
65 } catch (Exception e) {
66 addError("Failed to parse condition ["+conditionAttribute+"]", e);
67 }
68
69 if(condition!=null) {
70 state.boolResult = condition.evaluate();
71 }
72
73 }
74 }
75
76
77 @Override
78 public void end(InterpretationContext ic, String name) throws ActionException {
79
80 IfState state = stack.pop();
81 if(!state.active) {
82 return;
83 }
84
85
86 Object o = ic.peekObject();
87 if (o == null) {
88 throw new IllegalStateException("Unexpected null object on stack");
89 }
90 if (!(o instanceof IfAction)) {
91 throw new IllegalStateException("Unexpected object of type ["
92 + o.getClass() + "] on stack");
93 }
94
95 if (o != this) {
96 throw new IllegalStateException(
97 "IfAction different then current one on stack");
98 }
99 ic.popObject();
100
101 if (state.boolResult == null) {
102 addError("Failed to determine \"if then else\" result");
103 return;
104 }
105
106 Interpreter interpreter = ic.getJoranInterpreter();
107 List<SaxEvent> listToPlay = state.thenSaxEventList;
108 if (!state.boolResult) {
109 listToPlay = state.elseSaxEventList;
110 }
111
112
113 if(listToPlay != null) {
114
115 interpreter.getEventPlayer().addEventsDynamically(listToPlay, 1);
116 }
117
118 }
119
120
121 public void setThenSaxEventList(List<SaxEvent> thenSaxEventList) {
122 IfState state = stack.firstElement();
123 if(state.active) {
124 state.thenSaxEventList = thenSaxEventList;
125 } else {
126 throw new IllegalStateException("setThenSaxEventList() invoked on inactive IfAction");
127 }
128 }
129
130 public void setElseSaxEventList(List<SaxEvent> elseSaxEventList) {
131 IfState state = stack.firstElement();
132 if(state.active) {
133 state.elseSaxEventList = elseSaxEventList;
134 } else {
135 throw new IllegalStateException("setElseSaxEventList() invoked on inactive IfAction");
136 }
137
138 }
139
140 public boolean isActive() {
141 if(stack == null) return false;
142 if(stack.isEmpty()) return false;
143 return stack.peek().active;
144 }
145 }
146
147 class IfState {
148 Boolean boolResult;
149 List<SaxEvent> thenSaxEventList;
150 List<SaxEvent> elseSaxEventList;
151 boolean active;
152 }