| /** |
| * 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.xml.security.staxutils; |
| |
| import java.util.Collections; |
| import java.util.List; |
| |
| import javax.xml.stream.Location; |
| import javax.xml.stream.XMLStreamConstants; |
| import javax.xml.stream.XMLStreamException; |
| import javax.xml.stream.XMLStreamReader; |
| |
| |
| /** |
| * Abstract logic for creating XMLStreamReader from DOM documents. Its works |
| * using adapters for Element, Node and Attribute. |
| */ |
| public abstract class AbstractDOMStreamReader<T, I> implements XMLStreamReader { |
| protected int currentEvent = XMLStreamConstants.START_DOCUMENT; |
| |
| private FastStack<ElementFrame<T, I>> frames = new FastStack<>(); |
| |
| private ElementFrame<T, I> frame; |
| |
| |
| /** |
| * |
| */ |
| public static class ElementFrame<T, I> { |
| T element; |
| I currentChild; |
| |
| boolean started; |
| boolean ended; |
| |
| List<String> uris; |
| List<String> prefixes; |
| List<Object> attributes; |
| |
| final ElementFrame<T, I> parent; |
| |
| public ElementFrame(T element, ElementFrame<T, I> parent) { |
| this.element = element; |
| this.parent = parent; |
| } |
| |
| public ElementFrame(T element, ElementFrame<T, I> parent, I ch) { |
| this.element = element; |
| this.parent = parent; |
| this.currentChild = ch; |
| } |
| public ElementFrame(T doc, boolean s) { |
| this.element = doc; |
| parent = null; |
| started = s; |
| attributes = Collections.emptyList(); |
| prefixes = Collections.emptyList(); |
| uris = Collections.emptyList(); |
| } |
| public ElementFrame(T doc) { |
| this(doc, true); |
| } |
| public T getElement() { |
| return element; |
| } |
| |
| public I getCurrentChild() { |
| return currentChild; |
| } |
| public void setCurrentChild(I o) { |
| currentChild = o; |
| } |
| public boolean isDocument() { |
| return false; |
| } |
| public boolean isDocumentFragment() { |
| return false; |
| } |
| } |
| |
| /** |
| * @param frame |
| */ |
| public AbstractDOMStreamReader(ElementFrame<T, I> frame) { |
| this.frame = frame; |
| frames.push(this.frame); |
| } |
| |
| protected ElementFrame<T, I> getCurrentFrame() { |
| return frame; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#getProperty(java.lang.String) |
| */ |
| public Object getProperty(String key) throws IllegalArgumentException { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#next() |
| */ |
| public int next() throws XMLStreamException { |
| if (frame.ended) { |
| frames.pop(); |
| if (!frames.empty()) { |
| frame = frames.peek(); |
| } else { |
| currentEvent = END_DOCUMENT; |
| return currentEvent; |
| } |
| } |
| |
| if (!frame.started) { |
| frame.started = true; |
| currentEvent = frame.isDocument() ? START_DOCUMENT : START_ELEMENT; |
| } else if (hasMoreChildren()) { |
| currentEvent = nextChild(); |
| |
| if (currentEvent == START_ELEMENT) { |
| ElementFrame<T, I> newFrame = getChildFrame(); |
| newFrame.started = true; |
| frame = newFrame; |
| frames.push(this.frame); |
| currentEvent = START_ELEMENT; |
| |
| newFrame(newFrame); |
| } |
| } else { |
| frame.ended = true; |
| if (frame.isDocument()) { |
| currentEvent = END_DOCUMENT; |
| } else { |
| currentEvent = END_ELEMENT; |
| endElement(); |
| } |
| } |
| return currentEvent; |
| } |
| |
| protected void newFrame(ElementFrame<T, I> newFrame) { |
| } |
| |
| protected void endElement() { |
| } |
| |
| protected abstract boolean hasMoreChildren(); |
| protected abstract int nextChild(); |
| protected abstract ElementFrame<T, I> getChildFrame(); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#require(int, java.lang.String, |
| * java.lang.String) |
| */ |
| public void require(int arg0, String arg1, String arg2) throws XMLStreamException { |
| throw new UnsupportedOperationException(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#getElementText() |
| */ |
| public abstract String getElementText() throws XMLStreamException; |
| |
| public void consumeFrame() { |
| frame.started = true; |
| frame.ended = true; |
| if (frame.isDocument()) { |
| currentEvent = END_DOCUMENT; |
| } else { |
| currentEvent = END_ELEMENT; |
| endElement(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#nextTag() |
| */ |
| public int nextTag() throws XMLStreamException { |
| while (hasNext()) { |
| if (START_ELEMENT == next()) { |
| return START_ELEMENT; |
| } |
| } |
| |
| return currentEvent; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#hasNext() |
| */ |
| public boolean hasNext() throws XMLStreamException { |
| |
| return !(frame.ended && (frames.isEmpty() || frame.isDocumentFragment())); |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#close() |
| */ |
| public void close() throws XMLStreamException { |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#getNamespaceURI(java.lang.String) |
| */ |
| public abstract String getNamespaceURI(String prefix); |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#isStartElement() |
| */ |
| public boolean isStartElement() { |
| return currentEvent == START_ELEMENT; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#isEndElement() |
| */ |
| public boolean isEndElement() { |
| return currentEvent == END_ELEMENT; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#isCharacters() |
| */ |
| public boolean isCharacters() { |
| return currentEvent == CHARACTERS; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see javax.xml.stream.XMLStreamReader#isWhiteSpace() |
| */ |
| public boolean isWhiteSpace() { |
| if (currentEvent == CHARACTERS || currentEvent == CDATA) { |
| String text = getText(); |
| int len = text.length(); |
| for (int i = 0; i < len; ++i) { |
| if (text.charAt(i) > 0x0020) { |
| return false; |
| } |
| } |
| return true; |
| } |
| return currentEvent == SPACE; |
| } |
| |
| public int getEventType() { |
| return currentEvent; |
| } |
| |
| public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) |
| throws XMLStreamException { |
| char[] src = getText().toCharArray(); |
| |
| if (sourceStart + length >= src.length) { |
| length = src.length - sourceStart; |
| } |
| |
| for (int i = 0; i < length; i++) { |
| target[targetStart + i] = src[i + sourceStart]; |
| } |
| |
| return length; |
| } |
| |
| public boolean hasText() { |
| return currentEvent == CHARACTERS || currentEvent == DTD || currentEvent == ENTITY_REFERENCE |
| || currentEvent == COMMENT || currentEvent == SPACE; |
| } |
| |
| public String getSystemId() { |
| return null; |
| } |
| public String getPublicId() { |
| return null; |
| } |
| public Location getLocation() { |
| return new Location() { |
| |
| public int getCharacterOffset() { |
| return 0; |
| } |
| |
| public int getColumnNumber() { |
| return 0; |
| } |
| |
| public int getLineNumber() { |
| return 0; |
| } |
| |
| public String getPublicId() { |
| return AbstractDOMStreamReader.this.getPublicId(); |
| } |
| |
| public String getSystemId() { |
| return AbstractDOMStreamReader.this.getSystemId(); |
| } |
| |
| }; |
| } |
| |
| public boolean hasName() { |
| return currentEvent == START_ELEMENT || currentEvent == END_ELEMENT; |
| } |
| |
| public String getVersion() { |
| return null; |
| } |
| |
| public boolean isStandalone() { |
| return false; |
| } |
| |
| public boolean standaloneSet() { |
| return false; |
| } |
| |
| public String getCharacterEncodingScheme() { |
| return null; |
| } |
| } |