View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
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     // if boolResult==false & missing else,  listToPlay may be null
113     if(listToPlay != null) {
114       // insert past this event
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 }