/******************************************************************************* * Copyright 2010 Simon Mieth * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.kabeja.parser.xml; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.kabeja.DraftDocument; import org.kabeja.parser.ParseException; import org.kabeja.parser.Parser; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public abstract class AbstractSAXParser extends DefaultHandler implements Parser { protected DraftDocument doc; protected Map nsHandlers = new HashMap(); protected Map noNSHandlers = new HashMap(); protected XMLHandler currentHandler; protected boolean throughXMLHandler = false; protected ParsingContext context; protected boolean captureEvent = false; public void addHandler(XMLHandler xmlHandler) { Map elementHandlers = null; if (xmlHandler.getNamespaceHandle().length() == 0) { elementHandlers = noNSHandlers; } else if (this.nsHandlers.containsKey(xmlHandler.getNamespaceHandle())) { elementHandlers = (Map) this.nsHandlers.get(xmlHandler .getNamespaceHandle()); } else { elementHandlers = new HashMap(); this.nsHandlers.put(xmlHandler.getNamespaceHandle(), elementHandlers); } elementHandlers.put(xmlHandler.getElementNameHandle(), xmlHandler); } /* * (non-Javadoc) * * @see org.kabeja.parser.Parser#parse(java.io.InputStream, * java.lang.String) */ public void parse(InputStream input,DraftDocument doc, Map properties) throws ParseException { SAXParserFactory factory = SAXParserFactory.newInstance(); try { factory.setNamespaceAware(true); SAXParser parser = factory.newSAXParser(); // start parsing this.doc =doc; parser.parse(input, this); } catch (Exception e) { throw new ParseException(e); } } /* (non-Javadoc) * @see org.kabeja.parser.Parser#parse(java.io.InputStream, java.util.Map) */ public DraftDocument parse(InputStream in, Map properties) throws ParseException { parse(in, new DraftDocument(), properties); return this.doc; } /* * (non-Javadoc) * * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { if (this.throughXMLHandler) { this.currentHandler.characters(ch, start, length); } } /* * (non-Javadoc) * * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, * java.lang.String, java.lang.String) */ public void endElement(String uri, String localName, String name) throws SAXException { if (this.captureEvent) { this.currentHandler.endParseElement(uri, localName, this.context); if (this.currentHandler.getNamespaceHandle().equals(uri) && this.currentHandler.getElementNameHandle().equals(localName)) { this.captureEvent = false; this.throughXMLHandler=false; } } else if(uri == null||uri.length()==0) { if(noNSHandlers.containsKey(localName)){ this.currentHandler = (XMLHandler) noNSHandlers.get(localName); this.currentHandler.endParseElement(uri,localName, context); this.throughXMLHandler=false; } }else if (nsHandlers.containsKey(uri)) { Map handlers = (Map) nsHandlers.get(uri); if (handlers.containsKey(localName)) { this.currentHandler = (XMLHandler) handlers.get(localName); this.currentHandler.endParseElement(uri, localName, context); this.throughXMLHandler=false; } } } /* * (non-Javadoc) * * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, * java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { if (this.captureEvent) { this.fireStartParseElement(uri, localName, attributes); } else { if (uri == null || uri.length() == 0) { if (noNSHandlers.containsKey(localName)) { this.currentHandler = (XMLHandler) noNSHandlers .get(localName); fireStartParseElement(uri, localName, attributes); } } else { if (this.nsHandlers.containsKey(uri)) { Map handlers = (Map) nsHandlers.get(uri); if (handlers.containsKey(localName)) { this.currentHandler = (XMLHandler) handlers .get(localName); fireStartParseElement(uri, localName, attributes); } } } } } protected void fireStartParseElement(String namespace, String name, Attributes attributes) throws SAXException { this.throughXMLHandler=true; this.captureEvent = this.currentHandler.startParseElement(namespace, name, attributes, this.context); } public void startDocument() throws SAXException { this.context = new ParsingContext(this.doc); } }