blob: 6d658607ae0065e12fddb048d4a75c47c75da8df [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
* Copyright 2006 International Business Machines Corp.
*
* 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.apache.axis2.jaxws.message.util.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
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;
import org.apache.axis2.jaxws.i18n.Messages;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
/**
* XMLStreamReader created from walking a DOM.
* This is an implementation class used by SOAPElementReader.
* @see org.apache.axis2.jaxws.util.SOAPElementReader
*/
public class XMLStreamReaderFromDOM implements XMLStreamReader {
private Node cursor;
private Stack<Node> nextCursorStack = new Stack<Node>();
private Node root;
private int event = XMLStreamReader.START_DOCUMENT;
private Node nextCursor = null;
private int nextEvent = -1;
private NamespaceContextFromDOM cacheNCI = null;
private Element cacheNCIKey = null;
private List cacheND = null;
private Element cacheNDKey = null;
/**
* Create the XMLStreamReader with an Envelope
* @param envelope Element (probably an SAAJ SOAPEnvelope) representing the Envelope
*/
public XMLStreamReaderFromDOM(Element envelope) {
root = envelope;
cursor = root;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getProperty(java.lang.String)
*/
public Object getProperty(String key) throws IllegalArgumentException {
if (key == null) {
throw new IllegalArgumentException(Messages.getMessage("XMLSRErr1"));
}
return null;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#next()
*/
public int next() throws XMLStreamException {
if (!hasNext()) {
throw new XMLStreamException(Messages.getMessage("XMLSRErr"));
}
getNext();
cursor = nextCursor;
event = nextEvent;
return event;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#require(int, java.lang.String, java.lang.String)
*/
public void require(int event, String namespace, String localPart)
throws XMLStreamException {
try {
if (event != this.event) {
throw new XMLStreamException(Messages.getMessage("XMLSRErr3", String.valueOf(event), String.valueOf(this.event)));
}
if (namespace != null &&
!namespace.equals(cursor.getNamespaceURI())) {
throw new XMLStreamException(Messages.getMessage("XMLSRErr3", namespace, this.cursor.getNamespaceURI()));
}
if (localPart != null &&
!localPart.equals(cursor.getLocalName())) {
throw new XMLStreamException(Messages.getMessage("XMLSRErr3", localPart ,this.cursor.getLocalName()));
}
} catch (XMLStreamException e) {
throw e;
} catch (Exception e) {
throw new XMLStreamException(e);
}
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getElementText()
*/
public String getElementText() throws XMLStreamException {
if (event == XMLStreamReader.START_ELEMENT) {
next();
StringBuffer buffer = new StringBuffer();
while(event != XMLStreamReader.END_ELEMENT ) {
if (event == XMLStreamReader.CHARACTERS ||
event == XMLStreamReader.CDATA ||
event == XMLStreamReader.SPACE ||
event == XMLStreamReader.ENTITY_REFERENCE) {
buffer.append(getText());
} else if (event == XMLStreamReader.PROCESSING_INSTRUCTION ||
event == XMLStreamReader.COMMENT) {
// whitespace
} else {
throw new XMLStreamException(Messages.getMessage("XMLSRErr4","getElementText()"));
}
next();
}
return buffer.toString();
}
throw new XMLStreamException(Messages.getMessage("XMLSRErr4","getElementText()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#nextTag()
*/
public int nextTag() throws XMLStreamException {
next();
while(event == XMLStreamReader.CHARACTERS && isWhiteSpace() ||
event == XMLStreamReader.CDATA && isWhiteSpace() ||
event == XMLStreamReader.SPACE ||
event == XMLStreamReader.PROCESSING_INSTRUCTION ||
event == XMLStreamReader.COMMENT) {
event = next();
}
if (event == XMLStreamReader.START_ELEMENT ||
event == XMLStreamReader.END_ELEMENT) {
return event;
}
throw new XMLStreamException(Messages.getMessage("XMLSRErr4","nextTag()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#hasNext()
*/
public boolean hasNext() throws XMLStreamException {
return (event != XMLStreamReader.END_DOCUMENT);
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#close()
*/
public void close() throws XMLStreamException {
return;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getNamespaceURI(java.lang.String)
*/
public String getNamespaceURI(String prefix) {
if (cursor instanceof Element) {
return getNamespaceContext().getNamespaceURI(prefix);
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getNamespaceURI(String)"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isStartElement()
*/
public boolean isStartElement() {
return (event == XMLStreamReader.START_ELEMENT);
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isEndElement()
*/
public boolean isEndElement() {
return (event == XMLStreamReader.END_ELEMENT);
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isCharacters()
*/
public boolean isCharacters() {
return (event == XMLStreamReader.CHARACTERS);
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isWhiteSpace()
*/
public boolean isWhiteSpace() {
if (event == XMLStreamReader.CHARACTERS ||
event == XMLStreamReader.CDATA) {
String value = ((CharacterData) cursor).getData();
StringTokenizer st = new StringTokenizer(value);
return !(st.hasMoreTokens());
}
return false;
}
/**
* @return list of attributes that are not namespace declarations
*/
private List getAttributes() {
if (event == XMLStreamReader.START_ELEMENT) {
List attrs = new ArrayList();
NamedNodeMap map = ((Element) cursor).getAttributes();
if (map != null) {
for (int i=0; i<map.getLength(); i++) {
Attr attr = (Attr) map.item(i);
if (attr.getName().equals("xmlns") ||
attr.getName().startsWith("xmlns:")) {
// this is a namespace declaration
} else {
attrs.add(attr);
}
}
}
return attrs;
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4", "getAttributes()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeValue(java.lang.String, java.lang.String)
*/
public String getAttributeValue(String namespace, String localPart) {
if (event == XMLStreamReader.START_ELEMENT) {
return ((Element)cursor).getAttributeNS(namespace, localPart);
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getAttributeValue(String, String)"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeCount()
*/
public int getAttributeCount() {
return getAttributes().size();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeName(int)
*/
public QName getAttributeName(int index) {
Attr attr = (Attr) getAttributes().get(index);
return new QName(attr.getNamespaceURI(), attr.getLocalName());
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeNamespace(int)
*/
public String getAttributeNamespace(int index) {
Attr attr = (Attr) getAttributes().get(index);
return attr.getNamespaceURI();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeLocalName(int)
*/
public String getAttributeLocalName(int index) {
Attr attr = (Attr) getAttributes().get(index);
return attr.getLocalName();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributePrefix(int)
*/
public String getAttributePrefix(int index) {
Attr attr = (Attr) getAttributes().get(index);
return attr.getPrefix();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeType(int)
*/
public String getAttributeType(int index) {
Attr attr = (Attr) getAttributes().get(index);
return attr.getSchemaTypeInfo().getTypeName();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getAttributeValue(int)
*/
public String getAttributeValue(int index) {
Attr attr = (Attr) getAttributes().get(index);
return attr.getValue();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isAttributeSpecified(int)
*/
public boolean isAttributeSpecified(int arg0) {
return true;
}
/*
* @return number of namespace declarations on this element
*/
public int getNamespaceCount() {
if (cursor instanceof Element) {
List list = getNamespaceDeclarations();
return list.size();
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getNamespaceCount()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getNamespacePrefix(int)
*/
public String getNamespacePrefix(int index) {
if (cursor instanceof Element) {
List list = getNamespaceDeclarations();
return ((NamespaceDeclare) list.get(index)).getPrefix();
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4", "getNamespacePrefix(int)"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getNamespaceURI(int)
*/
public String getNamespaceURI(int index) {
if (cursor instanceof Element) {
List list = getNamespaceDeclarations();
return ((NamespaceDeclare) list.get(index)).getURI();
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getNamespaceURI(int)"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getNamespaceContext()
*/
public NamespaceContext getNamespaceContext() {
Element element = null;
if (cursor instanceof Element) {
element = (Element) cursor;
} else {
Element parent = (Element) cursor.getParentNode();
if (parent == null) {
parent = (Element) nextCursorStack.peek();
}
element = (Element) cursor.getParentNode();
}
if (element == cacheNCIKey) {
return cacheNCI;
}
cacheNCIKey = element;
cacheNCI = new NamespaceContextFromDOM(element);
return cacheNCI;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getEventType()
*/
public int getEventType() {
return event;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getText()
*/
public String getText() {
if (event == XMLStreamReader.CHARACTERS ||
event == XMLStreamReader.CDATA ||
event == XMLStreamReader.COMMENT) {
return ((CharacterData) cursor).getData();
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getText()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getTextCharacters()
*/
public char[] getTextCharacters() {
return getText().toCharArray();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getTextCharacters(int, char[], int, int)
*/
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length)
throws XMLStreamException {
String value = getText();
// Calculate the sourceEnd index
int sourceEnd = sourceStart + length;
if (value.length() < sourceEnd) {
sourceEnd = value.length();
}
value.getChars(sourceStart, sourceEnd, target, targetStart);
return sourceEnd - sourceStart;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getTextStart()
*/
public int getTextStart() {
return 0;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getTextLength()
*/
public int getTextLength() {
return getText().length();
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getEncoding()
*/
public String getEncoding() {
return null;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#hasText()
*/
public boolean hasText() {
return (event == XMLStreamReader.CHARACTERS ||
event == XMLStreamReader.CDATA ||
event == XMLStreamReader.COMMENT);
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getLocation()
*/
public Location getLocation() {
return dummyLocation;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getName()
*/
public QName getName() {
if (cursor instanceof Element) {
return new QName(cursor.getNamespaceURI(), cursor.getLocalName());
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getName()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getLocalName()
*/
public String getLocalName() {
if (cursor instanceof Element) {
return cursor.getLocalName();
}
throw new IllegalStateException(Messages.getMessage("XMLSRErr4","getLocalName()"));
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#hasName()
*/
public boolean hasName() {
return (isStartElement() || isEndElement());
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getNamespaceURI()
*/
public String getNamespaceURI() {
if (cursor instanceof Element) {
return cursor.getNamespaceURI();
} else {
return null;
}
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getPrefix()
*/
public String getPrefix() {
if (cursor instanceof Element) {
return cursor.getPrefix();
} else {
return null;
}
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getVersion()
*/
public String getVersion() {
return null;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#isStandalone()
*/
public boolean isStandalone() {
return false;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#standaloneSet()
*/
public boolean standaloneSet() {
return false;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getCharacterEncodingScheme()
*/
public String getCharacterEncodingScheme() {
return null;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getPITarget()
*/
public String getPITarget() {
return null;
}
/* (non-Javadoc)
* @see javax.xml.stream.XMLStreamReader#getPIData()
*/
public String getPIData() {
return null;
}
/**
* Sets nextCursor and nextEvent from
* using the current cursor and event.
*/
private void getNext() throws IllegalStateException {
switch (event) {
case XMLStreamReader.START_DOCUMENT: {
nextCursor = cursor;
nextEvent = XMLStreamReader.START_ELEMENT;
break;
}
case XMLStreamReader.START_ELEMENT: {
if (cursor.getFirstChild() != null) {
nextCursorStack.push(nextCursor);
nextCursor = cursor.getFirstChild();
nextEvent = startEvent(nextCursor);
} else {
nextEvent = XMLStreamReader.END_ELEMENT;
}
break;
}
case XMLStreamReader.ATTRIBUTE: {
throw new IllegalStateException(Messages.getMessage("XMLSRErr5","ATTRIBUTE"));
}
case XMLStreamReader.NAMESPACE: {
throw new IllegalStateException(Messages.getMessage("XMLSRErr5","NAMESPACE"));
}
case XMLStreamReader.END_ELEMENT:
case XMLStreamReader.CHARACTERS:
case XMLStreamReader.CDATA:
case XMLStreamReader.COMMENT:
case XMLStreamReader.SPACE:
case XMLStreamReader.PROCESSING_INSTRUCTION:
case XMLStreamReader.ENTITY_REFERENCE:
case XMLStreamReader.DTD:
{
if (cursor.getNextSibling() != null) {
nextCursor = cursor.getNextSibling();
nextEvent = startEvent(nextCursor);
} else if (cursor == root) {
nextEvent = XMLStreamReader.END_DOCUMENT;
} else {
// The following does not work with
// Axiom Text nodes
// nextCursor = cursor.getParentNode();
// This is the reason why a stack is used.
nextCursor = nextCursorStack.pop();
nextEvent = XMLStreamReader.END_ELEMENT;
}
break;
}
case XMLStreamReader.END_DOCUMENT: {
nextCursor = null;
nextEvent = -1;
}
default:
throw new IllegalStateException(Messages.getMessage("XMLSRErr5", String.valueOf(event)));
}
}
/**
* Returns the start event for this particular node
* @param node
* @return
*/
private int startEvent(Node node) {
if (node instanceof ProcessingInstruction) {
return XMLStreamReader.PROCESSING_INSTRUCTION;
}
if (node instanceof CDATASection) {
return XMLStreamReader.CDATA;
}
if (node instanceof Comment) {
return XMLStreamReader.COMMENT;
}
if (node instanceof Text) {
if (node instanceof javax.xml.soap.Text) {
javax.xml.soap.Text soapText = (javax.xml.soap.Text) node;
if (soapText.isComment()) {
return XMLStreamReader.COMMENT;
} else {
return XMLStreamReader.CHARACTERS;
}
}
return XMLStreamReader.CHARACTERS;
}
if (node instanceof Element) {
return XMLStreamReader.START_ELEMENT;
}
if (node instanceof Attr) {
return XMLStreamReader.ATTRIBUTE;
}
if (node instanceof Document) {
return XMLStreamReader.START_DOCUMENT;
}
if (node instanceof EntityReference) {
return XMLStreamReader.ENTITY_REFERENCE;
}
if (node instanceof DocumentType) {
return XMLStreamReader.DTD;
}
return -1;
}
// This is the definition of a dummy Location
private DummyLocation dummyLocation = new DummyLocation();
private class DummyLocation implements Location {
public int getLineNumber() {
return -1;
}
public int getColumnNumber() {
return 0;
}
public int getCharacterOffset() {
return 0;
}
public String getPublicId() {
return null;
}
public String getSystemId() {
return null;
}
}
public List getNamespaceDeclarations() {
Element element = null;
if (cursor instanceof Element) {
element = (Element) cursor;
} else {
return new ArrayList();
}
if (element == cacheNDKey) {
return cacheND;
}
cacheNDKey = element;
cacheND = new ArrayList();
NamedNodeMap attrs = element.getAttributes();
if (attrs != null) {
for (int i=0; i<attrs.getLength(); i++) {
Attr attr = (Attr) attrs.item(i);
String name = attr.getNodeName();
if (name.startsWith("xmlns")) {
String prefix = "";
if (name.startsWith("xmlns:")) {
prefix = name.substring(6);
}
NamespaceDeclare nd = new NamespaceDeclare(prefix, attr.getNodeValue());
cacheND.add(nd);
}
}
}
return cacheND;
}
class NamespaceDeclare {
String prefix;
String uri;
NamespaceDeclare(String prefix, String uri) {
this.prefix = prefix;
this.uri = uri;
}
String getPrefix() {
return prefix;
}
String getURI() {
return uri;
}
}
Node getNode() {
return cursor;
}
}