1 // $Id: ContentHandler.java 351 2008-08-14 20:20:56Z jg_hamburg $
2 /********************************************************************************
3 * DDTUnit, a Datadriven Approach to Unit- and Moduletesting
4 * Copyright (c) 2004, Joerg and Kai Gellien
5 * All rights reserved.
6 *
7 * The Software is provided under the terms of the Common Public License 1.0
8 * as provided with the distribution of DDTUnit in the file cpl-v10.html.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * + Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * + Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 *
21 * + Neither the name of the authors or DDTUnit, nor the
22 * names of its contributors may be used to endorse or promote
23 * products derived from this software without specific prior
24 * written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTOSRS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
30 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 ********************************************************************************/
38 package junitx.ddtunit.data.processing.parser;
39
40 import junitx.ddtunit.DDTException;
41 import junitx.ddtunit.data.IDataSet;
42 import junitx.ddtunit.data.processing.Engine;
43
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.xml.sax.Attributes;
47 import org.xml.sax.Locator;
48 import org.xml.sax.SAXException;
49 import org.xml.sax.SAXParseException;
50 import org.xml.sax.ext.LexicalHandler;
51 import org.xml.sax.helpers.DefaultHandler;
52
53 /**
54 * SAX content handler of ddtunit xml extension
55 *
56 * @author jg
57 */
58 class ContentHandler extends DefaultHandler implements LexicalHandler {
59 private static final String LF = System.getProperty("line.separator");
60
61 Logger log = LoggerFactory.getLogger(ContentHandler.class);
62
63 private Locator locator;
64
65 private String clusterId;
66
67 private String resourceName;
68
69 private int levelCount;
70
71 private Engine eventConsumer;
72
73 /**
74 * Instanciate sax content handler
75 *
76 * @param aParser
77 */
78 public ContentHandler(String resourceName, IDataSet clusterDataSet) {
79 super();
80 this.resourceName = resourceName;
81 this.eventConsumer = new Engine(clusterDataSet);
82 this.levelCount = 0;
83 }
84
85 /**
86 * Set Locator
87 *
88 * @param aLocator
89 */
90 public void setDocumentLocator(Locator aLocator) {
91 this.locator = aLocator;
92 }
93
94 /**
95 * SAX event startDocument ...
96 */
97 public void startDocument() {
98 log.debug("Start Document...");
99 }
100
101 /**
102 * SAX event endDocument ...
103 */
104 public void endDocument() {
105 log.debug("End Document...");
106 }
107
108 /**
109 * SAX startElement()
110 *
111 * @param namespaceURI namespace not null if provided in xml element
112 * @param localName of xml element
113 * @param qName qualified name of xml element
114 * @param attributes of xml element
115 */
116 public void startElement(String namespaceURI, String localName,
117 String qName, Attributes attributes) {
118 try {
119 this.levelCount++;
120 this.eventConsumer.processStartElement(qName, attributes,
121 this.levelCount);
122 } catch (Exception ex) {
123 StringBuffer sb = new StringBuffer(ex.getClass().getName());
124 sb.append(ex.getMessage());
125 sb.append(LF).append("Resource \'").append(this.resourceName)
126 .append("\' line/column ").append(locator.getLineNumber())
127 .append("/").append(locator.getColumnNumber());
128 DDTException ddtEx = new DDTException(sb.toString(), ex);
129 ddtEx.setStackTrace(ex.getStackTrace());
130 log.warn(sb.toString(), ddtEx);
131 throw ddtEx;
132 }
133 }
134
135 /**
136 * SAX endElement()
137 *
138 * @param namespace of xml element
139 * @param localName of xml element
140 * @param qName qualified name of xml element
141 *
142 * @throws SAXException if any parsing exception occures
143 */
144 public void endElement(String namespace, String localName, String qName)
145 throws SAXException {
146 try {
147 this.eventConsumer.processEndElement(qName, this.levelCount);
148 } catch (Exception ex) {
149 StringBuffer sb = new StringBuffer(ex.getClass().getName());
150 sb.append(ex.getMessage());
151 sb.append(LF).append("Resource \'").append(this.resourceName)
152 .append("\' line/column ").append(locator.getLineNumber())
153 .append("/").append(locator.getColumnNumber());
154 DDTException ddtEx = new DDTException(sb.toString(), ex);
155 ddtEx.setStackTrace(ex.getStackTrace());
156 log.warn(sb.toString(), ddtEx);
157 throw ddtEx;
158 } finally {
159 this.levelCount--;
160 }
161 }
162
163 /**
164 * Process simple content of xml tag values. <br/ > Ignore content outside
165 * of <code><obj></code> tags. <br/ > No splitted text content is
166 * processed correctly.
167 *
168 * @param buffer of character that contains value of xml element
169 * @param offset of xml value start
170 * @param length of xml value content
171 *
172 * @throws SAXException if any processing error occures
173 */
174 public void characters(char[] buffer, int offset, int length)
175 throws SAXException {
176 this.eventConsumer.processCharacters(buffer, offset, length);
177 }
178
179 public void ignorableWhitespace(char[] buffer, int offset, int length) {
180 System.err.println(new String(buffer, offset, length));
181 }
182
183 /**
184 * Implementation of ErrorHandler interface
185 *
186 * @param e
187 * @throws SAXException DOCUMENT ME!
188 */
189 public void error(SAXParseException e) throws SAXException {
190 log.error("Parse error detected", e);
191 throw e;
192 }
193
194 public void setClusterId(String clusterId) {
195 this.clusterId = clusterId;
196 this.eventConsumer.setClusterId(clusterId);
197 }
198
199 public String getClusterId() {
200 return clusterId;
201 }
202
203 /*
204 * (non-Javadoc)
205 *
206 * @see org.xml.sax.ext.LexicalHandler#endCDATA()
207 */
208 public void endCDATA() throws SAXException {
209 this.eventConsumer.endCDATA();
210 }
211
212 /*
213 * (non-Javadoc)
214 *
215 * @see org.xml.sax.ext.LexicalHandler#endDTD()
216 */
217 public void endDTD() throws SAXException {
218 }
219
220 /*
221 * (non-Javadoc)
222 *
223 * @see org.xml.sax.ext.LexicalHandler#startCDATA()
224 */
225 public void startCDATA() throws SAXException {
226 this.eventConsumer.startCDATA();
227 }
228
229 /*
230 * (non-Javadoc)
231 *
232 * @see org.xml.sax.ext.LexicalHandler#comment(char[], int, int)
233 */
234 public void comment(char[] ch, int start, int length) throws SAXException {
235 }
236
237 /*
238 * (non-Javadoc)
239 *
240 * @see org.xml.sax.ext.LexicalHandler#endEntity(java.lang.String)
241 */
242 public void endEntity(String name) throws SAXException {
243 }
244
245 /*
246 * (non-Javadoc)
247 *
248 * @see org.xml.sax.ext.LexicalHandler#startEntity(java.lang.String)
249 */
250 public void startEntity(String name) throws SAXException {
251 }
252
253 /*
254 * (non-Javadoc)
255 *
256 * @see org.xml.sax.ext.LexicalHandler#startDTD(java.lang.String,
257 * java.lang.String, java.lang.String)
258 */
259 public void startDTD(String name, String publicId, String systemId)
260 throws SAXException {
261 }
262 }