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

org.apache.axiom.util.stax.XMLFragmentStreamReader Maven / Gradle / Ivy

The newest version!
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.apache.axiom.util.stax;

import java.util.NoSuchElementException;

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

/**
 * Wrapping XML stream reader that reads a single element from the underlying stream.
 * It will generate START_DOCUMENT and END_DOCUMENT events as required to make
 * the sequence of events appear as a complete document.
 * 

* Assume for example that the parent reader is parsing the following document: *

<a><b>text</b></a>
* If the current event is <b> when the wrapper is created, it will produce * the following sequence of events: *

*

    *
  • A synthetic START_DOCUMENT event.
  • *
  • START_ELEMENT, CHARACTERS and END_ELEMENT events for <b>text</b>. * For these events, the wrapper directly delegates to the parent reader.
  • *
  • A synthetic END_DOCUMENT event.
  • *
* After all events have been consumed from the wrapper, the current event on the parent reader * will be the event following the last END_ELEMENT of the fragment. In the example above this * will be </a>. *

* The wrapper will release the reference to the parent reader when {@link #close()} is called. * For obvious reasons, the wrapper will never call {@link XMLStreamReader#close()} on the parent * reader. */ public class XMLFragmentStreamReader implements XMLStreamReader { // The current event is a synthetic START_DOCUMENT event private static final int STATE_START_DOCUMENT = 0; // The current event is from the fragment and there will be more events from the fragment private static final int STATE_IN_FRAGMENT = 1; // The current event is the final END_ELEMENT event from the fragment private static final int STATE_FRAGMENT_END = 2; // The current event is a synthetic END_DOCUMENT event private static final int STATE_END_DOCUMENT = 3; private XMLStreamReader parent; private int state; private int depth; /** * Constructor. * * @param parent the parent reader to read the fragment from * @throws IllegalStateException if the current event on the parent is not a START_ELEMENT */ public XMLFragmentStreamReader(XMLStreamReader parent) { this.parent = parent; if (parent.getEventType() != START_ELEMENT) { throw new IllegalStateException("Expected START_ELEMENT as current event"); } } public int getEventType() { switch (state) { case STATE_START_DOCUMENT: return START_DOCUMENT; case STATE_IN_FRAGMENT: return parent.getEventType(); case STATE_FRAGMENT_END: return END_ELEMENT; case STATE_END_DOCUMENT: return END_DOCUMENT; default: // We will never get here; just make the compiler happy. throw new IllegalStateException(); } } public int next() throws XMLStreamException { switch (state) { case STATE_START_DOCUMENT: state = STATE_IN_FRAGMENT; return START_ELEMENT; case STATE_IN_FRAGMENT: int type = parent.next(); switch (type) { case START_ELEMENT: depth++; break; case END_ELEMENT: if (depth == 0) { state = STATE_FRAGMENT_END; } else { depth--; } } return type; case STATE_FRAGMENT_END: // Consume the event from the parent to put the parser in a well-defined state parent.next(); state = STATE_END_DOCUMENT; return END_DOCUMENT; default: throw new NoSuchElementException("End of document reached"); } } public int nextTag() throws XMLStreamException { switch (state) { case STATE_START_DOCUMENT: state = STATE_IN_FRAGMENT; return START_ELEMENT; case STATE_END_DOCUMENT: case STATE_FRAGMENT_END: throw new NoSuchElementException(); default: int result = parent.nextTag(); switch (result) { case START_ELEMENT: depth++; break; case END_ELEMENT: if (depth == 0) { state = STATE_FRAGMENT_END; } else { depth--; } } return result; } } public void close() throws XMLStreamException { parent = null; } public Object getProperty(String name) throws IllegalArgumentException { return parent.getProperty(name); } public String getCharacterEncodingScheme() { if (state == STATE_START_DOCUMENT) { return null; } else { throw new IllegalStateException(); } } public String getEncoding() { if (state == STATE_START_DOCUMENT) { return null; } else { throw new IllegalStateException(); } } public String getVersion() { return "1.0"; } public boolean isStandalone() { return true; } public boolean standaloneSet() { return false; } public Location getLocation() { return parent.getLocation(); } public int getAttributeCount() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeCount(); } } public String getAttributeLocalName(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeLocalName(index); } } public QName getAttributeName(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeName(index); } } public String getAttributeNamespace(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeNamespace(index); } } public String getAttributePrefix(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributePrefix(index); } } public String getAttributeType(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeType(index); } } public String getAttributeValue(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeValue(index); } } public boolean isAttributeSpecified(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.isAttributeSpecified(index); } } public String getAttributeValue(String namespaceURI, String localName) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getAttributeValue(namespaceURI, localName); } } public String getElementText() throws XMLStreamException { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getElementText(); } } public String getLocalName() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getLocalName(); } } public QName getName() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getName(); } } public String getPrefix() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getPrefix(); } } public String getNamespaceURI() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getNamespaceURI(); } } public int getNamespaceCount() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getNamespaceCount(); } } public String getNamespacePrefix(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getNamespacePrefix(index); } } public String getNamespaceURI(int index) { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getNamespaceURI(index); } } public String getNamespaceURI(String prefix) { // It is not clear whether this method is allowed in all states. // The XMLStreamReader Javadoc suggest it is, but Woodstox doesn't // allow it on states other than START_ELEMENT and END_ELEMENT. // We emulate behavior of Woodstox. if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getNamespaceURI(prefix); } } public NamespaceContext getNamespaceContext() { return parent.getNamespaceContext(); } public String getPIData() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getPIData(); } } public String getPITarget() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getPITarget(); } } public String getText() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getText(); } } public char[] getTextCharacters() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getTextCharacters(); } } public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return getTextCharacters(sourceStart, target, targetStart, length); } } public int getTextLength() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getTextLength(); } } public int getTextStart() { if (state == STATE_START_DOCUMENT || state == STATE_END_DOCUMENT) { throw new IllegalStateException(); } else { return parent.getTextStart(); } } public boolean hasName() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.hasName(); } public boolean hasNext() throws XMLStreamException { return state != STATE_END_DOCUMENT; } public boolean hasText() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.hasText(); } public boolean isCharacters() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.isCharacters(); } public boolean isStartElement() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.isStartElement(); } public boolean isEndElement() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.isEndElement(); } public boolean isWhiteSpace() { return state != STATE_START_DOCUMENT && state != STATE_END_DOCUMENT && parent.isWhiteSpace(); } public void require(int type, String namespaceURI, String localName) throws XMLStreamException { switch (state) { case STATE_START_DOCUMENT: if (type != START_DOCUMENT) { throw new XMLStreamException("Expected START_DOCUMENT"); } break; case STATE_END_DOCUMENT: if (type != END_DOCUMENT) { throw new XMLStreamException("Expected END_DOCUMENT"); } break; default: parent.require(type, namespaceURI, localName); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy