3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.common
;
12 import java
.util
.HashSet
;
14 import java
.util
.Stack
;
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
;
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
;
29 * Base class for XMLSax imports
34 public class ImportHandlerBase
extends DefaultHandler2
{
35 private static final Logger logger
= Logger
.getLogger(ImportHandlerBase
.class);
37 private Set
<IIoObserver
> observers
= new HashSet
<IIoObserver
>();
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
>();
46 protected ImportHandlerBase(XmlImportBase
<?
,?
> importBase
){
47 this.importBase
= importBase
;
50 protected ImportHandlerBase(ImportHandlerBase previousHandler
){
51 this.previousHandler
= previousHandler
;
52 this.importBase
= previousHandler
.getImportBase();
53 this.locator
= previousHandler
.locator
;
57 //******************** Observers *********************************************************
60 * @see eu.etaxonomy.cdm.io.common.ICdmIO#addObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
62 public void addObserver(IIoObserver observer
){
63 observers
.add(observer
);
67 * @see eu.etaxonomy.cdm.io.common.ICdmIO#countObservers()
69 public int countObservers(){
70 return observers
.size();
74 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObserver(eu.etaxonomy.cdm.io.common.IIoObserver)
76 public void deleteObserver(IIoObserver observer
){
77 observers
.remove(observer
);
81 * @see eu.etaxonomy.cdm.io.common.ICdmIO#deleteObservers()
83 public void deleteObservers(){
84 observers
.removeAll(observers
);
88 * @see eu.etaxonomy.cdm.io.common.ICdmIO#fire(eu.etaxonomy.cdm.io.common.IIoEvent)
90 public void fire(IIoEvent event
){
91 for (IIoObserver observer
: observers
){
92 observer
.handleEvent(event
);
97 //******************** End Observers *********************************************************
101 * @see org.xml.sax.helpers.DefaultHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
104 public void notationDecl(String name
, String publicId
, String systemId
) throws SAXException
{
105 logger
.warn("Unexpected parse event: notationDecl");
109 * @see org.xml.sax.helpers.DefaultHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
112 public void unparsedEntityDecl(String name
, String publicId
, String systemId
, String notationName
) throws SAXException
{
113 logger
.warn("Unexpected parse event: unparsedEntityDecl");
117 * @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
120 public void setDocumentLocator(Locator locator
) {
121 if (logger
.isDebugEnabled()){
122 logger
.debug("Set Document Locator");
124 this.locator
= locator
;
128 * @see org.xml.sax.helpers.DefaultHandler#startDocument()
131 public void startDocument() throws SAXException
{
132 if (logger
.isDebugEnabled()){
133 logger
.debug("startDocument");
135 this.stateDocumentStarted
= true;
139 * @see org.xml.sax.helpers.DefaultHandler#endDocument()
142 public void endDocument() throws SAXException
{
143 if (logger
.isDebugEnabled()){
144 logger
.debug("endDocument");
146 this.stateDocumentStarted
= false;
150 * @see org.xml.sax.helpers.DefaultHandler#startPrefixMapping(java.lang.String, java.lang.String)
153 public void startPrefixMapping(String prefix
, String uri
) throws SAXException
{
154 logger
.warn("Unexpected parse event: startPrefixMapping");
158 * @see org.xml.sax.helpers.DefaultHandler#endPrefixMapping(java.lang.String)
161 public void endPrefixMapping(String prefix
) throws SAXException
{
162 logger
.warn("Unexpected parse event: endPrefixMapping");
166 * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
169 public void startElement(String uri
, String localName
, String qName
, Attributes attributes
) throws SAXException
{
170 if (logger
.isDebugEnabled()){
171 logger
.debug("startElement: " + qName
);
176 * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
179 public void endElement(String uri
, String localName
, String qName
) throws SAXException
{
180 logger
.warn("Unexpected parse event: endElement");
184 * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
187 public void characters(char[] ch
, int start
, int length
) throws SAXException
{
188 logger
.info("Unexpected parse event: characters: " );//+ chToString(ch));
191 private String
chToString(char[] ch
) {
192 StringBuffer str
= new StringBuffer(ch
.length
);
193 for (int i
= 0; i
< ch
.length
; i
++){
196 return str
.toString();
201 * @see org.xml.sax.helpers.DefaultHandler#ignorableWhitespace(char[], int, int)
204 public void ignorableWhitespace(char[] ch
, int start
, int length
) throws SAXException
{
205 logger
.warn("Unexpected parse event: ignorableWhitespace");
209 * @see org.xml.sax.helpers.DefaultHandler#processingInstruction(java.lang.String, java.lang.String)
212 public void processingInstruction(String target
, String data
) throws SAXException
{
213 logger
.warn("Unexpected parse event: processingInstruction");
217 * @see org.xml.sax.helpers.DefaultHandler#skippedEntity(java.lang.String)
220 public void skippedEntity(String name
) throws SAXException
{
221 logger
.warn("Unexpected parse event: skippedEntity");
225 * @see org.xml.sax.helpers.DefaultHandler#warning(org.xml.sax.SAXParseException)
228 public void warning(SAXParseException e
) throws SAXException
{
229 logger
.warn("Unexpected parse event: warning");
233 * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException)
236 public void error(SAXParseException e
) throws SAXException
{
237 logger
.warn("Unexpected parse event: error");
241 * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException)
244 public void fatalError(SAXParseException e
) throws SAXException
{
251 * @see org.xml.sax.ext.DefaultHandler2#startCDATA()
254 public void startCDATA() throws SAXException
{
255 logger
.warn("Unexpected parse event: startCDATA");
260 * @see org.xml.sax.ext.DefaultHandler2#endCDATA()
263 public void endCDATA() throws SAXException
{
264 logger
.warn("Unexpected parse event: endCDATA");
268 public void setImportBase(XmlImportBase
<?
,?
> importBase
) {
269 this.importBase
= importBase
;
272 public XmlImportBase
<?
,?
> getImportBase() {
277 public boolean isFinished(){
278 return (handledElements
.size() + unhandledElements
.size()) == 0;
284 protected void handleUnexpectedAttributes(Attributes attributes
) {
285 if (this.unhandledElements
.size() == 0 ){
286 fireUnexpectedAttributes(attributes
, 1);
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
));
295 String message
= "Unexpected attributes: %s";
296 IoProblemEvent event
= makeProblemEvent(String
.format(message
, attributesString
), 1 , stackDepth
+1 );
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);
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);
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 );
323 * Creates a problem event.
324 * Be aware of the right depths of the stack trace !
329 private IoProblemEvent
makeProblemEvent(String message
, int severity
, int 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
;
338 declaringClass
= Class
.forName(className
);
339 } catch (ClassNotFoundException e
) {
340 declaringClass
= this.getClass();
343 IoProblemEvent event
= IoProblemEvent
.NewInstance(declaringClass
, message
,
344 location
, lineNumber
, severity
, methodName
);
349 protected void handleUnexpectedStartElement(String uri
, String localName
, String qName
) {
350 if (! unhandledElements
.empty()){
351 unhandledElements
.push(qName
);
353 fireUnexpectedStartElement(uri
, localName
, qName
, 1);
358 protected void handleUnexpectedEndElement(String uri
, String localName
, String qName
) {
359 if (unhandledElements
.peek().equals(qName
)){
360 unhandledElements
.pop();
362 fireUnexpectedEndElement(uri
, localName
, qName
, 1);
367 protected void handleNotYetImplementedElement(String uri
, String localName
, String qName
) {
368 unhandledElements
.push(qName
);
369 fireNotYetImplementedElement(uri
, localName
, qName
, 1);