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

net.sf.saxon.pull.PullToStax Maven / Gradle / Ivy

Go to download

Saxon a complete and conformant implementation of the XSLT 2.0, XQuery 1.0, and XPath 2.0 Recommendations published on 23 January 2007 by W3C

The newest version!
package net.sf.saxon.pull;

import net.sf.saxon.expr.ExpressionLocation;
import net.sf.saxon.om.AttributeCollection;
import net.sf.saxon.om.FastStringBuffer;
import net.sf.saxon.om.NamePool;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.value.Whitespace;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.SourceLocator;

/**
 * This class bridges PullProvider events to XMLStreamReader (Stax) events. That is, it acts
 * as an XMLStreamReader, fetching the underlying data from a PullProvider.
 * 

* A PullProvider may provide access to any XDM sequence, whereas an XMLStreamReader always * reads a document. The conversion of a sequence to a document follows the rules for * "normalizing" a sequence in the Serialization specification: for example, atomic values are * converted into text nodes, with adjacent atomic values being space-separated. */ public class PullToStax implements XMLStreamReader { private PullNamespaceReducer provider; private NamePool namePool; private boolean previousAtomic; private FastStringBuffer currentTextNode = new FastStringBuffer(100); private int currentStaxEvent = XMLStreamReader.START_DOCUMENT; private XPathException pendingException = null; /** * Create a PullToStax instance, which wraps a Saxon PullProvider as a Stax XMLStreamReader * @param provider the Saxon PullProvider from which the events will be read */ public PullToStax(PullProvider provider) { if (provider instanceof PullNamespaceReducer) { this.provider = (PullNamespaceReducer)provider; } else { this.provider = new PullNamespaceReducer(provider); } namePool = provider.getPipelineConfiguration().getConfiguration().getNamePool(); } public int getAttributeCount() { try { return provider.getAttributes().getLength(); } catch (XPathException e) { pendingException = e; return 0; } } public boolean isAttributeSpecified(int i) { return true; } public QName getAttributeName(int i) { try { AttributeCollection atts = provider.getAttributes(); return new QName(atts.getURI(i), atts.getLocalName(i), atts.getPrefix(i)); } catch (XPathException e) { pendingException = e; return new QName("http://saxon.sf.net/error", "error", ""); } } public String getAttributeLocalName(int i) { try { return provider.getAttributes().getLocalName(i); } catch (XPathException e) { pendingException = e; return "error"; } } public String getAttributeNamespace(int i) { try { return provider.getAttributes().getURI(i); } catch (XPathException e) { pendingException = e; return "http://saxon.sf.net/error"; } } public String getAttributePrefix(int i) { try { return provider.getAttributes().getPrefix(i); } catch (XPathException e) { pendingException = e; return ""; } } public String getAttributeType(int i) { try { AttributeCollection ac = provider.getAttributes(); if (ac.isId(i)) { return "ID"; } else if (ac.isIdref(i)) { return "IDREFS"; } else { return "CDATA"; } } catch (XPathException e) { pendingException = e; return "CDATA"; } } public String getAttributeValue(int i) { try { return provider.getAttributes().getValue(i); } catch (XPathException e) { pendingException = e; return "error"; } } public String getAttributeValue(String uri, String local) { try { return provider.getAttributes().getValue(uri, local); } catch (XPathException e) { pendingException = e; return ""; } } public int getEventType() { return currentStaxEvent; } public int getNamespaceCount() { try { return provider.getNamespaceDeclarations().getNumberOfNamespaces(); } catch (XPathException e) { pendingException = e; return 0; } } public String getText() { if (previousAtomic) { return currentTextNode.toString(); } else { try { return provider.getStringValue().toString(); } catch (XPathException e) { pendingException = e; return ""; } } } public int getTextLength() { if (previousAtomic) { return currentTextNode.length(); } else { try { return provider.getStringValue().length(); } catch (XPathException e) { pendingException = e; return 0; } } } public int getTextStart() { return 0; } public char[] getTextCharacters() { if (previousAtomic) { return currentTextNode.getCharArray(); } else { try { String stringValue = provider.getStringValue().toString(); char[] chars = new char[stringValue.length()]; stringValue.getChars(0, chars.length, chars, 0); return chars; } catch (XPathException e) { pendingException = e; return new char[0]; } } } public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (previousAtomic) { int end = sourceStart + length; if (end > currentTextNode.length()) { end = currentTextNode.length(); } currentTextNode.getChars(sourceStart, end, target, targetStart); return end - sourceStart; } else { try { String stringValue = provider.getStringValue().subSequence(sourceStart, sourceStart + length).toString(); stringValue.getChars(0, length, target, targetStart); return length; } catch (XPathException e) { pendingException = e; return 0; } } } public int next() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } int p; try { p = provider.next(); } catch (XPathException e) { throw new XMLStreamException(e); } switch (p) { case PullProvider.START_OF_INPUT: return next(); case PullProvider.ATOMIC_VALUE: currentTextNode.setLength(0); if (previousAtomic) { currentTextNode.append(' '); } currentTextNode.append(provider.getAtomicValue().getStringValue()); currentStaxEvent = XMLStreamConstants.CHARACTERS; break; case PullProvider.START_DOCUMENT: currentStaxEvent = XMLStreamConstants.START_DOCUMENT; return next(); case PullProvider.END_DOCUMENT: currentStaxEvent = XMLStreamConstants.END_DOCUMENT; break; case PullProvider.START_ELEMENT: currentStaxEvent = XMLStreamConstants.START_ELEMENT; break; case PullProvider.END_ELEMENT: currentStaxEvent = XMLStreamConstants.END_ELEMENT; break; case PullProvider.TEXT: currentStaxEvent = XMLStreamConstants.CHARACTERS; break; case PullProvider.COMMENT: currentStaxEvent = XMLStreamConstants.COMMENT; break; case PullProvider.PROCESSING_INSTRUCTION: currentStaxEvent = XMLStreamConstants.PROCESSING_INSTRUCTION; break; case PullProvider.END_OF_INPUT: currentStaxEvent = XMLStreamConstants.END_DOCUMENT; break; case PullProvider.ATTRIBUTE: throw new XMLStreamException("Free-standing attributes cannot be serialized"); case PullProvider.NAMESPACE: throw new XMLStreamException("Free-standing namespace nodes cannot be serialized"); default: throw new IllegalStateException("Unknown Stax event " + p); } previousAtomic = (p == PullProvider.ATOMIC_VALUE); return currentStaxEvent; } public int nextTag() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } int eventType = next(); while ((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace || (eventType == XMLStreamConstants.CDATA && isWhiteSpace()) // skip whitespace || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT ) { eventType = next(); } if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) { throw new XMLStreamException("expected start or end tag", getLocation()); } return eventType; } public void close() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } provider.close(); } public boolean hasName() { return currentStaxEvent == XMLStreamConstants.START_ELEMENT || currentStaxEvent == XMLStreamConstants.END_ELEMENT; } public boolean hasNext() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } return currentStaxEvent != XMLStreamConstants.END_DOCUMENT; } public boolean hasText() { return currentStaxEvent == XMLStreamConstants.CHARACTERS || currentStaxEvent == XMLStreamConstants.COMMENT; } public boolean isCharacters() { return currentStaxEvent == XMLStreamConstants.CHARACTERS; } public boolean isEndElement() { return currentStaxEvent == XMLStreamConstants.END_ELEMENT; } public boolean isStandalone() { return false; } public boolean isStartElement() { return currentStaxEvent == XMLStreamConstants.START_ELEMENT; } public boolean isWhiteSpace() { try { return currentStaxEvent == XMLStreamConstants.CHARACTERS && Whitespace.isWhite(provider.getStringValue()); } catch (XPathException e) { pendingException = e; return false; } } public boolean standaloneSet() { return false; } public String getCharacterEncodingScheme() { return null; } public String getElementText() throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (getEventType() != XMLStreamConstants.START_ELEMENT) { throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation()); } int eventType = next(); StringBuffer content = new StringBuffer(); while (eventType != XMLStreamConstants.END_ELEMENT) { if (eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE) { content.append(getText()); } else if (eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT) { // skipping } else if (eventType == XMLStreamConstants.END_DOCUMENT) { throw new XMLStreamException("unexpected end of document when reading element text content", getLocation()); } else if (eventType == XMLStreamConstants.START_ELEMENT) { throw new XMLStreamException("element text content may not contain START_ELEMENT", getLocation()); } else { throw new XMLStreamException("Unexpected event type " + eventType, getLocation()); } eventType = next(); } return content.toString(); } public String getEncoding() { return null; } public String getLocalName() { return namePool.getLocalName(provider.getNameCode()); } public String getNamespaceURI() { return namePool.getURI(provider.getNameCode()); } public String getPIData() { if (currentStaxEvent != XMLStreamConstants.PROCESSING_INSTRUCTION) { throw new IllegalStateException("Not positioned at a processing instruction"); } try { return provider.getStringValue().toString(); } catch (XPathException e) { pendingException = e; return ""; } } public String getPITarget() { if (currentStaxEvent != XMLStreamConstants.PROCESSING_INSTRUCTION) { throw new IllegalStateException("Not positioned at a processing instruction"); } return namePool.getLocalName(provider.getNameCode()); } public String getPrefix() { return namePool.getPrefix(provider.getNameCode()); } public String getVersion() { return "1.0"; } public String getNamespacePrefix(int i) { try { return provider.getNamespaceDeclarations().getPrefix(i); } catch (XPathException e) { pendingException = e; return ""; } } public String getNamespaceURI(int i) { try { return provider.getNamespaceDeclarations().getURI(i); } catch (XPathException e) { pendingException = e; return ""; } } public NamespaceContext getNamespaceContext() { return new NamespaceContextImpl(provider); } public QName getName() { int nc = provider.getNameCode(); return new QName(namePool.getURI(nc), namePool.getLocalName(nc), namePool.getPrefix(nc)); } public Location getLocation() { SourceLocator sourceLocator = provider.getSourceLocator(); if (sourceLocator == null) { sourceLocator = new ExpressionLocation(); } return new SourceStreamLocation(sourceLocator); } public Object getProperty(String s) throws IllegalArgumentException { return null; //TODO: implement this method } public void require(int event, String uri, String local) throws XMLStreamException { if (pendingException != null) { throw new XMLStreamException(pendingException); } if (currentStaxEvent != event) { throw new XMLStreamException("Required event type is " + event + ", actual event is " + currentStaxEvent); } if (uri != null && !uri.equals(getNamespaceURI())) { throw new XMLStreamException("Required namespace is " + uri + ", actual is " + getNamespaceURI()); } if (local != null && !local.equals(getLocalName())) { throw new XMLStreamException("Required local name is " + local + ", actual is " + getLocalName()); } } public String getNamespaceURI(String s) { return provider.getURIForPrefix(s, true); } /** * Bridge a SAX SourceLocator to a javax.xml.stream.Location */ public class SourceStreamLocation implements javax.xml.stream.Location { private SourceLocator locator; /** * Create a StAX SourceStreamLocation object based on a given SAX SourceLocator * @param locator the SAX SourceLocator */ public SourceStreamLocation(SourceLocator locator) { this.locator = locator; } public int getCharacterOffset() { return -1; } public int getColumnNumber() { return locator.getColumnNumber(); } public int getLineNumber() { return locator.getLineNumber(); } public String getPublicId() { return locator.getPublicId(); } public String getSystemId() { return locator.getSystemId(); } } } // // The contents of this file are subject to the Mozilla Public License Version 1.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.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" basis, // WITHOUT WARRANTY OF ANY KIND, either express or implied. // See the License for the specific language governing rights and limitations under the License. // // The Original Code is: all this file // // The Initial Developer of the Original Code is Michael H. Kay. // // Contributor(s): //





© 2015 - 2024 Weber Informatics LLC | Privacy Policy