/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * 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 *******************************************************************************/ package org.ebayopensource.turmeric.runtime.binding.impl.parser.objectnode; import java.util.Iterator; 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.ebayopensource.turmeric.runtime.binding.objectnode.ObjectNode; import org.ebayopensource.turmeric.runtime.binding.utils.Stack; /** * @author wdeng */ public class ObjectNodeStreamReader implements ObjectNodeBuilder, XMLStreamReader { private static final String DEFAULT_ATTR_TYPE = "CDATA"; private Stack<Iterator<ObjectNode>> m_nodeStack; private XMLStreamReader m_reader; private int m_event; private StreamableObjectNodeImpl m_rootNode; protected StreamableObjectNodeImpl m_currentNode; private int m_rawEvent; private boolean m_allowNodeBuilding = true; private String m_encodingScheme; private String m_version; public ObjectNodeStreamReader(XMLStreamReader reader) throws XMLStreamException { m_nodeStack = new Stack<Iterator<ObjectNode>>(); m_reader = reader; m_event = START_DOCUMENT; m_encodingScheme = m_reader.getCharacterEncodingScheme(); m_version = m_reader.getVersion(); nextRawEvent(); m_rootNode = new StreamableObjectNodeImpl(this); m_currentNode = m_rootNode; } public ObjectNode getObjectNode() throws XMLStreamException { return m_rootNode; } public boolean allowNodeBuilding() { return m_allowNodeBuilding; } public void stopNodeBuilding() { m_allowNodeBuilding = false; } public void close() throws XMLStreamException { m_reader.close(); } public int getAttributeCount() { if (m_currentNode == null) { int cnt = m_reader.getAttributeCount(); return cnt; } return m_currentNode.getAttributeCount(); } public String getAttributeLocalName(int index) { if (m_currentNode == null) { String name = m_reader.getAttributeLocalName(index); return name; } return getAttributeName(index).getLocalPart(); } public QName getAttributeName(int index) { if (m_currentNode == null) { QName qName = m_reader.getAttributeName(index); return qName; } return m_currentNode.getAttribute(index).getNodeName(); } public String getAttributeNamespace(int index) { if (m_currentNode == null) { String ns = m_reader.getAttributeNamespace(index); return ns; } return getAttributeName(index).getNamespaceURI(); } public String getAttributePrefix(int index) { if (m_currentNode == null) { return m_reader.getAttributePrefix(index); } return getAttributeName(index).getPrefix(); } public String getAttributeType(int index) { if (m_currentNode == null) { String type = m_reader.getAttributeType(index); return type; } // hard coded since we are not able to get the attribute type from anywhere return DEFAULT_ATTR_TYPE; //throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".getAttributeType(int index)"); } public String getAttributeValue(int index) { if (m_currentNode == null) { String value = m_reader.getAttributeValue(index); return value; } return (String)m_currentNode.getAttribute(index).getNodeValue(); } public String getAttributeValue(String nsURI, String localName) { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".getAttributeValue(String nsURI, String localName)"); } public String getCharacterEncodingScheme() { return m_encodingScheme; } public String getElementText() throws XMLStreamException { return getText(); } public String getEncoding() { return m_reader.getEncoding(); } public int getEventType() { if (m_currentNode == null) { return m_reader.getEventType(); } return m_event; } public String getLocalName() { return getName().getLocalPart(); } public Location getLocation() { if (m_currentNode == null) { return m_reader.getLocation(); } return m_currentNode.getLocation(); } public QName getName() { if (m_currentNode == null) { QName qName = m_reader.getName(); return qName; } return m_currentNode.getNodeName(); } public NamespaceContext getNamespaceContext() { return m_reader.getNamespaceContext(); } public int getNamespaceCount() { if (m_currentNode == null) { return m_reader.getNamespaceCount(); } return m_currentNode.getNamespaceCount(); } public String getNamespacePrefix(int index) { if (m_currentNode == null) { return m_reader.getNamespacePrefix(index); } return m_currentNode.getNamespacePrefix(index); } public String getNamespaceURI() { if (null == m_currentNode) { return m_reader.getNamespaceURI(); } return m_currentNode.getNodeName().getNamespaceURI(); } public String getNamespaceURI(int index) { if (m_currentNode == null) { return m_reader.getNamespaceURI(index); } return m_currentNode.getNamespaceURI(index); } public String getNamespaceURI(String prefix) { if (m_currentNode == null) { return m_reader.getNamespaceURI(prefix); } return m_currentNode.getNamespaceURI(prefix); } public String getPIData() { return m_reader.getPIData(); } public String getPITarget() { return m_reader.getPITarget(); } public String getPrefix() { return getName().getPrefix(); } public Object getProperty(String arg0) throws IllegalArgumentException { return m_reader.getProperty(arg0); } public String getText() { if (null == m_currentNode) { return m_reader.getText(); } return m_currentNode.getNodeValue(); } public char[] getTextCharacters() { if (null == m_currentNode) { return m_reader.getTextCharacters(); } return getText().toCharArray(); } public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { char[] textChars = getTextCharacters(); System.arraycopy(textChars, sourceStart, target, targetStart, length); int availableSpace = target.length - targetStart - 1; int remainingChars = textChars.length - sourceStart - 1; return Math.min(Math.min(availableSpace, remainingChars), length); } public int getTextLength() { if (null == m_currentNode) { return m_reader.getTextLength(); } return getText().length(); } public int getTextStart() { if (null == m_currentNode) { return m_reader.getTextStart(); } return 0; } public String getVersion() { return m_version; } public boolean hasName() { return null != getName(); } public boolean hasNext() throws XMLStreamException { if (m_event == END_DOCUMENT) { return false; } if (null == m_currentNode) { return m_reader.hasNext(); } return m_event != END_DOCUMENT ? true : false; } public boolean hasText() { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".hasText()"); } public boolean isAttributeSpecified(int index) { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".isAttributeSpecified(int index)"); } public boolean isCharacters() { if (null == m_currentNode) { return m_reader.isCharacters(); } return m_event == CHARACTERS; } public boolean isEndElement() { if (null == m_currentNode) { return m_reader.isEndElement(); } return m_event == END_ELEMENT; } public boolean isStandalone() { return false; // throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".isStandalone()"); } public boolean isStartElement() { if (null == m_currentNode) { return m_reader.isStartElement(); } return m_event == START_ELEMENT; } public boolean isWhiteSpace() { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".isWhiteSpace()"); } public int next() throws XMLStreamException { if (m_event == END_DOCUMENT) { return m_event; } if (null == m_currentNode) { int event = nextRawEvent(); return event; } if (m_event == START_DOCUMENT) { // Gets the top level childrens of the tree. return startNextChildNode(END_DOCUMENT); } if (m_event == START_ELEMENT) { String value = m_currentNode.getNodeValue(); if (value != null) { m_event = CHARACTERS; return m_event; } return startNextChildNode(END_ELEMENT); } if (m_event == CHARACTERS) { return startNextChildNode(END_ELEMENT); } if (m_event == END_ELEMENT) { m_currentNode = (StreamableObjectNodeImpl)m_currentNode.getParentNode(); Iterator<ObjectNode> children = m_nodeStack.peek(); if (children.hasNext()) { StreamableObjectNodeImpl node = (StreamableObjectNodeImpl)children.next(); // LogManager.getInstance(ObjectNodeStreamReader.class).log(Level.FINE, "Event: " + m_event + " Child: " + node); m_currentNode = node; m_event = START_ELEMENT; return m_event; } if (m_currentNode.isBuilding()) { // This is the end of built object nodes. from this point // on, read from the underneath xml stream reader. m_currentNode = null; return m_rawEvent; } if (m_nodeStack.size() > 0) { m_nodeStack.pop(); m_event = END_ELEMENT; return m_event; } m_event = END_DOCUMENT; return m_event; } throw new XMLStreamException("Wrong-formatted input, " + "found unrecognized event id: " + m_event); } public int nextTag() throws XMLStreamException { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".nextTag()"); } public void require(int type, String nsURI, String localName) throws XMLStreamException { throw new UnsupportedOperationException(ObjectNodeStreamReader.class.getName() + ".require(int type, String nsURI, String localName)"); } public boolean standaloneSet() { return m_reader.standaloneSet(); } int getCurrentRawEvent() { return m_rawEvent; } int nextRawEvent() throws XMLStreamException { int currentEvent = getCurrentRawEvent(); m_rawEvent = m_reader.next(); while (SPACE == m_rawEvent || COMMENT == m_rawEvent || (END_ELEMENT == currentEvent && CHARACTERS == m_rawEvent)) { m_rawEvent = m_reader.next(); } return m_rawEvent; } Location getRawLocation() { return m_reader.getLocation(); } String getRawText() { return m_reader.getText(); } QName getRawName() { return m_reader.getName(); } int getRawNamespaceCount() { return m_reader.getNamespaceCount(); } String getRawNamespacePrefix(int index) { return m_reader.getNamespacePrefix(index); } String getRawNamespaceURI(int index) { return m_reader.getNamespaceURI(index); } int getRawAttributeCount() { return m_reader.getAttributeCount(); } QName getRawAttributeName(int index) { return m_reader.getAttributeName(index); } String getRawAttributeLocalName(int index) { return m_reader.getAttributeLocalName(index); } String getRawAttributeNamespace(int index) { String nsURI = m_reader.getAttributeNamespace(index); if (null == nsURI) { return ""; } return nsURI; } String getRawAttributePrefix(int index) { String prefix = m_reader.getAttributePrefix(index); if (null == prefix) { return ""; } return prefix; } String getRawAttributeValue(int index) { return m_reader.getAttributeValue(index); } private int startNextChildNode(int eventWhenNoMoreChild) throws XMLStreamException { StreamableObjectNodeImpl nodeImpl = m_currentNode; Iterator<ObjectNode> children = m_allowNodeBuilding ? nodeImpl.getChildrenIterator() : nodeImpl.getIteratorForBuiltChildren(); StreamableObjectNodeImpl node = null; if (children.hasNext()) { m_nodeStack.push(children); node = (StreamableObjectNodeImpl) children.next(); } // LogManager.getInstance(ObjectNodeStreamReader.class).log(Level.INFO, "Event: " + m_event + " Node: " + m_currentNode + " Child: " + node); if (null != node) { m_currentNode = node; m_event = START_ELEMENT; return m_event; } if (m_currentNode.isBuilding()) { // This is the end of built object nodes. from this point // on, read from the underneath xml stream reader. m_currentNode = null; return m_rawEvent; } m_event = eventWhenNoMoreChild; return m_event; } }