View Javadoc

1   /**
2    * Logback: the generic, reliable, fast and flexible logging framework.
3    * 
4    * Copyright (C) 2000-2008, 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  package ch.qos.logback.core.joran.action;
11  
12  import java.util.Stack;
13  
14  import org.xml.sax.Attributes;
15  
16  import ch.qos.logback.core.joran.spi.InterpretationContext;
17  import ch.qos.logback.core.joran.spi.Pattern;
18  import ch.qos.logback.core.joran.spi.PropertySetter;
19  import ch.qos.logback.core.util.AggregationType;
20  
21  /**
22   * This action is responsible for tying together a parent object with one of its
23   * <em>simple</em> properties specified as an element but for which there is
24   * no explicit rule.
25   * 
26   * @author Ceki G&uuml;lc&uuml;
27   */
28  public class NestedBasicPropertyIA extends ImplicitAction {
29  
30  
31    // We use a stack of IADataForBasicProperty objects in order to 
32    // support nested elements which are handled by the same NestedBasicPropertyIA instance.
33    // We push a IADataForBasicProperty instance in the isApplicable method (if the
34    // action is applicable) and pop it in the end() method.
35    // The XML well-formedness property will guarantee that a push will eventually
36    // be followed by the corresponding pop.
37    Stack<IADataForBasicProperty> actionDataStack = new Stack<IADataForBasicProperty>();
38  
39    public boolean isApplicable(Pattern pattern, Attributes attributes,
40        InterpretationContext ec) {
41      // System.out.println("in NestedSimplePropertyIA.isApplicable [" + pattern +
42      // "]");
43      String nestedElementTagName = pattern.peekLast();
44  
45      // no point in attempting if there is no parent object
46      if (ec.isEmpty()) {
47        return false;
48      }
49  
50      Object o = ec.peekObject();
51      PropertySetter parentBean = new PropertySetter(o);
52      parentBean.setContext(context);
53  
54      AggregationType aggregationType = parentBean
55          .computeAggregationType(nestedElementTagName);
56  
57      switch (aggregationType) {
58      case NOT_FOUND:
59      case AS_COMPLEX_PROPERTY:
60      case AS_COMPLEX_PROPERTY_COLLECTION:
61        return false;
62  
63      case AS_BASIC_PROPERTY:
64      case AS_BASIC_PROPERTY_COLLECTION:
65        IADataForBasicProperty ad = new IADataForBasicProperty(parentBean,
66            aggregationType, nestedElementTagName);
67        actionDataStack.push(ad);
68        // addInfo("NestedSimplePropertyIA deemed applicable [" + pattern + "]");
69        return true;
70      default:
71        addError("PropertySetter.canContainComponent returned " + aggregationType);
72        return false;
73      }
74    }
75  
76    public void begin(InterpretationContext ec, String localName,
77        Attributes attributes) {
78      // NOP
79    }
80  
81    public void body(InterpretationContext ec, String body) {
82  
83      String finalBody = ec.subst(body);
84      // System.out.println("body "+body+", finalBody="+finalBody);
85      // get the action data object pushed in isApplicable() method call
86      IADataForBasicProperty actionData = (IADataForBasicProperty) actionDataStack.peek();
87      switch (actionData.aggregationType) {
88      case AS_BASIC_PROPERTY:
89        actionData.parentBean.setProperty(actionData.propertyName, finalBody);
90        break;
91      case AS_BASIC_PROPERTY_COLLECTION:
92        actionData.parentBean
93            .addBasicProperty(actionData.propertyName, finalBody);
94      }
95    }
96  
97    public void end(InterpretationContext ec, String tagName) {
98      // pop the action data object pushed in isApplicable() method call
99      actionDataStack.pop();
100   }
101 }