1 /** 2 * Logback: the reliable, fast and flexible logging library for Java. 3 * 4 * Copyright (C) 1999-2006, QOS.ch 5 * 6 * This library is free software, you can redistribute it and/or modify it under 7 * the terms of the GNU Lesser General Public License as published by the Free 8 * Software Foundation. 9 */ 10 11 package chapter3.calculator; 12 13 import java.util.Stack; 14 15 import org.xml.sax.Attributes; 16 17 import ch.qos.logback.core.joran.action.Action; 18 import ch.qos.logback.core.joran.spi.InterpretationContext; 19 import ch.qos.logback.core.util.OptionHelper; 20 21 22 /** 23 * ComputationAction2 will print the result of the compuration made by 24 * children elements but only if the compuration itself is named, that is if the 25 * name attribute of the associated computation element is not null. In other 26 * words, anonymous computations will not print their result. 27 * 28 * ComputationAction2 differs from ComputationAction1 in its handling of 29 * instance variables. ComputationAction1 has a simple <Code>nameStr</code> 30 * instance variable. This variable is set when the begin() method is called 31 * and then later used within the end() method. 32 * 33 * This simple approach works properly if the begin() and end() 34 * method of a given action are expected to be called in sequence. However, 35 * there are situations where the begin() method of the same action instance is 36 * invoked multiple times before the matching end() method is invoked. 37 * 38 * When this happens, the second call to begin() overwrites values set by 39 * the first invocation to begin(). The solution is to save parameter values 40 * into a separate stack. The well-formedness of XML will guarantee that a value 41 * saved by one begin() will be consumed only by the matching end() method. 42 * 43 * Note that in the vast majority of cases there is no need to resort to a 44 * separate stack for each variable. The situation of successibe begin() 45 * invocations can only occur if: 46 * 47 * 1) the associated pattern contains a wildcard, i.e. the * character 48 * 49 * and 50 * 51 * 2) the associated element tag can contain itself as a child 52 * 53 * For example, "*/computation" pattern means that computations can contain 54 * other computation elements as children. 55 * 56 * @author Ceki Gülcü 57 */ 58 public class ComputationAction2 extends Action { 59 public static String NAME_ATR = "name"; 60 61 Stack<String> nameStrStack = new Stack<String>(); 62 63 64 public void begin(InterpretationContext ec, String name, Attributes attributes) { 65 String nameStr = attributes.getValue(NAME_ATR); 66 // save nameStr value in a special stack. Note that the value is saved 67 // even if it is empty or null. 68 nameStrStack.push(nameStr); 69 } 70 71 public void end(InterpretationContext ec, String name) { 72 // pop nameStr value from the special stack 73 String nameStr = (String) nameStrStack.pop(); 74 75 if (OptionHelper.isEmpty(nameStr)) { 76 // nothing to do 77 } else { 78 Integer i = (Integer) ec.peekObject(); 79 System.out.println( 80 "The computation named [" + nameStr + "] resulted in the value " + i); 81 } 82 } 83 }