org.exolab.castor.xml.util.StaxStreamHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of castor-xml Show documentation
Show all versions of castor-xml Show documentation
The core XML data binding framework with support for marshalling Java objects to
and unmarshalling from XML documents.
The newest version!
/*
* Copyright 2011 Jakub Narloch
*
* 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.exolab.castor.xml.util;
import java.util.Enumeration;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.castor.core.util.Assert;
import org.exolab.castor.xml.NamespacesStack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* A document handler that uses internally a instance of {@link XMLStreamWriter} to output the
* result xml.
*
* @author Jakub Narloch
* @version 1.3.3
* @since 1.3.3
*/
public class StaxStreamHandler extends DefaultHandler {
/**
* Represents the instance of {@link XMLStreamWriter} class, that will be used to output the
* marshalled object.
*/
private final XMLStreamWriter xmlStreamWriter;
/**
* Instance of {@link org.exolab.castor.xml.Namespaces} used for handling the namespace.
*/
private NamespacesStack namespacesStack = new NamespacesStack();
/**
* Flag indicating whether the new namespace scope is required to create.
*/
private boolean createNamespaceScope = true;
/**
* Creates new instance of {@link StaxStreamHandler} class.
*
* @param xmlStreamWriter the instance of {@link XMLStreamWriter} to use
*
* @throws IllegalArgumentException if xmlStreamWriter is null
*/
public StaxStreamHandler(XMLStreamWriter xmlStreamWriter) {
Assert.paramNotNull(xmlStreamWriter, "xmlStreamWriter");
this.xmlStreamWriter = xmlStreamWriter;
}
@Override
public void startDocument() throws SAXException {
try {
xmlStreamWriter.writeStartDocument();
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the document start.", e);
}
}
@Override
public void endDocument() throws SAXException {
try {
xmlStreamWriter.writeEndDocument();
xmlStreamWriter.flush();
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the document end.", e);
}
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
if (createNamespaceScope) {
namespacesStack.addNewNamespaceScope();
createNamespaceScope = false;
}
namespacesStack.addNamespace(prefix, uri);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
try {
// writes the element start
xmlStreamWriter.writeStartElement(qName);
// iterates through all attributes and writes them
for (int i = 0; i < attributes.getLength(); i++) {
xmlStreamWriter.writeAttribute(attributes.getQName(i), attributes.getValue(i));
}
// retrieves the default namespace
String defaultNamespace = namespacesStack.getDefaultNamespaceURI();
if (defaultNamespace != null && defaultNamespace.length() > 0) {
xmlStreamWriter.setDefaultNamespace(defaultNamespace);
}
// iterates over all namespaces declared in current scope
Enumeration enumeration = namespacesStack.getLocalNamespacePrefixes();
String prefix;
while (enumeration.hasMoreElements()) {
prefix = (String) enumeration.nextElement();
xmlStreamWriter.writeNamespace(prefix, namespacesStack.getNamespaceURI(prefix));
}
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the element start.", e);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
try {
// writes the element end
xmlStreamWriter.writeEndElement();
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the element end.", e);
}
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
try {
// writes the characters to output xml
xmlStreamWriter.writeCharacters(ch, start, length);
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the white spaces.", e);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
try {
// writes the characters to output xml
xmlStreamWriter.writeCharacters(ch, start, length);
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the characters.", e);
}
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
try {
// writes the processing instruction
xmlStreamWriter.writeProcessingInstruction(target, data);
} catch (XMLStreamException e) {
convertToSAXException("Error occurred when writing the processing instruction.", e);
}
}
/**
* Converts the passed exception into a {@link SAXException} instance with using the provided
* error message and exception cause.
*
* @param msg the error message
* @param e the inner cause of newly created exception
*
* @throws SAXException the newly created exception instance
*/
private void convertToSAXException(String msg, XMLStreamException e) throws SAXException {
throw new SAXException(msg, e);
}
}