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