All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xwiki.xml.stax.SAXEventWriter Maven / Gradle / Ivy

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.xml.stax;

import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.Comment;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.ProcessingInstruction;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.XMLEventConsumer;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;

import javanet.staxutils.BaseXMLEventWriter;
import javanet.staxutils.DummyLocator;
import javanet.staxutils.helpers.XMLFilterImplEx;

/**
 * Receive and convert StAX events to SAX events.
 * 

* Extends {@link XMLEventConsumer} with {@link javax.xml.stream.XMLEventWriter} methods. * * @version $Id: 486e0999083ce176ee288abee14389ff8849db51 $ * @since 5.2M1 */ // SAX requires fairly complex code @SuppressWarnings("checkstyle:ClassFanOutComplexity") public class SAXEventWriter extends BaseXMLEventWriter { /** * The SAX filter. */ private XMLFilterImplEx filter; /** * The depth of XML elements. */ private int depth; /** * @param handler the content handler */ public SAXEventWriter(ContentHandler handler) { this.filter = new XMLFilterImplEx(); this.filter.setContentHandler(handler); if (handler instanceof LexicalHandler) { this.filter.setLexicalHandler((LexicalHandler) handler); } if (handler instanceof ErrorHandler) { this.filter.setErrorHandler((ErrorHandler) handler); } } @Override protected void sendEvent(XMLEvent event) throws XMLStreamException { convertEvent(event); } /** * @param event the XML event to convert * @throws XMLStreamException */ // SAX requires fairly complex code @SuppressWarnings("checkstyle:CyclomaticComplexity") private void convertEvent(XMLEvent event) throws XMLStreamException { try { if (event.isStartDocument()) { this.handleStartDocument(event); } else if (event.isEndDocument()) { this.handleEndDocument(); } else { // These are all of the events listed in the javadoc for // XMLEvent. // The spec only really describes 11 of them. switch (event.getEventType()) { case XMLStreamConstants.START_ELEMENT: this.depth++; this.handleStartElement(event.asStartElement()); break; case XMLStreamConstants.END_ELEMENT: this.handleEndElement(event.asEndElement()); this.depth--; if (this.depth == 0) { break; } break; case XMLStreamConstants.CHARACTERS: this.handleCharacters(event.asCharacters()); break; case XMLStreamConstants.PROCESSING_INSTRUCTION: this.handlePI((ProcessingInstruction) event); break; case XMLStreamConstants.COMMENT: this.handleComment((Comment) event); break; case XMLStreamConstants.CDATA: this.handleCDATA((Characters) event); break; default: break; } } } catch (SAXException e) { throw new XMLStreamException(e); } } private void handleEndDocument() throws SAXException { this.filter.endDocument(); } private void handleStartDocument(final XMLEvent event) throws SAXException { final Location location = event.getLocation(); if (location != null) { // CHECKSTYLE:AnonInnerLength(2) // SAX requires fairly complex code this.filter.setDocumentLocator(new Locator() { @Override public int getColumnNumber() { return location.getColumnNumber(); } @Override public int getLineNumber() { return location.getLineNumber(); } @Override public String getPublicId() { return location.getPublicId(); } @Override public String getSystemId() { return location.getSystemId(); } }); } else { this.filter.setDocumentLocator(new DummyLocator()); } this.filter.startDocument(); } private void handlePI(ProcessingInstruction event) throws SAXException { this.filter.processingInstruction(event.getTarget(), event.getData()); } private void handleCharacters(Characters event) throws SAXException { this.filter.characters(event.getData().toCharArray(), 0, event.getData().length()); } private void handleEndElement(EndElement event) throws XMLStreamException { QName qName = event.getName(); try { // fire endElement String prefix = qName.getPrefix(); String rawname; if (prefix == null || prefix.length() == 0) { rawname = qName.getLocalPart(); } else { rawname = prefix + ':' + qName.getLocalPart(); } this.filter.endElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname); // end namespace bindings for (@SuppressWarnings("unchecked") Iterator i = event.getNamespaces(); i.hasNext();) { String nsprefix = i.next().getPrefix(); // true for default namespace if (nsprefix == null) { nsprefix = ""; } this.filter.endPrefixMapping(nsprefix); } } catch (SAXException e) { throw new XMLStreamException(e); } } private void handleStartElement(StartElement event) throws XMLStreamException { try { // start namespace bindings for (@SuppressWarnings("unchecked") Iterator i = event.getNamespaces(); i.hasNext();) { String prefix = i.next().getPrefix(); // true for default namespace if (prefix == null) { prefix = ""; } this.filter.startPrefixMapping(prefix, event.getNamespaceURI(prefix)); } // fire startElement QName qName = event.getName(); String prefix = qName.getPrefix(); String rawname; if (prefix == null || prefix.length() == 0) { rawname = qName.getLocalPart(); } else { rawname = prefix + ':' + qName.getLocalPart(); } Attributes saxAttrs = this.getAttributes(event); this.filter.startElement(qName.getNamespaceURI(), qName.getLocalPart(), rawname, saxAttrs); } catch (SAXException e) { throw new XMLStreamException(e); } } /** * Get the attributes associated with the given START_ELEMENT StAXevent. * * @param event the StAX start element event * @return the StAX attributes converted to an org.xml.sax.Attributes */ // SAX requires fairly complex code @SuppressWarnings("checkstyle:CyclomaticComplexity") private Attributes getAttributes(StartElement event) { AttributesImpl attrs = new AttributesImpl(); if (!event.isStartElement()) { throw new InternalError("getAttributes() attempting to process: " + event); } // Add namspace declarations if required if (this.filter.getNamespacePrefixes()) { for (@SuppressWarnings("unchecked") Iterator i = event.getNamespaces(); i.hasNext();) { Namespace staxNamespace = i.next(); String uri = staxNamespace.getNamespaceURI(); if (uri == null) { uri = ""; } String prefix = staxNamespace.getPrefix(); if (prefix == null) { prefix = ""; } String qName = "xmlns"; if (prefix.length() == 0) { prefix = qName; } else { qName = qName + ':' + prefix; } attrs.addAttribute("http://www.w3.org/2000/xmlns/", prefix, qName, "CDATA", uri); } } // gather non-namespace attrs for (@SuppressWarnings("unchecked") Iterator i = event.getAttributes(); i.hasNext();) { Attribute staxAttr = i.next(); String uri = staxAttr.getName().getNamespaceURI(); if (uri == null) { uri = ""; } String localName = staxAttr.getName().getLocalPart(); String prefix = staxAttr.getName().getPrefix(); String qName; if (prefix == null || prefix.length() == 0) { qName = localName; } else { qName = prefix + ':' + localName; } String type = staxAttr.getDTDType(); String value = staxAttr.getValue(); attrs.addAttribute(uri, localName, qName, type, value); } return attrs; } private void handleComment(Comment comment) throws XMLStreamException { try { String text = comment.getText(); this.filter.comment(text.toCharArray(), 0, text.length()); } catch (SAXException e) { throw new XMLStreamException(e); } } private void handleCDATA(Characters event) throws SAXException { this.filter.startCDATA(); this.filter.characters(event.getData().toCharArray(), 0, event.getData().length()); this.filter.endCDATA(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy