001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.joran.spi; 015 016import java.util.Map; 017import java.util.Stack; 018 019import ch.qos.logback.core.Context; 020import ch.qos.logback.core.joran.action.Action; 021import ch.qos.logback.core.model.Model; 022import ch.qos.logback.core.spi.ContextAwareBase; 023import ch.qos.logback.core.spi.PropertyContainer; 024import ch.qos.logback.core.spi.ScanException; 025import ch.qos.logback.core.util.OptionHelper; 026 027/** 028 * 029 * An InterpretationContext contains the contextual state of a Joran parsing 030 * session. {@link Action} objects depend on this context to exchange and store 031 * information. 032 * 033 * @author Ceki Gülcü 034 */ 035public class SaxEventInterpretationContext extends ContextAwareBase implements PropertyContainer { 036 // Stack<Object> xobjectStack; 037 Stack<Model> modelStack; 038 // Stack<ImplicitActionDataBase> implicitActionDataStack; 039 040 // Map<String, Object> objectMap; 041 // Map<String, String> propertiesMap; 042 // Map<String, String> importMap; 043 044// final HashMap<Model, List<String>> dependenciesMap = new HashMap<>(); 045// final List<String> startedDependencies = new ArrayList<>(); 046 047 SaxEventInterpreter saxEventInterpreter; 048// DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry(); 049// private BeanDescriptionCache beanDescriptionCache; 050 051 public SaxEventInterpretationContext(Context context, SaxEventInterpreter saxEventInterpreter) { 052 this.context = context; 053 this.saxEventInterpreter = saxEventInterpreter; 054 // this.objectStack = new Stack<>(); 055 this.modelStack = new Stack<>(); 056 // this.implicitActionDataStack = new Stack<>(); 057 058 // objectMap = new HashMap<>(5); 059 // propertiesMap = new HashMap<>(5); 060 // importMap = new HashMap<>(5); 061 } 062 063// public BeanDescriptionCache getBeanDescriptionCache() { 064// if (beanDescriptionCache == null) { 065// beanDescriptionCache = new BeanDescriptionCache(getContext()); 066// } 067// return beanDescriptionCache; 068// } 069// 070// public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() { 071// return defaultNestedComponentRegistry; 072// } 073 074// public Map<String, String> getCopyOfPropertyMap() { 075// return new HashMap<String, String>(propertiesMap); 076// } 077// 078// void setPropertiesMap(Map<String, String> propertiesMap) { 079// this.propertiesMap = propertiesMap; 080// } 081 082// public HashMap<Model, List<String>> getDependenciesMap() { 083// return dependenciesMap; 084// } 085 086// public void addDependency(Model model, String ref) { 087// List<String> refList = dependenciesMap.get(model); 088// if(refList == null) { 089// refList = new ArrayList<>(); 090// } 091// refList.add(ref); 092// dependenciesMap.put(model, refList); 093// } 094 095// public List<String> getDependencies(Model model) { 096// return dependenciesMap.get(model); 097// } 098 099// public String getLineNumber() { 100// if(saxEventInterpreter == null) { 101// return "NA"; 102// } 103// Locator locator = saxEventInterpreter.getLocator(); 104// 105// if (locator != null) { 106// return Integer.toString(locator.getLineNumber()); 107// } else { 108// return "NA"; 109// } 110// } 111 112 public SaxEventInterpreter getSaxEventInterpreter() { 113 return saxEventInterpreter; 114 } 115 116// public Stack<Object> getObjectStack() { 117// return objectStack; 118// } 119 120// /** 121// * @deprecated Use {@link isObjectStackEmpty isObjectStackEmpty()} method 122// * instead 123// * @return 124// */ 125// public boolean isEmpty() { 126// return isObjectStackEmpty(); 127// } 128 129// /** 130// * 131// * @return whether the objectStack is empty or not 132// */ 133// public boolean isObjectStackEmpty() { 134// return objectStack.isEmpty(); 135// } 136// 137// public Object peekObject() { 138// return objectStack.peek(); 139// } 140// 141// public void pushObject(Object o) { 142// objectStack.push(o); 143// } 144// 145// public Object popObject() { 146// return objectStack.pop(); 147// } 148 149 /** 150 * actionDataStack contains ActionData instances We use a stack of ActionData 151 * objects in order to support nested elements which are handled by the same 152 * NestedComplexPropertyIA instance. We push a ActionData instance in the 153 * isApplicable method (if the action is applicable) and pop it in the end() 154 * method. The XML well-formedness property will guarantee that a push will 155 * eventually be followed by a corresponding pop. 156 */ 157// public Stack<ImplicitActionDataBase> getImplcitActionDataStack() { 158// return implicitActionDataStack; 159// } 160// 161 /** 162 * Return the Model at the top of the model stack, may return null. 163 * 164 * @return 165 */ 166 public Model peekModel() { 167 if(modelStack.isEmpty()) { 168 return null; 169 } 170 return modelStack.peek(); 171 } 172 173 public void pushModel(Model m) { 174 modelStack.push(m); 175 } 176 177 public boolean isModelStackEmpty() { 178 return modelStack.isEmpty(); 179 } 180 181 public Model popModel() { 182 return modelStack.pop(); 183 } 184 185 public Stack<Model> getCopyOfModelStack() { 186 Stack<Model> copy = new Stack<>(); 187 copy.addAll(modelStack); 188 return copy; 189 } 190 191// public Object getObject(int i) { 192// return objectStack.get(i); 193// } 194 195// public Map<String, Object> getObjectMap() { 196// return objectMap; 197// } 198 199// /** 200// * Add a property to the properties of this execution context. If the property 201// * exists already, it is overwritten. 202// */ 203// public void addSubstitutionProperty(String key, String value) { 204// if (key == null || value == null) { 205// return; 206// } 207// // values with leading or trailing spaces are bad. We remove them now. 208// value = value.trim(); 209// propertiesMap.put(key, value); 210// } 211 212// public void addSubstitutionProperties(Properties props) { 213// if (props == null) { 214// return; 215// } 216// for (Object keyObject : props.keySet()) { 217// String key = (String) keyObject; 218// String val = props.getProperty(key); 219// addSubstitutionProperty(key, val); 220// } 221// } 222 223 /** 224 * If a key is found in propertiesMap then return it. Otherwise, delegate to the 225 * context. 226 */ 227 public String getProperty(String key) { 228 return context.getProperty(key); 229 } 230 231 @Override 232 public Map<String, String> getCopyOfPropertyMap() { 233 return null; 234 } 235 236 public String subst(String value) { 237 if (value == null) { 238 return null; 239 } 240 241 try { 242 return OptionHelper.substVars(value, this, context); 243 } catch (ScanException | IllegalArgumentException e) { 244 addError("Problem while parsing [" + value + "]", e); 245 return value; 246 } 247 } 248 249// public void markStartOfNamedDependency(String name) { 250// startedDependencies.add(name); 251// } 252// public boolean isNamedDependencyStarted(String name) { 253// return startedDependencies.contains(name); 254// } 255 256// /** 257// * Add an import to the importMao 258// * @param stem the class to import 259// * @param fqcn the fully qualified name of the class 260// * 261// * @since 1.3 262// */ 263// public void addImport(String stem, String fqcn) { 264// importMap.put(stem, fqcn); 265// } 266// 267// /** 268// * Given a stem, get the fully qualified name of the class corresponding to the stem. 269// * For unknown stems, returns the stem as is. If stem is null, null is returned. 270// * 271// * @param stem may be null 272// * @return fully qualified name of the class corresponding to the stem. For unknown stems, returns the stem as is. 273// * If stem is null, null is returned. 274// * @since 1.3 275// */ 276// public String getImport(String stem) { 277// if(stem == null) 278// return null; 279// 280// String result = importMap.get(stem); 281// if(result == null) 282// return stem; 283// else 284// return result; 285// } 286 287}