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

org.kitesdk.morphline.saxon.XMLStreamCopier Maven / Gradle / Ivy

// Copied and adapted from nux-1.6
/*
 * Copyright (c) 2005, The Regents of the University of California, through
 * Lawrence Berkeley National Laboratory (subject to receipt of any required
 * approvals from the U.S. Dept. of Energy). All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * (1) Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * 
 * (2) Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * 
 * (3) Neither the name of the University of California, Lawrence Berkeley
 * National Laboratory, U.S. Dept. of Energy nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * You are under no obligation whatsoever to provide any bug fixes, patches, or
 * upgrades to the features, functionality or performance of the source code
 * ("Enhancements") to anyone; however, if you choose to make your Enhancements
 * available either publicly, or directly to Lawrence Berkeley National
 * Laboratory, without imposing a separate written license agreement for such
 * Enhancements, then you hereby grant the following license: a non-exclusive,
 * royalty-free perpetual license to install, use, modify, prepare derivative
 * works, incorporate into other computer software, distribute, and sublicense
 * such enhancements or derivative works thereof, in binary and source code
 * form.
 */
package org.kitesdk.morphline.saxon;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

/**
 * Reads all events from a given StAX {@link XMLStreamReader} parser and pipes
 * them into a given StAX {@link XMLStreamWriter} serializer.
 * 
 * @author whoschek.AT.lbl.DOT.gov
 * @author $Author: hoschek $
 * @version $Revision: 1.3 $, $Date: 2006/12/16 01:58:19 $
 */
final class XMLStreamCopier {

	private final XMLStreamReader reader;
	private final XMLStreamWriter writer;
	
	public XMLStreamCopier(XMLStreamReader reader, XMLStreamWriter writer) {
		if (reader == null)
			throw new IllegalArgumentException("reader must not be null");
		if (writer == null)
			throw new IllegalArgumentException("writer must not be null");
		
		this.reader = reader;
		this.writer = writer;
	}
	
	/**
	 * Reads all events from the reader and pipes them into the writer.
	 * 
	 * @param isFragmentMode
	 *            if true, copies all events of the XML fragment starting at the
	 *            current cursor position, if false copies all events of the
	 *            document starting at the current cursor positions.
	 * @throws XMLStreamException
	 *             If an error occurs while copying the stream
	 */
	public void copy(boolean isFragmentMode) throws XMLStreamException {
		int ev = isFragmentMode ? 
			XMLStreamConstants.START_ELEMENT : XMLStreamConstants.START_DOCUMENT;
		reader.require(ev, null, null);

		int depth = 0;
		ev = reader.getEventType();
		while (true) {
			switch (ev) {
				case XMLStreamConstants.START_ELEMENT: {
					writer.writeStartElement(
					    nonNull(reader.getPrefix()), // fixup bug where woodstox-3.2.7 returns null
							reader.getLocalName(), 
							nonNull(reader.getNamespaceURI())); // Saxon requires nonNull
					copyAttributes();
					copyNamespaces();
					depth++;
					break;
				}
				case XMLStreamConstants.END_ELEMENT: {
					writer.writeEndElement();
					depth--;
					if (isFragmentMode && depth == 0) {
						writer.flush();
						return; // we're done
					}
					break;
				}
				case XMLStreamConstants.ATTRIBUTE: {
					// can happen as part of an XPath result sequence, or similar
					copyAttribute(0);
					break;
				}
				case XMLStreamConstants.START_DOCUMENT:	{
					copyStartDocument();
					break;
				}
				case XMLStreamConstants.END_DOCUMENT: {
					writer.writeEndDocument();
					writer.flush();
					return; // we're done
				}
				case XMLStreamConstants.PROCESSING_INSTRUCTION: {
					writer.writeProcessingInstruction(
							reader.getPITarget(), reader.getPIData());
					break;
				}
				case XMLStreamConstants.COMMENT: {
					writer.writeComment(reader.getText());
					break;
				}
				case XMLStreamConstants.CDATA: {
					writer.writeCData(reader.getText());
					break;
				}
				case XMLStreamConstants.SPACE:
				case XMLStreamConstants.CHARACTERS: {
					copyText();
					break;
				}
				case XMLStreamConstants.ENTITY_REFERENCE: {
//					writer.writeEntityRef(reader.getLocalName()); // don't expand the ref
					copyText(); // expand the ref (safer)
					break;
				}
				case XMLStreamConstants.DTD: {
					copyDTD();
					break;
				}
				case XMLStreamConstants.ENTITY_DECLARATION: 
					break; // ignore (handled by XMLStreamConstants.DTD)
				case XMLStreamConstants.NOTATION_DECLARATION: 
					break; // ignore (handled by XMLStreamConstants.DTD)
				case XMLStreamConstants.NAMESPACE: {
					// can happen as part of an XPath result sequence, or similar
					writer.writeNamespace(reader.getPrefix(), reader.getNamespaceURI());
					break;
				}
				default: {
					throw new XMLStreamException("Unrecognized event type: " 
							+ reader.getEventType());
				}
			}
			
			ev = reader.next();
		}
	}
	
	private void copyAttributes() throws XMLStreamException {
		int count = reader.getAttributeCount();
		for (int i = 0; i < count; i++) {
			copyAttribute(i);
		}
	}
	
	private void copyAttribute(int i) throws XMLStreamException {
		writer.writeAttribute(
				reader.getAttributePrefix(i),
				reader.getAttributeNamespace(i),
				reader.getAttributeLocalName(i),
				reader.getAttributeValue(i));
	}
	
	private void copyNamespaces() throws XMLStreamException {
		int count = reader.getNamespaceCount();
		for (int i = 0; i < count; i++) {
			String prefix = reader.getNamespacePrefix(i);
			String namespaceURI = nonNull(reader.getNamespaceURI(i)); // Saxon requires nonNull
			writer.writeNamespace(prefix, namespaceURI);
		}
	}

//	private char[] buf = new char[2048];
	private void copyText() throws XMLStreamException {
		writer.writeCharacters(reader.getText());
		
//		int len = buf.length;
//		for (int start = 0; ; start += len) {
//			int n = reader.getTextCharacters(start, buf, 0, len);
//			writer.writeCharacters(buf, 0, n);
//			if (n < len) break;
//		}
	}
	
	private void copyStartDocument() throws XMLStreamException {
		String encoding = reader.getEncoding();
		String version = reader.getVersion();
		if (version == null) version = "1.0";
		writer.writeStartDocument(encoding, version); 
	}	

	private void copyDTD() throws XMLStreamException {
		writer.writeDTD(reader.getText());
//		Nodes nodes = DTDParser.readDocType(reader, new NodeFactory());
//		if (nodes.size() > 0) {
//			String str = nodes.get(0).toXML();
//			writer.writeDTD(str);
//		}		
	}
	
	private String nonNull(String str) {
	  return str == null ? "" : str;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy