View Javadoc

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