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  
11  package ch.qos.logback.core.joran.event;
12  
13  import java.io.IOException;
14  import java.io.InputStream;
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import javax.xml.parsers.SAXParser;
19  import javax.xml.parsers.SAXParserFactory;
20  
21  import org.xml.sax.Attributes;
22  import org.xml.sax.InputSource;
23  import org.xml.sax.Locator;
24  import org.xml.sax.SAXException;
25  import org.xml.sax.SAXParseException;
26  import org.xml.sax.helpers.DefaultHandler;
27  
28  import ch.qos.logback.core.Context;
29  import ch.qos.logback.core.joran.spi.JoranException;
30  import ch.qos.logback.core.joran.spi.Pattern;
31  import ch.qos.logback.core.spi.ContextAware;
32  import ch.qos.logback.core.spi.ContextAwareImpl;
33  import ch.qos.logback.core.status.Status;
34  
35  public class SaxEventRecorder extends DefaultHandler implements ContextAware {
36  
37    
38    final ContextAwareImpl cai;
39    
40    public SaxEventRecorder() {
41      cai =  new ContextAwareImpl(this);
42    }
43    public List<SaxEvent> saxEventList = new ArrayList<SaxEvent>();
44    Locator locator;
45    Pattern globalPattern = new Pattern();
46  
47   
48    final public void recordEvents(InputStream inputStream) throws JoranException {
49      recordEvents(new InputSource(inputStream));
50    }
51  
52    public List<SaxEvent> recordEvents(InputSource inputSource)
53        throws JoranException {
54      SAXParser saxParser = null;
55      try {
56        SAXParserFactory spf = SAXParserFactory.newInstance();
57        spf.setValidating(false);
58        spf.setNamespaceAware(true);
59        saxParser = spf.newSAXParser();
60      } catch (Exception pce) {
61        String errMsg = "Parser configuration error occured";
62        addError(errMsg, pce);
63        throw new JoranException(errMsg, pce);
64      }
65  
66      try {
67        saxParser.parse(inputSource, this);
68        return saxEventList;
69  
70      } catch (IOException ie) {
71        String errMsg = "I/O error occurred while parsing xml file";
72        addError(errMsg, ie);
73        throw new JoranException(errMsg, ie);
74      } catch (Exception ex) {
75        String errMsg = "Problem parsing XML document. See previously reported errors. Abandoning all further processing.";
76        addError(errMsg, ex);
77        throw new JoranException(errMsg, ex);
78      }
79  
80    }
81  
82    public void startDocument() {
83    }
84  
85    public Locator getLocator() {
86      return locator;
87    }
88  
89    public void setDocumentLocator(Locator l) {
90      locator = l;
91    }
92  
93    public void startElement(String namespaceURI, String localName, String qName,
94        Attributes atts) {
95  
96      String tagName = getTagName(localName, qName);
97      globalPattern.push(tagName);
98      Pattern current = (Pattern) globalPattern.clone();
99      saxEventList.add(new StartEvent(current, namespaceURI, localName, qName,
100         atts, getLocator()));
101   }
102 
103   public void characters(char[] ch, int start, int length) {
104 
105     String body = new String(ch, start, length);
106     if (body == null) {
107       return;
108     }
109 
110     // if the body string is null
111     if (body != null) {
112       String bodyTrimmed = body.trim();
113       if (bodyTrimmed.length() == 0) {
114         return;
115       }
116     }
117 
118     SaxEvent lastEvent = getLastEvent();
119     if (lastEvent instanceof BodyEvent) {
120       BodyEvent be = (BodyEvent) lastEvent;
121       be.append(body);
122     } else {
123       saxEventList.add(new BodyEvent(body, getLocator()));
124     }
125 
126   }
127 
128   SaxEvent getLastEvent() {
129     if (saxEventList.isEmpty()) {
130       return null;
131     }
132     int size = saxEventList.size();
133     return saxEventList.get(size - 1);
134   }
135 
136   public void endElement(String namespaceURI, String localName, String qName) {
137     saxEventList
138         .add(new EndEvent(namespaceURI, localName, qName, getLocator()));
139     globalPattern.pop();
140   }
141 
142   String getTagName(String localName, String qName) {
143     String tagName = localName;
144     if ((tagName == null) || (tagName.length() < 1)) {
145       tagName = qName;
146     }
147     return tagName;
148   }
149 
150   public void error(SAXParseException spe) throws SAXException {
151     addError("Parsing error on line " + spe.getLineNumber() + " and column "
152         + spe.getColumnNumber(), spe);
153   }
154 
155   public void fatalError(SAXParseException spe) throws SAXException {
156     addError("Parsing fatal error on line " + spe.getLineNumber() + " and column "
157         + spe.getColumnNumber(), spe);
158   }
159 
160   public void warning(SAXParseException spe) throws SAXException {
161     addWarn("Parsing warning on line " + spe.getLineNumber() + " and column "
162         + spe.getColumnNumber(), spe);
163   }
164 
165   public void addError(String msg) {
166     cai.addError(msg);
167   }
168 
169   public void addError(String msg, Throwable ex) {
170     cai.addError(msg, ex);
171   }
172 
173   public void addInfo(String msg) {
174     cai.addInfo(msg);
175   }
176 
177   public void addInfo(String msg, Throwable ex) {
178     cai.addInfo(msg, ex);
179   }
180 
181   public void addStatus(Status status) {
182     cai.addStatus(status);
183   }
184 
185   public void addWarn(String msg) {
186     cai.addWarn(msg);
187   }
188 
189   public void addWarn(String msg, Throwable ex) {
190     cai.addWarn(msg, ex);
191   }
192 
193   public Context getContext() {
194     return cai.getContext();
195   }
196 
197   public void setContext(Context context) {
198     cai.setContext(context);
199   }
200 
201   public List<SaxEvent> getSaxEventList() {
202     return saxEventList;
203   }
204 
205 }