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.spi;
15  
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.Iterator;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Properties;
22  import java.util.Stack;
23  
24  import org.xml.sax.Locator;
25  
26  import ch.qos.logback.core.Context;
27  import ch.qos.logback.core.joran.action.Action;
28  import ch.qos.logback.core.joran.event.InPlayListener;
29  import ch.qos.logback.core.joran.event.SaxEvent;
30  import ch.qos.logback.core.spi.ContextAwareBase;
31  import ch.qos.logback.core.spi.PropertyContainer;
32  import ch.qos.logback.core.util.OptionHelper;
33  
34  /**
35   * 
36   * An InterpretationContext contains the contextual state of a Joran parsing
37   * session. {@link Action} objects depend on this context to exchange and store
38   * information.
39   * 
40   * @author Ceki Gülcü
41   */
42  public class InterpretationContext extends ContextAwareBase implements
43      PropertyContainer {
44    Stack<Object> objectStack;
45    Map<String, Object> objectMap;
46    Map<String, String> propertiesMap;
47  
48    Interpreter joranInterpreter;
49    final List<InPlayListener> listenerList = new ArrayList<InPlayListener>();
50    DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry();
51  
52    public InterpretationContext(Context context, Interpreter joranInterpreter) {
53      this.context = context;
54      this.joranInterpreter = joranInterpreter;
55      objectStack = new Stack<Object>();
56      objectMap = new HashMap<String, Object>(5);
57      propertiesMap = new HashMap<String, String>(5);
58    }
59  
60    
61    public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
62      return defaultNestedComponentRegistry;
63    }
64    
65    void setPropertiesMap(Map<String, String> propertiesMap) {
66      this.propertiesMap = propertiesMap;
67    }
68  
69    String updateLocationInfo(String msg) {
70      Locator locator = joranInterpreter.getLocator();
71  
72      if (locator != null) {
73        return msg + locator.getLineNumber() + ":" + locator.getColumnNumber();
74      } else {
75        return msg;
76      }
77    }
78  
79    public Locator getLocator() {
80      return joranInterpreter.getLocator();
81    }
82  
83    public Interpreter getJoranInterpreter() {
84      return joranInterpreter;
85    }
86  
87    public Stack<Object> getObjectStack() {
88      return objectStack;
89    }
90  
91    public boolean isEmpty() {
92      return objectStack.isEmpty();
93    }
94  
95    public Object peekObject() {
96      return objectStack.peek();
97    }
98  
99    public void pushObject(Object o) {
100     objectStack.push(o);
101   }
102 
103   public Object popObject() {
104     return objectStack.pop();
105   }
106 
107   public Object getObject(int i) {
108     return objectStack.get(i);
109   }
110 
111   public Map<String, Object> getObjectMap() {
112     return objectMap;
113   }
114 
115   /**
116    * Add a property to the properties of this execution context. If the property
117    * exists already, it is overwritten.
118    */
119   public void addSubstitutionProperty(String key, String value) {
120     if (key == null || value == null) {
121       return;
122     }
123     // values with leading or trailing spaces are bad. We remove them now.
124     value = value.trim();
125     propertiesMap.put(key, value);
126   }
127 
128   public void addSubstitutionProperties(Properties props) {
129     if (props == null) {
130       return;
131     }
132     Iterator i = props.keySet().iterator();
133     while (i.hasNext()) {
134       String key = (String) i.next();
135       addSubstitutionProperty(key, props.getProperty(key));
136     }
137   }
138 
139   /**
140    * If a key is found in propertiesMap then return it. Otherwise, delegate to
141    * the context.
142    */
143   public String getProperty(String key) {
144     String v = propertiesMap.get(key);
145     if (v != null) {
146       return v;
147     } else {
148       return context.getProperty(key);
149     }
150   }
151 
152   public String subst(String value) {
153     if (value == null) {
154       return null;
155     }
156     return OptionHelper.substVars(value, this, context);
157   }
158 
159 
160   
161 
162   public boolean isListenerListEmpty() {
163     return listenerList.isEmpty();
164   }
165   
166   public void addInPlayListener(InPlayListener ipl) {
167     if (listenerList.contains(ipl)) {
168       addWarn("InPlayListener " + ipl + " has been already registered");
169     } else {
170       listenerList.add(ipl);
171     }
172   }
173 
174   public boolean removeInPlayListener(InPlayListener ipl) {
175     return listenerList.remove(ipl);
176   }
177 
178   void fireInPlay(SaxEvent event) {
179     for (InPlayListener ipl : listenerList) {
180       ipl.inPlay(event);
181     }
182   }
183 }