1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.model.processor;
15
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Properties;
22 import java.util.Stack;
23 import java.util.function.Supplier;
24
25 import ch.qos.logback.core.Appender;
26 import ch.qos.logback.core.Context;
27 import ch.qos.logback.core.joran.GenericXMLConfigurator;
28 import ch.qos.logback.core.joran.JoranConfiguratorBase;
29 import ch.qos.logback.core.joran.JoranConstants;
30 import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
31 import ch.qos.logback.core.joran.util.beans.BeanDescriptionCache;
32 import ch.qos.logback.core.model.Model;
33 import ch.qos.logback.core.model.util.VariableSubstitutionsHelper;
34 import ch.qos.logback.core.spi.AppenderAttachable;
35 import ch.qos.logback.core.spi.ContextAwareBase;
36 import ch.qos.logback.core.spi.ContextAwarePropertyContainer;
37 import ch.qos.logback.core.spi.PropertyContainer;
38
39 public class ModelInterpretationContext extends ContextAwareBase implements ContextAwarePropertyContainer {
40
41 Stack<Object> objectStack;
42 Stack<Model> modelStack;
43
44
45
46
47
48
49
50
51 Supplier<? extends GenericXMLConfigurator> configuratorSupplier;
52
53
54 Map<String, Object> objectMap;
55 protected VariableSubstitutionsHelper variableSubstitutionsHelper;
56 protected Map<String, String> importMap;
57
58 final private BeanDescriptionCache beanDescriptionCache;
59 final DefaultNestedComponentRegistry defaultNestedComponentRegistry = new DefaultNestedComponentRegistry();
60 List<DependencyDefinition> dependencyDefinitionList = new ArrayList<>();
61 final List<String> startedDependees = new ArrayList<>();
62
63 Object configuratorHint;
64
65 Model topModel;
66
67 public ModelInterpretationContext(Context context) {
68 this(context, null);
69 }
70
71 public ModelInterpretationContext(Context context, Object configuratorHint) {
72 this.context = context;
73 this.configuratorHint = configuratorHint;
74 this.objectStack = new Stack<>();
75 this.modelStack = new Stack<>();
76 this.beanDescriptionCache = new BeanDescriptionCache(context);
77 objectMap = new HashMap<>(5);
78 variableSubstitutionsHelper = new VariableSubstitutionsHelper(context);
79 importMap = new HashMap<>(5);
80 }
81
82 public ModelInterpretationContext(ModelInterpretationContext otherMic) {
83 this(otherMic.context, otherMic.configuratorHint);
84 importMap = new HashMap<>(otherMic.importMap);
85 variableSubstitutionsHelper = new VariableSubstitutionsHelper(context, otherMic.getCopyOfPropertyMap());
86 defaultNestedComponentRegistry.duplicate(otherMic.getDefaultNestedComponentRegistry());
87 createAppenderBags();
88 }
89
90 public Map<String, Object> getObjectMap() {
91 return objectMap;
92 }
93
94 public void createAppenderBags() {
95 objectMap.put(JoranConstants.APPENDER_BAG, new HashMap<String, Appender<?>>());
96 objectMap.put(JoranConstants.APPENDER_REF_BAG, new HashMap<String, AppenderAttachable<?>>());
97 }
98
99 public Model getTopModel() {
100 return topModel;
101 }
102
103 public void setTopModel(Model topModel) {
104 this.topModel = topModel;
105 }
106
107
108
109 public void pushModel(Model m) {
110 modelStack.push(m);
111 }
112
113 public Model peekModel() {
114 return modelStack.peek();
115 }
116
117 public boolean isModelStackEmpty() {
118 return modelStack.isEmpty();
119 }
120
121 public Model popModel() {
122 return modelStack.pop();
123 }
124
125
126
127 public Stack<Object> getObjectStack() {
128 return objectStack;
129 }
130
131 public boolean isObjectStackEmpty() {
132 return objectStack.isEmpty();
133 }
134
135 public Object peekObject() {
136 return objectStack.peek();
137 }
138
139 public void pushObject(Object o) {
140 objectStack.push(o);
141 }
142
143 public Object popObject() {
144 return objectStack.pop();
145 }
146
147 public Object getObject(int i) {
148 return objectStack.get(i);
149 }
150
151
152
153 public Object getConfiguratorHint() {
154 return configuratorHint;
155 }
156
157 public void setConfiguratorHint(Object configuratorHint) {
158 this.configuratorHint = configuratorHint;
159 }
160
161 public BeanDescriptionCache getBeanDescriptionCache() {
162 return beanDescriptionCache;
163 }
164
165 public String subst(String ref) {
166 return variableSubstitutionsHelper.subst(ref);
167 }
168
169
170 public DefaultNestedComponentRegistry getDefaultNestedComponentRegistry() {
171 return defaultNestedComponentRegistry;
172 }
173
174
175
176 public void addDependencyDefinition(DependencyDefinition dd) {
177 dependencyDefinitionList.add(dd);
178 }
179
180 public List<DependencyDefinition> getDependencyDefinitions() {
181 return Collections.unmodifiableList(dependencyDefinitionList);
182 }
183
184 public List<String> getDependeeNamesForModel(Model model) {
185 List<String> dependencyList = new ArrayList<>();
186 for (DependencyDefinition dd : dependencyDefinitionList) {
187 if (dd.getDepender() == model) {
188 dependencyList.add(dd.getDependee());
189 }
190 }
191 return dependencyList;
192 }
193
194 public boolean hasDependers(String dependeeName) {
195
196 if (dependeeName == null || dependeeName.trim().length() == 0) {
197 new IllegalArgumentException("Empty dependeeName name not allowed here");
198 }
199
200 for (DependencyDefinition dd : dependencyDefinitionList) {
201 if (dd.dependee.equals(dependeeName))
202 return true;
203 }
204
205 return false;
206 }
207
208
209 public void markStartOfNamedDependee(String name) {
210 startedDependees.add(name);
211 }
212
213 public boolean isNamedDependeeStarted(String name) {
214 return startedDependees.contains(name);
215 }
216
217
218
219
220
221
222
223 @Override
224 public void addSubstitutionProperty(String key, String value) {
225 variableSubstitutionsHelper.addSubstitutionProperty(key, value);
226 }
227
228
229
230
231
232 public String getProperty(String key) {
233 return variableSubstitutionsHelper.getProperty(key);
234 }
235
236 @Override
237 public Map<String, String> getCopyOfPropertyMap() {
238 return variableSubstitutionsHelper.getCopyOfPropertyMap();
239 }
240
241
242
243
244
245
246
247
248
249
250
251 public void addImport(String stem, String fqcn) {
252 importMap.put(stem, fqcn);
253 }
254
255 public Map<String, String> getImportMapCopy() {
256 return new HashMap<>(importMap);
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270
271 public String getImport(String stem) {
272 if (stem == null)
273 return null;
274
275 String result = importMap.get(stem);
276 if (result == null)
277 return stem;
278 else
279 return result;
280 }
281
282
283
284
285
286
287 public Supplier<? extends GenericXMLConfigurator> getConfiguratorSupplier() {
288 return this.configuratorSupplier;
289 }
290
291
292
293
294
295 public void setConfiguratorSupplier(Supplier<? extends GenericXMLConfigurator> configuratorSupplier) {
296 this.configuratorSupplier = configuratorSupplier;
297 }
298 }