Project

General

Profile

Download (11.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.io.common;
10

    
11
import java.util.HashSet;
12
import java.util.Set;
13
import java.util.Stack;
14

    
15
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
16
import org.xml.sax.Attributes;
17
import org.xml.sax.Locator;
18
import org.xml.sax.SAXException;
19
import org.xml.sax.SAXParseException;
20
import org.xml.sax.ext.DefaultHandler2;
21

    
22
import eu.etaxonomy.cdm.common.CdmUtils;
23
import eu.etaxonomy.cdm.io.common.events.IIoEvent;
24
import eu.etaxonomy.cdm.io.common.events.IIoObserver;
25
import eu.etaxonomy.cdm.io.common.events.IoProblemEvent;
26

    
27
/**
28
 * Base class for XMLSax imports
29
 * @author a.mueller
30
 * @since 28.06.2011
31
 *
32
 */
33
public class ImportHandlerBase extends DefaultHandler2 {
34
	private static final Logger logger = LogManager.getLogger(ImportHandlerBase.class);
35
	
36
	private Set<IIoObserver> observers = new HashSet<IIoObserver>();
37
	
38
	protected XmlImportBase<?,?> importBase; 
39
	protected ImportHandlerBase previousHandler;
40
	private Locator locator;
41
	private boolean stateDocumentStarted = false;
42
	protected Stack<String> unhandledElements = new Stack<String>();
43
	protected Stack<String> handledElements = new Stack<String>();
44
	
45
	protected ImportHandlerBase(XmlImportBase<?,?> importBase){
46
		this.importBase = importBase;
47
	}
48
	
49
	protected ImportHandlerBase(ImportHandlerBase previousHandler){
50
		this.previousHandler = previousHandler;
51
		this.importBase = previousHandler.getImportBase();
52
		this.locator = previousHandler.locator;
53
	}
54
	
55

    
56
//******************** Observers *********************************************************	
57
	
58
	/* (non-Javadoc)
59
	 * @see eu.etaxonomy.cdm.io.common.ICdmIO#addObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
60
	 */
61
	public void addObserver(IIoObserver observer){
62
		observers.add(observer);
63
	}
64

    
65
	/* (non-Javadoc)
66
	 * @see eu.etaxonomy.cdm.io.common.ICdmIO#countObservers()
67
	 */
68
	public int countObservers(){
69
		return observers.size();
70
	}
71

    
72
    /* (non-Javadoc)
73
     * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
74
     */
75
	public void deleteObserver(IIoObserver observer){
76
		observers.remove(observer);
77
	}
78

    
79
	/* (non-Javadoc)
80
	 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObservers()
81
	 */
82
	public void deleteObservers(){
83
		observers.removeAll(observers);
84
	}
85
	
86
	/* (non-Javadoc)
87
	 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.IIoEvent)
88
	 */
89
	public void fire(IIoEvent event){
90
		for (IIoObserver observer: observers){
91
			observer.handleEvent(event);
92
		}
93
	}
94

    
95

    
96
//******************** End Observers *********************************************************	
97
	
98
	
99
	/* (non-Javadoc)
100
	 * @see org.xml.sax.helpers.DefaultHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
101
	 */
102
	@Override
103
	public void notationDecl(String name, String publicId, String systemId) throws SAXException {
104
		logger.warn("Unexpected parse event: notationDecl");
105
	}
106

    
107
	/* (non-Javadoc)
108
	 * @see org.xml.sax.helpers.DefaultHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
109
	 */
110
	@Override
111
	public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
112
		logger.warn("Unexpected parse event: unparsedEntityDecl");
113
	}
114

    
115
	/* (non-Javadoc)
116
	 * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
117
	 */
118
	@Override
119
	public void setDocumentLocator(Locator locator) {
120
		if (logger.isDebugEnabled()){
121
			logger.debug("Set Document Locator");
122
		}
123
		this.locator = locator;
124
	}
125

    
126
	/* (non-Javadoc)
127
	 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
128
	 */
129
	@Override
130
	public void startDocument() throws SAXException {
131
		if (logger.isDebugEnabled()){
132
			logger.debug("startDocument");
133
		}
134
		this.stateDocumentStarted = true;
135
	}
136

    
137
	/* (non-Javadoc)
138
	 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
139
	 */
140
	@Override
141
	public void endDocument() throws SAXException {
142
		if (logger.isDebugEnabled()){
143
			logger.debug("endDocument");
144
		}
145
		this.stateDocumentStarted = false;
146
	}
147

    
148
	/* (non-Javadoc)
149
	 * @see org.xml.sax.helpers.DefaultHandler#startPrefixMapping(java.lang.String, java.lang.String)
150
	 */
151
	@Override
152
	public void startPrefixMapping(String prefix, String uri) throws SAXException {
153
		logger.warn("Unexpected parse event: startPrefixMapping");
154
	}
155

    
156
	/* (non-Javadoc)
157
	 * @see org.xml.sax.helpers.DefaultHandler#endPrefixMapping(java.lang.String)
158
	 */
159
	@Override
160
	public void endPrefixMapping(String prefix) throws SAXException {
161
		logger.warn("Unexpected parse event: endPrefixMapping");
162
	}
163

    
164
	/* (non-Javadoc)
165
	 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
166
	 */
167
	@Override
168
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
169
		if (logger.isDebugEnabled()){
170
			logger.debug("startElement: " + qName);
171
		}
172
	}
173

    
174
	/* (non-Javadoc)
175
	 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
176
	 */
177
	@Override
178
	public void endElement(String uri, String localName, String qName) throws SAXException {
179
		logger.warn("Unexpected parse event: endElement");
180
	}
181

    
182
	/* (non-Javadoc)
183
	 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
184
	 */
185
	@Override
186
	public void characters(char[] ch, int start, int length) throws SAXException {
187
		logger.info("Unexpected parse event: characters: " );//+ chToString(ch));
188
	}
189

    
190
	private String chToString(char[] ch) {
191
		StringBuffer str = new StringBuffer(ch.length);
192
		for (int i = 0; i < ch.length; i++){
193
			str.append(ch[i]);
194
		}
195
		return str.toString();
196
	}
197

    
198

    
199
	/* (non-Javadoc)
200
	 * @see org.xml.sax.helpers.DefaultHandler#ignorableWhitespace(char[], int, int)
201
	 */
202
	@Override
203
	public void ignorableWhitespace(char[] ch, int start, int length)  throws SAXException {
204
		logger.warn("Unexpected parse event: ignorableWhitespace");
205
	}
206

    
207
	/* (non-Javadoc)
208
	 * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, java.lang.String)
209
	 */
210
	@Override
211
	public void processingInstruction(String target, String data) throws SAXException {
212
		logger.warn("Unexpected parse event: processingInstruction");
213
	}
214

    
215
	/* (non-Javadoc)
216
	 * @see org.xml.sax.helpers.DefaultHandler#skippedEntity(java.lang.String)
217
	 */
218
	@Override
219
	public void skippedEntity(String name) throws SAXException {
220
		logger.warn("Unexpected parse event: skippedEntity");
221
	}
222

    
223
	/* (non-Javadoc)
224
	 * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
225
	 */
226
	@Override
227
	public void warning(SAXParseException e) throws SAXException {
228
		logger.warn("Unexpected parse event: warning");
229
	}
230

    
231
	/* (non-Javadoc)
232
	 * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
233
	 */
234
	@Override
235
	public void error(SAXParseException e) throws SAXException {
236
		logger.warn("Unexpected parse event: error");
237
	}
238

    
239
	/* (non-Javadoc)
240
	 * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
241
	 */
242
	@Override
243
	public void fatalError(SAXParseException e) throws SAXException {
244
		super.fatalError(e);
245
	}
246
	
247

    
248

    
249
	/* (non-Javadoc)
250
	 * @see org.xml.sax.ext.DefaultHandler2#startCDATA()
251
	 */
252
	@Override
253
	public void startCDATA() throws SAXException {
254
		logger.warn("Unexpected parse event: startCDATA");
255
	}
256

    
257

    
258
	/* (non-Javadoc)
259
	 * @see org.xml.sax.ext.DefaultHandler2#endCDATA()
260
	 */
261
	@Override
262
	public void endCDATA() throws SAXException {
263
		logger.warn("Unexpected parse event: endCDATA");
264
	}
265
	
266

    
267
	public void setImportBase(XmlImportBase<?,?> importBase) {
268
		this.importBase = importBase;
269
	}
270

    
271
	public XmlImportBase<?,?> getImportBase() {
272
		return importBase;
273
	}
274
	
275
	
276
	public boolean isFinished(){
277
		return (handledElements.size() + unhandledElements.size()) == 0;
278
	}
279
	
280

    
281
	
282

    
283
	protected void handleUnexpectedAttributes(Attributes attributes) {
284
		if (this.unhandledElements.size() == 0 ){
285
			fireUnexpectedAttributes(attributes, 1);
286
		}
287
	}
288
	
289
	protected void fireUnexpectedAttributes(Attributes attributes, int stackDepth) {
290
		String attributesString = "";
291
		for (int i = 0; i < attributes.getLength(); i++){
292
			attributesString = CdmUtils.concat(",", attributesString, attributes.getQName(i));
293
		}
294
		String message = "Unexpected attributes: %s";
295
		IoProblemEvent event = makeProblemEvent(String.format(message, attributesString), 1 , stackDepth +1 );
296
		fire(event);	
297
	}
298

    
299

    
300

    
301
	protected void fireUnexpectedStartElement(String uri, String localName, String qName, int stackDepth) {
302
		String message = "Unexpected start element: %s";
303
		IIoEvent event = makeProblemEvent(String.format(message, qName), 2, stackDepth +1);
304
		fire(event);		
305
	}
306
	
307

    
308
	protected void fireUnexpectedEndElement(String uri, String localName, String qName, int stackDepth) {
309
		String message = "Unexpected end element: %s";
310
		IIoEvent event = makeProblemEvent(String.format(message, qName), 16, stackDepth+1);
311
		fire(event);		
312
	}
313
	
314

    
315
	protected void fireNotYetImplementedElement(String uri, String localName, String qName, int stackDepth) {
316
		String message = "Element not yet implement: %s";
317
		IIoEvent event = makeProblemEvent(String.format(message, qName), 1, stackDepth+1 );
318
		fire(event);		
319
	}
320

    
321
	/**
322
	 * Creates a problem event.
323
	 * Be aware of the right depths of the stack trace !
324
	 * @param message
325
	 * @param severity
326
	 * @return
327
	 */
328
	private IoProblemEvent makeProblemEvent(String message, int severity, int stackDepth) {
329
		stackDepth++;
330
		StackTraceElement[] stackTrace = new Exception().getStackTrace();
331
		int lineNumber = stackTrace[stackDepth].getLineNumber();
332
		String methodName = stackTrace[stackDepth].getMethodName();
333
		String location = locator == null ? " - no locator - " : "l." + locator.getLineNumber() + "/c."+ locator.getColumnNumber();
334
		String className = stackTrace[stackDepth].getClassName();
335
		Class<?> declaringClass;
336
		try {
337
			declaringClass = Class.forName(className);
338
		} catch (ClassNotFoundException e) {
339
			declaringClass = this.getClass();
340
		}
341
		
342
		IoProblemEvent event = IoProblemEvent.NewInstance(declaringClass, message, 
343
				location, lineNumber, severity, methodName);
344
		return event;
345
	}
346
	
347
	
348
	protected void handleUnexpectedStartElement(String uri, String localName, String qName) {
349
		if (! unhandledElements.empty()){
350
			unhandledElements.push(qName);
351
		}else{
352
			fireUnexpectedStartElement(uri, localName, qName, 1);
353
		}
354
		
355
	}
356

    
357
	protected void handleUnexpectedEndElement(String uri, String localName, String qName) {
358
		if (unhandledElements.peek().equals(qName)){
359
			unhandledElements.pop();
360
		}else{
361
			fireUnexpectedEndElement(uri, localName, qName, 1);
362
		}
363
		
364
	}
365

    
366
	protected void handleNotYetImplementedElement(String uri, String localName, String qName) {
367
		unhandledElements.push(qName);
368
		fireNotYetImplementedElement(uri, localName, qName, 1);
369
	}
370

    
371

    
372
	
373
}
(40-40/65)