1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.joran.spi;
15
16 import java.util.ArrayList;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Stack;
21 import java.util.Vector;
22
23 import org.xml.sax.Attributes;
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.action.ImplicitAction;
29 import ch.qos.logback.core.joran.event.BodyEvent;
30 import ch.qos.logback.core.joran.event.EndEvent;
31 import ch.qos.logback.core.joran.event.StartEvent;
32 import ch.qos.logback.core.spi.ContextAwareImpl;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class Interpreter {
68 private static List EMPTY_LIST = new Vector(0);
69
70 final private RuleStore ruleStore;
71 final private InterpretationContext interpretationContext;
72 final private ArrayList<ImplicitAction> implicitActions;
73 final private CAI_WithLocatorSupport cai;
74 private Pattern pattern;
75 Locator locator;
76 EventPlayer eventPlayer;
77
78
79
80
81
82
83
84
85
86 Stack<List> actionListStack;
87
88
89
90
91
92 Pattern skip = null;
93
94 public Interpreter(Context context, RuleStore rs, Pattern initialPattern) {
95 this.cai = new CAI_WithLocatorSupport(this);
96 this.cai.setContext(context);
97 ruleStore = rs;
98 interpretationContext = new InterpretationContext(context, this);
99 implicitActions = new ArrayList<ImplicitAction>(3);
100 this.pattern = initialPattern;
101 actionListStack = new Stack<List>();
102 eventPlayer = new EventPlayer(this);
103 }
104
105 public EventPlayer getEventPlayer() {
106 return eventPlayer;
107 }
108
109 public void setInterpretationContextPropertiesMap(
110 Map<String, String> propertiesMap) {
111 interpretationContext.setPropertiesMap(propertiesMap);
112 }
113
114
115
116
117 public InterpretationContext getExecutionContext() {
118 return getInterpretationContext();
119 }
120
121 public InterpretationContext getInterpretationContext() {
122 return interpretationContext;
123 }
124
125 public void startDocument() {
126 }
127
128 public void startElement(StartEvent se) {
129 setDocumentLocator(se.getLocator());
130 startElement(se.namespaceURI, se.localName, se.qName, se.attributes);
131 }
132
133 private void startElement(String namespaceURI, String localName,
134 String qName, Attributes atts) {
135
136 String tagName = getTagName(localName, qName);
137 pattern.push(tagName);
138
139 if (skip != null) {
140
141 pushEmptyActionList();
142 return;
143 }
144
145 List applicableActionList = getApplicableActionList(pattern, atts);
146 if (applicableActionList != null) {
147 actionListStack.add(applicableActionList);
148 callBeginAction(applicableActionList, tagName, atts);
149 } else {
150
151 pushEmptyActionList();
152 String errMsg = "no applicable action for [" + tagName
153 + "], current pattern is [" + pattern + "]";
154 cai.addError(errMsg);
155 }
156 }
157
158
159
160
161 private void pushEmptyActionList() {
162 actionListStack.add(EMPTY_LIST);
163 }
164
165 public void characters(BodyEvent be) {
166
167 setDocumentLocator(be.locator);
168
169 String body = be.getText();
170 List applicableActionList = (List) actionListStack.peek();
171
172 if (body != null) {
173 body = body.trim();
174 }
175 if (body.length() > 0) {
176
177 callBodyAction(applicableActionList, body);
178 }
179 }
180
181 public void endElement(EndEvent endEvent) {
182 setDocumentLocator(endEvent.locator);
183 endElement(endEvent.namespaceURI, endEvent.localName, endEvent.qName);
184 }
185
186 private void endElement(String namespaceURI, String localName, String qName) {
187
188
189
190 List applicableActionList = (List) actionListStack.pop();
191
192 if (skip != null) {
193 if (skip.equals(pattern)) {
194 skip = null;
195 }
196 } else if (applicableActionList != EMPTY_LIST) {
197 callEndAction(applicableActionList, getTagName(localName, qName));
198 }
199
200
201 pattern.pop();
202 }
203
204 public Locator getLocator() {
205 return locator;
206 }
207
208 public void setDocumentLocator(Locator l) {
209 locator = l;
210 }
211
212 String getTagName(String localName, String qName) {
213 String tagName = localName;
214
215 if ((tagName == null) || (tagName.length() < 1)) {
216 tagName = qName;
217 }
218
219 return tagName;
220 }
221
222 public void addImplicitAction(ImplicitAction ia) {
223 implicitActions.add(ia);
224 }
225
226
227
228
229
230
231 List lookupImplicitAction(Pattern pattern, Attributes attributes,
232 InterpretationContext ec) {
233 int len = implicitActions.size();
234
235 for (int i = 0; i < len; i++) {
236 ImplicitAction ia = (ImplicitAction) implicitActions.get(i);
237
238 if (ia.isApplicable(pattern, attributes, ec)) {
239 List<Action> actionList = new ArrayList<Action>(1);
240 actionList.add(ia);
241
242 return actionList;
243 }
244 }
245
246 return null;
247 }
248
249
250
251
252 List getApplicableActionList(Pattern pattern, Attributes attributes) {
253 List applicableActionList = ruleStore.matchActions(pattern);
254
255
256 if (applicableActionList == null) {
257 applicableActionList = lookupImplicitAction(pattern, attributes,
258 interpretationContext);
259 }
260
261 return applicableActionList;
262 }
263
264 void callBeginAction(List applicableActionList, String tagName,
265 Attributes atts) {
266 if (applicableActionList == null) {
267 return;
268 }
269
270 Iterator i = applicableActionList.iterator();
271 while (i.hasNext()) {
272 Action action = (Action) i.next();
273
274
275 try {
276 action.begin(interpretationContext, tagName, atts);
277 } catch (ActionException e) {
278 skip = (Pattern) pattern.clone();
279 cai.addError("ActionException in Action for tag [" + tagName + "]", e);
280 } catch (RuntimeException e) {
281 skip = (Pattern) pattern.clone();
282 cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
283 }
284 }
285 }
286
287 private void callBodyAction(List applicableActionList, String body) {
288 if (applicableActionList == null) {
289 return;
290 }
291 Iterator i = applicableActionList.iterator();
292
293 while (i.hasNext()) {
294 Action action = (Action) i.next();
295 try {
296 action.body(interpretationContext, body);
297 } catch (ActionException ae) {
298 cai
299 .addError("Exception in end() methd for action [" + action + "]",
300 ae);
301 }
302 }
303 }
304
305 private void callEndAction(List applicableActionList, String tagName) {
306 if (applicableActionList == null) {
307 return;
308 }
309
310
311 Iterator i = applicableActionList.iterator();
312
313 while (i.hasNext()) {
314 Action action = (Action) i.next();
315
316
317 try {
318 action.end(interpretationContext, tagName);
319 } catch (ActionException ae) {
320
321
322 cai.addError("ActionException in Action for tag [" + tagName + "]", ae);
323 } catch (RuntimeException e) {
324
325 cai.addError("RuntimeException in Action for tag [" + tagName + "]", e);
326 }
327 }
328 }
329
330 public RuleStore getRuleStore() {
331 return ruleStore;
332 }
333 }
334
335
336
337
338
339
340
341
342 class CAI_WithLocatorSupport extends ContextAwareImpl {
343
344 CAI_WithLocatorSupport(Interpreter interpreter) {
345 super(interpreter);
346 }
347
348 @Override
349 protected Object getOrigin() {
350 Interpreter i = (Interpreter) super.getOrigin();
351 Locator locator = i.locator;
352 if (locator != null) {
353 return Interpreter.class.getName() + "@" + locator.getLineNumber() + ":"
354 + locator.getColumnNumber();
355 } else {
356 return Interpreter.class.getName() + "@NA:NA";
357 }
358 }
359 }