change on logging, try find error for stracktrace handling
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / common / ImportHandlerBase.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.io.common;
11
12 import java.util.HashSet;
13 import java.util.Set;
14 import java.util.Stack;
15
16 import org.apache.log4j.Logger;
17 import org.xml.sax.Attributes;
18 import org.xml.sax.Locator;
19 import org.xml.sax.SAXException;
20 import org.xml.sax.SAXParseException;
21 import org.xml.sax.ext.DefaultHandler2;
22
23 import eu.etaxonomy.cdm.common.CdmUtils;
24 import eu.etaxonomy.cdm.io.common.events.IIoEvent;
25 import eu.etaxonomy.cdm.io.common.events.IIoObserver;
26 import eu.etaxonomy.cdm.io.common.events.IoProblemEvent;
27
28 /**
29 * Base class for XMLSax imports
30 * @author a.mueller
31 * @date 28.06.2011
32 *
33 */
34 public class ImportHandlerBase extends DefaultHandler2 {
35 private static final Logger logger = Logger.getLogger(ImportHandlerBase.class);
36
37 private Set<IIoObserver> observers = new HashSet<IIoObserver>();
38
39 protected XmlImportBase<?,?> importBase;
40 protected ImportHandlerBase previousHandler;
41 private Locator locator;
42 private boolean stateDocumentStarted = false;
43 protected Stack<String> unhandledElements = new Stack<String>();
44 protected Stack<String> handledElements = new Stack<String>();
45
46 protected ImportHandlerBase(XmlImportBase<?,?> importBase){
47 this.importBase = importBase;
48 }
49
50 protected ImportHandlerBase(ImportHandlerBase previousHandler){
51 this.previousHandler = previousHandler;
52 this.importBase = previousHandler.getImportBase();
53 this.locator = previousHandler.locator;
54 }
55
56
57 //******************** Observers *********************************************************
58
59 /* (non-Javadoc)
60 * @see eu.etaxonomy.cdm.io.common.ICdmIO#addObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
61 */
62 public void addObserver(IIoObserver observer){
63 observers.add(observer);
64 }
65
66 /* (non-Javadoc)
67 * @see eu.etaxonomy.cdm.io.common.ICdmIO#countObservers()
68 */
69 public int countObservers(){
70 return observers.size();
71 }
72
73 /* (non-Javadoc)
74 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
75 */
76 public void deleteObserver(IIoObserver observer){
77 observers.remove(observer);
78 }
79
80 /* (non-Javadoc)
81 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObservers()
82 */
83 public void deleteObservers(){
84 observers.removeAll(observers);
85 }
86
87 /* (non-Javadoc)
88 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.IIoEvent)
89 */
90 public void fire(IIoEvent event){
91 for (IIoObserver observer: observers){
92 observer.handleEvent(event);
93 }
94 }
95
96
97 //******************** End Observers *********************************************************
98
99
100 /* (non-Javadoc)
101 * @see org.xml.sax.helpers.DefaultHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
102 */
103 @Override
104 public void notationDecl(String name, String publicId, String systemId) throws SAXException {
105 logger.warn("Unexpected parse event: notationDecl");
106 }
107
108 /* (non-Javadoc)
109 * @see org.xml.sax.helpers.DefaultHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
110 */
111 @Override
112 public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
113 logger.warn("Unexpected parse event: unparsedEntityDecl");
114 }
115
116 /* (non-Javadoc)
117 * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
118 */
119 @Override
120 public void setDocumentLocator(Locator locator) {
121 if (logger.isDebugEnabled()){
122 logger.debug("Set Document Locator");
123 }
124 this.locator = locator;
125 }
126
127 /* (non-Javadoc)
128 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
129 */
130 @Override
131 public void startDocument() throws SAXException {
132 if (logger.isDebugEnabled()){
133 logger.debug("startDocument");
134 }
135 this.stateDocumentStarted = true;
136 }
137
138 /* (non-Javadoc)
139 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
140 */
141 @Override
142 public void endDocument() throws SAXException {
143 if (logger.isDebugEnabled()){
144 logger.debug("endDocument");
145 }
146 this.stateDocumentStarted = false;
147 }
148
149 /* (non-Javadoc)
150 * @see org.xml.sax.helpers.DefaultHandler#startPrefixMapping(java.lang.String, java.lang.String)
151 */
152 @Override
153 public void startPrefixMapping(String prefix, String uri) throws SAXException {
154 logger.warn("Unexpected parse event: startPrefixMapping");
155 }
156
157 /* (non-Javadoc)
158 * @see org.xml.sax.helpers.DefaultHandler#endPrefixMapping(java.lang.String)
159 */
160 @Override
161 public void endPrefixMapping(String prefix) throws SAXException {
162 logger.warn("Unexpected parse event: endPrefixMapping");
163 }
164
165 /* (non-Javadoc)
166 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
167 */
168 @Override
169 public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
170 if (logger.isDebugEnabled()){
171 logger.debug("startElement: " + qName);
172 }
173 }
174
175 /* (non-Javadoc)
176 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
177 */
178 @Override
179 public void endElement(String uri, String localName, String qName) throws SAXException {
180 logger.warn("Unexpected parse event: endElement");
181 }
182
183 /* (non-Javadoc)
184 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
185 */
186 @Override
187 public void characters(char[] ch, int start, int length) throws SAXException {
188 logger.info("Unexpected parse event: characters: " );//+ chToString(ch));
189 }
190
191 private String chToString(char[] ch) {
192 StringBuffer str = new StringBuffer(ch.length);
193 for (int i = 0; i < ch.length; i++){
194 str.append(ch[i]);
195 }
196 return str.toString();
197 }
198
199
200 /* (non-Javadoc)
201 * @see org.xml.sax.helpers.DefaultHandler#ignorableWhitespace(char[], int, int)
202 */
203 @Override
204 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
205 logger.warn("Unexpected parse event: ignorableWhitespace");
206 }
207
208 /* (non-Javadoc)
209 * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, java.lang.String)
210 */
211 @Override
212 public void processingInstruction(String target, String data) throws SAXException {
213 logger.warn("Unexpected parse event: processingInstruction");
214 }
215
216 /* (non-Javadoc)
217 * @see org.xml.sax.helpers.DefaultHandler#skippedEntity(java.lang.String)
218 */
219 @Override
220 public void skippedEntity(String name) throws SAXException {
221 logger.warn("Unexpected parse event: skippedEntity");
222 }
223
224 /* (non-Javadoc)
225 * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
226 */
227 @Override
228 public void warning(SAXParseException e) throws SAXException {
229 logger.warn("Unexpected parse event: warning");
230 }
231
232 /* (non-Javadoc)
233 * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
234 */
235 @Override
236 public void error(SAXParseException e) throws SAXException {
237 logger.warn("Unexpected parse event: error");
238 }
239
240 /* (non-Javadoc)
241 * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
242 */
243 @Override
244 public void fatalError(SAXParseException e) throws SAXException {
245 super.fatalError(e);
246 }
247
248
249
250 /* (non-Javadoc)
251 * @see org.xml.sax.ext.DefaultHandler2#startCDATA()
252 */
253 @Override
254 public void startCDATA() throws SAXException {
255 logger.warn("Unexpected parse event: startCDATA");
256 }
257
258
259 /* (non-Javadoc)
260 * @see org.xml.sax.ext.DefaultHandler2#endCDATA()
261 */
262 @Override
263 public void endCDATA() throws SAXException {
264 logger.warn("Unexpected parse event: endCDATA");
265 }
266
267
268 public void setImportBase(XmlImportBase<?,?> importBase) {
269 this.importBase = importBase;
270 }
271
272 public XmlImportBase<?,?> getImportBase() {
273 return importBase;
274 }
275
276
277 public boolean isFinished(){
278 return (handledElements.size() + unhandledElements.size()) == 0;
279 }
280
281
282
283
284 protected void handleUnexpectedAttributes(Attributes attributes) {
285 if (this.unhandledElements.size() == 0 ){
286 fireUnexpectedAttributes(attributes, 1);
287 }
288 }
289
290 protected void fireUnexpectedAttributes(Attributes attributes, int stackDepth) {
291 String attributesString = "";
292 for (int i = 0; i < attributes.getLength(); i++){
293 attributesString = CdmUtils.concat(",", attributesString, attributes.getQName(i));
294 }
295 String message = "Unexpected attributes: %s";
296 IoProblemEvent event = makeProblemEvent(String.format(message, attributesString), 1 , stackDepth +1 );
297 fire(event);
298 }
299
300
301
302 protected void fireUnexpectedStartElement(String uri, String localName, String qName, int stackDepth) {
303 String message = "Unexpected start element: %s";
304 IIoEvent event = makeProblemEvent(String.format(message, qName), 2, stackDepth +1);
305 fire(event);
306 }
307
308
309 protected void fireUnexpectedEndElement(String uri, String localName, String qName, int stackDepth) {
310 String message = "Unexpected end element: %s";
311 IIoEvent event = makeProblemEvent(String.format(message, qName), 16, stackDepth+1);
312 fire(event);
313 }
314
315
316 protected void fireNotYetImplementedElement(String uri, String localName, String qName, int stackDepth) {
317 String message = "Element not yet implement: %s";
318 IIoEvent event = makeProblemEvent(String.format(message, qName), 1, stackDepth+1 );
319 fire(event);
320 }
321
322 /**
323 * Creates a problem event.
324 * Be aware of the right depths of the stack trace !
325 * @param message
326 * @param severity
327 * @return
328 */
329 private IoProblemEvent makeProblemEvent(String message, int severity, int stackDepth) {
330 stackDepth++;
331 StackTraceElement[] stackTrace = new Exception().getStackTrace();
332 int lineNumber = stackTrace[stackDepth].getLineNumber();
333 String methodName = stackTrace[stackDepth].getMethodName();
334 String location = locator == null ? " - no locator - " : "l." + locator.getLineNumber() + "/c."+ locator.getColumnNumber();
335 String className = stackTrace[stackDepth].getClassName();
336 Class<?> declaringClass;
337 try {
338 declaringClass = Class.forName(className);
339 } catch (ClassNotFoundException e) {
340 declaringClass = this.getClass();
341 }
342
343 IoProblemEvent event = IoProblemEvent.NewInstance(declaringClass, message,
344 location, lineNumber, severity, methodName);
345 return event;
346 }
347
348
349 protected void handleUnexpectedStartElement(String uri, String localName, String qName) {
350 if (! unhandledElements.empty()){
351 unhandledElements.push(qName);
352 }else{
353 fireUnexpectedStartElement(uri, localName, qName, 1);
354 }
355
356 }
357
358 protected void handleUnexpectedEndElement(String uri, String localName, String qName) {
359 if (unhandledElements.peek().equals(qName)){
360 unhandledElements.pop();
361 }else{
362 fireUnexpectedEndElement(uri, localName, qName, 1);
363 }
364
365 }
366
367 protected void handleNotYetImplementedElement(String uri, String localName, String qName) {
368 unhandledElements.push(qName);
369 fireNotYetImplementedElement(uri, localName, qName, 1);
370 }
371
372
373
374 }