Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Created SAX reader and writer to read/write directly from JDOM Docume…

…nts.

Signed-off-by: gburgett <gordon.burgett@gmail.com>
  • Loading branch information...
commit ac5f25a3a861d00880df2cd61b3174a87379f727 1 parent 54ed0cc
@gburgett authored
View
110 contrib/src/java/org/jdom2/contrib/helpers/JDOMNamespaceContext.java
@@ -0,0 +1,110 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom2.contrib.helpers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.namespace.NamespaceContext;
+import org.jdom2.Namespace;
+
+/**
+ * A Read-Only {@link NamespaceContext} that describes namespaces found
+ * in a JDOM node.
+ * @author gordon burgett https://github.com/gburgett
+ */
+public class JDOMNamespaceContext implements NamespaceContext {
+
+ private List<Namespace> namespaces;
+
+ public JDOMNamespaceContext(List<Namespace> namespaces){
+ this.namespaces = new ArrayList<Namespace>(namespaces);
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ for(Namespace n : namespaces){
+ if(n.getPrefix().equals(prefix)){
+ return n.getURI();
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getPrefix(String namespaceURI) {
+ for(Namespace n : namespaces){
+ if(n.getURI().equals(namespaceURI)){
+ return n.getPrefix();
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Iterator getPrefixes(String namespaceURI) {
+ List<String> ret = new ArrayList<String>();
+ for(Namespace n : namespaces){
+ if(n.getURI().equals(namespaceURI)){
+ ret.add(n.getPrefix());
+ }
+ }
+
+ return ret.iterator();
+ }
+
+}
View
468 contrib/src/java/org/jdom2/contrib/input/JDOMStreamWriter.java
@@ -0,0 +1,468 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+package org.jdom2.contrib.input;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.jdom2.Attribute;
+import org.jdom2.CDATA;
+import org.jdom2.Comment;
+import org.jdom2.Content;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.EntityRef;
+import org.jdom2.Namespace;
+import org.jdom2.ProcessingInstruction;
+import org.jdom2.Text;
+
+/**
+ * An {@link XMLStreamWriter} implementation that writes XML data to a new JDOM
+ * {@link Document}. The document can be retrieved using {@link #getDocument() }.
+ * @author gordon burgett https://github.com/gburgett
+ */
+public class JDOMStreamWriter implements XMLStreamWriter {
+
+ private Document document;
+ private Stack<Element> elementStack = new Stack<Element>();
+
+ private Element root;
+
+ private StreamWriterState state = StreamWriterState.BEFORE_DOCUMENT_START;
+
+ /**
+ * Gets the {@link Document} that was created by this writer.
+ * Only available after {@link #writeEndDocument() } has been called.
+ * @return The created {@link Document}
+ */
+ public Document getDocument(){
+ if(state == StreamWriterState.CLOSED){
+ throw new IllegalStateException("writer is closed");
+ }
+
+ if(state != StreamWriterState.DOCUMENT_ENDED){
+ throw new IllegalStateException("Cannot get document until writer has ended the document");
+ }
+
+ return document;
+ }
+
+
+ @Override
+ public void writeStartElement(String localName) throws XMLStreamException {
+ this.writeStartElement(null, localName, null);
+ }
+
+ @Override
+ public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
+ this.writeStartElement(null, localName, namespaceURI);
+ }
+
+ @Override
+ public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
+ Namespace ns = getNamespace(namespaceURI, prefix);
+
+ Element e = new Element(localName, ns);
+
+ switch(state){
+ case DOCUMENT_START:
+ this.root = e;
+ document.setRootElement(root);
+ state = StreamWriterState.IN_ROOT_ELEMENT;
+ break;
+
+ case IN_ROOT_ELEMENT:
+ this.root.addContent(e);
+ this.elementStack.push(e);
+ state = StreamWriterState.IN_ELEMENT;
+ break;
+
+ case IN_ELEMENT:
+ Element parent = this.elementStack.peek();
+ parent.addContent(e);
+ this.elementStack.push(e);
+ //still in element
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write new element when in state " + state);
+ }
+ }
+
+ @Override
+ public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
+ this.writeEmptyElement(null, localName, null);
+ }
+
+ @Override
+ public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
+ Namespace ns = getNamespace(namespaceURI, prefix);
+
+ Element e = new Element(localName, ns);
+
+ switch(state){
+ case DOCUMENT_START:
+ //an empty root element
+ this.root = e;
+ document.setRootElement(root);
+ state = StreamWriterState.END_ROOT_ELEMENT;
+ break;
+
+ case IN_ROOT_ELEMENT:
+ this.root.addContent(e);
+ //still in root element
+ break;
+
+ case IN_ELEMENT:
+ Element pop = this.elementStack.peek();
+ if(pop == null){
+ pop = this.root;
+ }
+ pop.addContent(e);
+ //still in element
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write new element when in state " + state);
+ }
+ }
+
+ @Override
+ public void writeEmptyElement(String localName) throws XMLStreamException {
+ this.writeEmptyElement(null, localName, null);
+ }
+
+ @Override
+ public void writeEndElement() throws XMLStreamException {
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ //done with root element
+ state = StreamWriterState.END_ROOT_ELEMENT;
+ break;
+
+ case IN_ELEMENT:
+ this.elementStack.pop();
+ if(this.elementStack.isEmpty()){
+ //back to root element
+ state = StreamWriterState.IN_ROOT_ELEMENT;
+ }
+ //else still in element
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write end element when in state " + state);
+ }
+ }
+
+ @Override
+ public void writeEndDocument() throws XMLStreamException {
+ if(state != StreamWriterState.END_ROOT_ELEMENT){
+ throw new IllegalStateException("Cannot write end document before writing end of root element");
+ }
+
+ state = StreamWriterState.DOCUMENT_ENDED;
+ }
+
+ @Override
+ public void close() throws XMLStreamException {
+ this.document = null;
+ this.root = null;
+ this.elementStack = null;
+ this.state = StreamWriterState.CLOSED;
+ }
+
+ @Override
+ public void flush() throws XMLStreamException {
+ }
+
+ @Override
+ public void writeAttribute(String localName, String value) throws XMLStreamException {
+ this.writeAttribute(null, null, localName, value);
+ }
+
+ @Override
+ public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
+ Attribute a = new Attribute(localName, value, getNamespace(namespaceURI, prefix));
+
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ this.root.setAttribute(a);
+ break;
+
+ case IN_ELEMENT:
+ this.elementStack.peek().setAttribute(a);
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write attribute when in state " + state);
+ }
+ }
+
+ @Override
+ public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
+ this.writeAttribute(null, namespaceURI, localName, value);
+ }
+
+ @Override
+ public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
+ Namespace ns = this.getNamespace(namespaceURI, prefix);
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ this.root.addNamespaceDeclaration(ns);
+ break;
+
+ case IN_ELEMENT:
+ this.elementStack.peek().addNamespaceDeclaration(ns);
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write namespace when in state " + state);
+ }
+ }
+
+ @Override
+ public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
+ this.writeNamespace(null, namespaceURI);
+ }
+
+ @Override
+ public void writeComment(String data) throws XMLStreamException {
+ Comment c = new Comment(data);
+ this.addContent(c);
+ }
+
+ @Override
+ public void writeProcessingInstruction(String target) throws XMLStreamException {
+ this.writeProcessingInstruction(target, null);
+ }
+
+ @Override
+ public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
+ ProcessingInstruction pi = new ProcessingInstruction(target, data);
+ this.addContent(pi);
+ }
+
+ @Override
+ public void writeCData(String data) throws XMLStreamException {
+ this.addContent(new CDATA(data));
+ }
+
+ @Override
+ public void writeDTD(String dtd) throws XMLStreamException {
+ throw new UnsupportedOperationException("not supported yet");
+ }
+
+ @Override
+ public void writeEntityRef(String name) throws XMLStreamException {
+ EntityRef e = new EntityRef(name);
+ this.addContent(e);
+ }
+
+ @Override
+ public void writeStartDocument() throws XMLStreamException {
+ this.writeStartDocument(null);
+ }
+
+ @Override
+ public void writeStartDocument(String version) throws XMLStreamException {
+ this.writeStartDocument(null, version);
+ }
+
+ @Override
+ public void writeStartDocument(String encoding, String version) throws XMLStreamException {
+ if(this.state != StreamWriterState.BEFORE_DOCUMENT_START){
+ throw new IllegalStateException("Cannot write start document while in state " + this.state);
+ }
+
+ this.document = new Document();
+ if(encoding != null && !"".equals(encoding))
+ this.document.setProperty("ENCODING", encoding);
+ //TODO: how to set version?
+
+ this.state = StreamWriterState.DOCUMENT_START;
+ }
+
+ @Override
+ public void writeCharacters(String text) throws XMLStreamException {
+ this.addContent(new Text(text));
+ }
+
+ @Override
+ public void writeCharacters(char[] text, int start, int len) throws XMLStreamException {
+ String s = new String(text, start, len);
+ this.addContent(new Text(s));
+ }
+
+ @Override
+ public String getPrefix(String uri) throws XMLStreamException {
+ for(Namespace n : getCurrentNamespaces()){
+ if(uri == null){
+ if(n.getURI() == null){
+ return n.getPrefix();
+ }
+ }
+ else{
+ if(uri.equals(n.getURI())){
+ return n.getPrefix();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void setPrefix(String prefix, String uri) throws XMLStreamException {
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ this.root.addNamespaceDeclaration(Namespace.getNamespace(prefix, uri));
+
+ case IN_ELEMENT:
+ this.elementStack.peek().addNamespaceDeclaration(Namespace.getNamespace(prefix, uri));
+
+ default:
+ throw new IllegalStateException("Attempt to set prefix outside the context of an element");
+ }
+ }
+
+ @Override
+ public void setDefaultNamespace(String uri) throws XMLStreamException {
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ this.root.addNamespaceDeclaration(Namespace.getNamespace(uri));
+
+ case IN_ELEMENT:
+ this.elementStack.peek().addNamespaceDeclaration(Namespace.getNamespace(uri));
+
+ default:
+ throw new IllegalStateException("Attempt to set default namespace outside the context of an element");
+ }
+ }
+
+ @Override
+ public void setNamespaceContext(NamespaceContext context) throws XMLStreamException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public NamespaceContext getNamespaceContext() {
+ final List<Namespace> namespaces = getCurrentNamespaces();
+
+ return new org.jdom2.contrib.helpers.JDOMNamespaceContext(namespaces);
+ }
+
+ private List<Namespace> getCurrentNamespaces() {
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ return root.getNamespacesInScope();
+
+ case IN_ELEMENT:
+ return elementStack.peek().getNamespacesInScope();
+
+ case DOCUMENT_START:
+ case END_ROOT_ELEMENT:
+ return document.getNamespacesInScope();
+
+ default:
+ throw new IllegalStateException("Attempt to get namespaces in unsupported state " + this.state);
+ }
+ }
+
+ @Override
+ public Object getProperty(String name) throws IllegalArgumentException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ private Namespace getNamespace(String namespaceURI, String prefix) {
+ Namespace ns = null;
+ if(namespaceURI != null){
+ if(prefix == null || "".equals(prefix) || "xmlns".equalsIgnoreCase(prefix)){
+ ns = Namespace.getNamespace(namespaceURI);
+ }
+ else{
+ ns = Namespace.getNamespace(prefix, namespaceURI);
+ }
+ }
+ return ns;
+ }
+
+ private void addContent(Content c){
+ switch(state){
+ case IN_ROOT_ELEMENT:
+ this.root.addContent(c);
+ break;
+
+ case IN_ELEMENT:
+ this.elementStack.peek().addContent(c);
+ break;
+
+ default:
+ throw new IllegalStateException("Cannot write end element when in state " + state);
+ }
+ }
+
+ private enum StreamWriterState{
+ BEFORE_DOCUMENT_START,
+ DOCUMENT_START,
+ IN_ROOT_ELEMENT,
+ IN_ELEMENT,
+ END_ROOT_ELEMENT,
+ DOCUMENT_ENDED,
+ CLOSED
+ }
+}
View
789 contrib/src/java/org/jdom2/contrib/output/JDOMStreamReader.java
@@ -0,0 +1,789 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+
+package org.jdom2.contrib.output;
+
+import java.util.Iterator;
+import javax.xml.XMLConstants;
+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 org.jdom2.Attribute;
+import org.jdom2.Content;
+import org.jdom2.DocType;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.EntityRef;
+import org.jdom2.Namespace;
+import org.jdom2.ProcessingInstruction;
+import org.jdom2.Text;
+
+/**
+ * An {@link XMLStreamReader} implementation that reads the XML document
+ * out of a JDOM {@link Document}.
+ *
+ * The reader reads XML Events by walking the DOM tree, reporting all XML stream
+ * events as it encounters them in the DOM.
+ * @author gordon burgett https://github.com/gburgett
+ */
+public class JDOMStreamReader implements XMLStreamReader {
+
+ private Document document;
+ private Element root;
+ private DomWalkingContentIterator rootIterator;
+ private ReaderState state = ReaderState.START_DOCUMENT;
+
+ private int currentEvt = START_DOCUMENT;
+
+ private Content getCurrentContent(){
+ Content ret = rootIterator.getCurrentContent();
+ if(ret == null){
+ return root;
+ }
+ return ret;
+ }
+
+ public JDOMStreamReader(Document document){
+ this.document = document;
+ this.root = document.getRootElement();
+ }
+
+ @Override
+ public Object getProperty(String name) throws IllegalArgumentException {
+ return null;
+ }
+
+ @Override
+ public int next() throws XMLStreamException {
+ switch(state){
+ case START_DOCUMENT:
+ state = ReaderState.START_ROOT_ELEMENT;
+ return currentEvt = START_DOCUMENT;
+
+ case START_ROOT_ELEMENT:
+ state = ReaderState.WALKING_TREE;
+ this.rootIterator = new DomWalkingContentIterator(root);
+ return currentEvt = START_ELEMENT;
+
+ case WALKING_TREE:
+ if(this.rootIterator.hasNext()){
+ return currentEvt = this.rootIterator.next();
+ }
+ else{
+ state = ReaderState.END_ROOT_ELEMENT;
+ return currentEvt = END_ELEMENT;
+ }
+
+ case END_ROOT_ELEMENT:
+ state = ReaderState.END_DOCUMENT;
+ return currentEvt = END_DOCUMENT;
+
+ default:
+ throw new IllegalStateException("Reader does not have next");
+ }
+ }
+
+ @Override
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ if(type != currentEvt){
+ throw new XMLStreamException("required event " + type + " but got event " + currentEvt);
+ }
+
+ if(localName != null){
+ if(!localName.equals(getLocalName())){
+ throw new XMLStreamException("required name " + localName + " but got name " + getLocalName());
+ }
+ }
+
+ if(namespaceURI != null){
+ if(!namespaceURI.equals(getNamespaceURI())){
+ throw new XMLStreamException("required namespace " + namespaceURI + " but got namespace " + getNamespaceURI());
+ }
+ }
+ }
+
+ @Override
+ public String getElementText() throws XMLStreamException {
+ if(getEventType() != XMLStreamConstants.START_ELEMENT) {
+ throw new XMLStreamException("parser must be on START_ELEMENT to read next text", getLocation());
+ }
+
+ int eventType = next();
+ StringBuffer buf = new StringBuffer();
+ while(eventType != XMLStreamConstants.END_ELEMENT ) {
+ if(eventType == XMLStreamConstants.CHARACTERS
+ || eventType == XMLStreamConstants.CDATA
+ || eventType == XMLStreamConstants.SPACE
+ || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
+ buf.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 buf.toString();
+ }
+
+ @Override
+ public int nextTag() throws XMLStreamException {
+ 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;
+ }
+
+ @Override
+ public boolean hasNext() throws XMLStreamException {
+ return !(state == ReaderState.END_DOCUMENT ||
+ state == ReaderState.CLOSED);
+ }
+
+ @Override
+ public void close() throws XMLStreamException {
+ this.state = ReaderState.CLOSED;
+ this.document = null;
+ this.root = null;
+ this.rootIterator = null;
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ if("xml".equalsIgnoreCase(prefix)){
+ return Namespace.XML_NAMESPACE.getURI();
+ }
+ if("xmlns".equalsIgnoreCase(prefix)){
+ return "http://www.w3.org/2000/xmlns/";
+ }
+
+ Content c = getCurrentContent();
+ for(Namespace ns : c.getNamespacesInScope()){
+ if(ns.getPrefix().equals(prefix)){
+ return ns.getURI();
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean isStartElement() {
+ return currentEvt == START_ELEMENT;
+ }
+
+ @Override
+ public boolean isEndElement() {
+ return currentEvt == END_ELEMENT;
+ }
+
+ @Override
+ public boolean isCharacters() {
+ return currentEvt == CHARACTERS;
+ }
+
+ @Override
+ public boolean isWhiteSpace() {
+ return currentEvt == SPACE;
+ }
+
+ @Override
+ public String getAttributeValue(String namespaceURI, String localName) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+
+ if(namespaceURI != null){
+ return e.getAttributeValue(localName, Namespace.getNamespace(namespaceURI));
+ }
+
+ //else search by local name only
+ for(Attribute a : e.getAttributes()){
+ if(a.getName().equalsIgnoreCase(localName)){
+ return a.getValue();
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public int getAttributeCount() {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ return e.getAttributes().size();
+ }
+
+ @Override
+ public QName getAttributeName(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+
+ String ns = a.getNamespaceURI();
+ if("".equals(ns))
+ ns = null;
+ String prefix = a.getNamespacePrefix();
+ if(prefix == null || "".equals(prefix)){
+ prefix = XMLConstants.DEFAULT_NS_PREFIX;
+ }
+
+ return new QName(ns, a.getName(), prefix);
+ }
+
+ @Override
+ public String getAttributeNamespace(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+ String ret = a.getNamespaceURI();
+ if("".equals(ret)){
+ return null;
+ }
+ return ret;
+ }
+
+ @Override
+ public String getAttributeLocalName(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+ return a.getName();
+ }
+
+ @Override
+ public String getAttributePrefix(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+ String ret = a.getNamespacePrefix();
+ if(ret == null || "".equals(ret)){
+ return XMLConstants.DEFAULT_NS_PREFIX;
+ }
+ return ret;
+ }
+
+ @Override
+ public String getAttributeType(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+
+ return a.getAttributeType().name();
+ }
+
+ @Override
+ public String getAttributeValue(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+ return a.getValue();
+ }
+
+ @Override
+ public boolean isAttributeSpecified(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ Attribute a = e.getAttributes().get(index);
+
+ return a.isSpecified();
+ }
+
+ @Override
+ public int getNamespaceCount() {
+ switch(currentEvt){
+ case START_ELEMENT:
+ case NAMESPACE:
+ case END_ELEMENT:
+ Element e = (Element)getCurrentContent();
+ return e.getNamespacesIntroduced().size();
+ }
+
+ throw new IllegalStateException("getNamespaceCount not supported for event " + currentEvt);
+ }
+
+ @Override
+ public String getNamespacePrefix(int index) {
+ switch(currentEvt){
+ case START_ELEMENT:
+ case NAMESPACE:
+ case END_ELEMENT:
+ Element e = (Element)getCurrentContent();
+ Namespace ns = e.getNamespacesIntroduced().get(index);
+ String ret = ns.getPrefix();
+ if(ret == null || "".equals(ret)){
+ ret = XMLConstants.DEFAULT_NS_PREFIX;
+ }
+ return ret;
+ }
+
+ throw new IllegalStateException("getNamespacePrefix not supported for event " + currentEvt);
+ }
+
+ @Override
+ public String getNamespaceURI(int index) {
+
+ switch(currentEvt){
+ case START_ELEMENT:
+ case NAMESPACE:
+ case END_ELEMENT:
+ Element e = (Element)getCurrentContent();
+ Namespace ns = e.getNamespacesIntroduced().get(index);
+ String ret = ns.getURI();
+ if("".equals(ret)){
+ ret = null;
+ }
+ return ret;
+ }
+
+ throw new IllegalStateException("getNamespaceURI not supported for event " + currentEvt);
+ }
+
+ @Override
+ public NamespaceContext getNamespaceContext() {
+ if(state == ReaderState.START_DOCUMENT || state == ReaderState.END_DOCUMENT || state == ReaderState.CLOSED){
+ throw new IllegalStateException("getNamespaceCount not supported for event " + currentEvt);
+ }
+
+ Content c = getCurrentContent();
+ return new org.jdom2.contrib.helpers.JDOMNamespaceContext(c.getNamespacesInScope());
+ }
+
+ @Override
+ public int getEventType() {
+ return currentEvt;
+ }
+
+ @Override
+ public String getText() {
+ Content c = getCurrentContent();
+ switch(c.getCType()){
+ case CDATA:
+ case Text:
+ case Comment:
+ return c.getValue();
+
+ case DocType:
+ return ((DocType)c).getInternalSubset();
+ }
+
+ throw new IllegalStateException("getText not valid for event type " + currentEvt);
+ }
+
+ @Override
+ public char[] getTextCharacters() {
+ return getText().toCharArray();
+ }
+
+ @Override
+ public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
+ char[] chars = getText().toCharArray();
+ int i = 0;
+ for(; i < length; i++){
+ if(sourceStart > chars.length){
+ return i;
+ }
+ if(targetStart > target.length){
+ return i;
+ }
+
+ target[targetStart++] = chars[sourceStart++];
+ }
+
+ return i;
+ }
+
+ @Override
+ public int getTextStart() {
+ return 0;
+ }
+
+ @Override
+ public int getTextLength() {
+ return getText().length();
+ }
+
+ @Override
+ public String getEncoding() {
+ Object ret = document.getProperty("ENCODING");
+ if(ret == null)
+ return null;
+
+ return ret.toString();
+ }
+
+ @Override
+ public boolean hasText() {
+ return currentEvt == CHARACTERS ||
+ currentEvt == DTD ||
+ currentEvt == ENTITY_REFERENCE ||
+ currentEvt == COMMENT ||
+ currentEvt == SPACE;
+ }
+
+ @Override
+ public Location getLocation() {
+ return new Location(){
+ @Override
+ public int getLineNumber() {
+ return -1;
+ }
+
+ @Override
+ public int getColumnNumber() {
+ return -1;
+ }
+
+ @Override
+ public int getCharacterOffset() {
+ return -1;
+ }
+
+ @Override
+ public String getPublicId() {
+ return null;
+ }
+
+ @Override
+ public String getSystemId() {
+ return null;
+ }
+
+ };
+ }
+
+ @Override
+ public QName getName() {
+ if(currentEvt != START_ELEMENT && currentEvt != END_ELEMENT){
+ throw new IllegalStateException("getName not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ String ns = e.getNamespaceURI();
+ if("".equals(ns))
+ ns = null;
+
+ String prefix = e.getNamespacePrefix();
+ if(prefix == null || "".equals(prefix))
+ prefix = XMLConstants.DEFAULT_NS_PREFIX;
+
+ return new QName(ns, e.getName(), prefix);
+ }
+
+ @Override
+ public String getLocalName() {
+ switch(currentEvt){
+ case START_ELEMENT:
+ case END_ELEMENT:
+ Element e = (Element)getCurrentContent();
+ return e.getName();
+
+ case ENTITY_REFERENCE:
+ EntityRef er = (EntityRef)getCurrentContent();
+ return er.getName();
+ }
+
+ throw new IllegalStateException("getLocalName not supported for event " + currentEvt);
+ }
+
+ @Override
+ public boolean hasName() {
+ return currentEvt == START_ELEMENT || currentEvt == END_ELEMENT;
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ if(currentEvt != START_ELEMENT && currentEvt != END_ELEMENT){
+ throw new IllegalStateException("getNamespaceURI not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ String ret = e.getNamespaceURI();
+ if("".equals(ret)){
+ ret = null;
+ }
+ return ret;
+ }
+
+ @Override
+ public String getPrefix() {
+ if(currentEvt != START_ELEMENT && currentEvt != END_ELEMENT){
+ throw new IllegalStateException("getName not supported for event " + currentEvt);
+ }
+
+ Element e = (Element)getCurrentContent();
+ String ret = e.getNamespacePrefix();
+ if(ret == null || "".equals(ret))
+ ret = XMLConstants.DEFAULT_NS_PREFIX;
+
+ return ret;
+ }
+
+ @Override
+ public String getVersion() {
+ return null;
+ }
+
+ @Override
+ public boolean isStandalone() {
+ Object ret = document.getProperty("STANDALONE");
+ return Boolean.TRUE.equals(ret);
+ }
+
+ @Override
+ public boolean standaloneSet() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public String getCharacterEncodingScheme() {
+ Object ret = document.getProperty("ENCODING_SCHEME");
+ if(ret == null)
+ return null;
+
+ return ret.toString();
+ }
+
+ @Override
+ public String getPITarget() {
+ if(currentEvt != PROCESSING_INSTRUCTION){
+ throw new IllegalStateException("getPITarget not supported for event " + currentEvt);
+ }
+
+ ProcessingInstruction pi = (ProcessingInstruction)getCurrentContent();
+ return pi.getTarget();
+ }
+
+ @Override
+ public String getPIData() {
+ if(currentEvt != PROCESSING_INSTRUCTION){
+ throw new IllegalStateException("getPIData not supported for event " + currentEvt);
+ }
+
+ ProcessingInstruction pi = (ProcessingInstruction)getCurrentContent();
+ return pi.getData();
+ }
+
+ /**
+ * An Iterator that recursively walks DOM elements and returns
+ * {@link XMLStreamConstants XML stream events}.
+ */
+ private class DomWalkingContentIterator implements Iterator<Integer> {
+
+ private int contentIndex = 0;
+
+ private DomWalkingContentIterator subIterator;
+
+ private Content currentContent;
+ public Content getCurrentContent(){
+ Content ret = null;
+ if(subIterator != null){
+ ret = subIterator.getCurrentContent();
+ }
+
+ if(ret == null){
+ return currentContent;
+ }
+
+ return ret;
+ }
+
+ private Element toWalk;
+
+ public DomWalkingContentIterator(Element toWalk){
+ this.toWalk = toWalk;
+ }
+
+ @Override
+ public boolean hasNext() {
+ //if we're walking a recursive sub-iterator
+ if(subIterator != null){
+ //we either have sub-iterator content or we have END_ELEMENT
+ return true;
+ }
+
+ //if we have content remaining
+ if(toWalk.getContentSize() > contentIndex){
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public Integer next() {
+ int next;
+ if(subIterator != null){
+ //walk the sub-element
+ if(subIterator.hasNext()){
+ next = subIterator.next();
+ return next;
+ }
+ else{
+ subIterator = null;
+ return END_ELEMENT;
+ }
+ }
+
+ if(this.toWalk.getContentSize() > contentIndex){
+ Content c = this.toWalk.getContent(contentIndex++);
+ this.currentContent = c;
+ if(c.getCType() == Content.CType.Element){
+ subIterator = new DomWalkingContentIterator((Element)c);
+ return START_ELEMENT;
+ }
+
+ return getEventType(c);
+ }
+
+ throw new IllegalStateException("Iterator does not have next");
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Remove is not supported.");
+ }
+
+
+ }
+
+
+ private int getEventType(Content c){
+ switch(c.getCType()){
+ case CDATA:
+ return CDATA;
+
+ case Comment:
+ return COMMENT;
+
+ case DocType:
+ return DTD;
+
+ case EntityRef:
+ //TODO: properly expand entity refs
+ throw new UnsupportedOperationException("Entity references not yet supported");
+
+ case ProcessingInstruction:
+ return PROCESSING_INSTRUCTION;
+
+ case Text:
+ if(((Text)c).getText().trim().length() == 0){
+ return SPACE;
+ }
+ return CHARACTERS;
+
+ default:
+ throw new UnsupportedOperationException("No event type available for content type " + c.getCType());
+ }
+ }
+
+ /**
+ * The current state of the reader
+ */
+ private enum ReaderState{
+ START_DOCUMENT,
+ START_ROOT_ELEMENT,
+ WALKING_TREE,
+ END_ROOT_ELEMENT,
+ END_DOCUMENT,
+ CLOSED
+ }
+}
View
206 test/src/java/org/jdom2/test/cases/input/TestJDOMStreamWriter.java
@@ -0,0 +1,206 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+package org.jdom2.test.cases.input;
+
+import java.util.List;
+import org.jdom2.Content;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.Namespace;
+import org.jdom2.contrib.input.JDOMStreamWriter;
+import org.junit.After;
+import static org.junit.Assert.*;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link JDOMStreamWriter}
+ * @author gordon burgett https://github.com/gburgett
+ */
+public class TestJDOMStreamWriter {
+
+ public TestJDOMStreamWriter() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testEmptyRootElement_DocumentHasEmptyRoot() throws Exception {
+ System.out.println("testEmptyRootElement_DocumentHasEmptyRoot");
+
+ Document doc;
+ JDOMStreamWriter writer = new JDOMStreamWriter();
+ try{
+ writer.writeStartDocument();
+
+ writer.writeEmptyElement("testroot");
+
+ writer.writeEndDocument();
+
+ doc = writer.getDocument();
+ }
+ finally{
+ writer.close();
+ }
+
+ assertNotNull("Should have root element", doc.getRootElement());
+ assertEquals("Should have correct name", "testroot", doc.getRootElement().getName());
+ assertEquals("Should have no content", 0, doc.getRootElement().getContentSize());
+ }//end testEmptyRootElement_DocumentHasEmptyRoot
+
+ @Test
+ public void testMultipleElementsWithText_DocHasElements() throws Exception {
+ System.out.println("testMultipleElementsWithText_DocHasElements");
+
+ Document doc;
+ JDOMStreamWriter writer = new JDOMStreamWriter();
+ try{
+ writer.writeStartDocument();
+ writer.writeStartElement("testroot");
+
+ writer.writeStartElement("testdata");
+ writer.writeAttribute("id", "1");
+ writer.writeEndElement();
+
+ writer.writeStartElement("testdata");
+ writer.writeAttribute("id", "2");
+ writer.writeStartElement("deep");
+ writer.writeStartElement("deeper");
+ writer.writeCData("Textual CDATA");
+ writer.writeEndElement();
+ writer.writeEndElement();
+ writer.writeEndElement();
+
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ doc = writer.getDocument();
+ }
+ finally{
+ writer.close();
+ }
+
+ assertNotNull("Should have root element", doc.getRootElement());
+ assertEquals("Should have correct name", "testroot", doc.getRootElement().getName());
+ assertEquals("should have content", 2, doc.getRootElement().getContentSize());
+
+ List<Element> content = doc.getRootElement().getChildren();
+ assertEquals("should have correct names", "testdata", content.get(0).getName());
+ assertEquals("should have correct ID attributes", "1", content.get(0).getAttributeValue("id"));
+ assertEquals("should have correct names", "testdata", content.get(1).getName());
+ assertEquals("should have correct ID attributes", "2", content.get(1).getAttributeValue("id"));
+
+ List<Content> deepContent = content.get(1).getChild("deep").getChild("deeper").getContent();
+ assertEquals("should have CDATA element", Content.CType.CDATA, deepContent.get(0).getCType());
+ assertEquals("should have super deep data", "Textual CDATA", deepContent.get(0).getValue());
+ }//end testMultipleElementsWithText_DocHasElements
+
+ @Test
+ public void testElementsWithNamespace() throws Exception {
+ System.out.println("testElementsWithNamespace");
+
+ Document doc;
+ JDOMStreamWriter writer = new JDOMStreamWriter();
+ try{
+ writer.writeStartDocument();
+ writer.writeStartElement("testUri", "root");
+ writer.writeNamespace("tst", "testUri2");
+
+ writer.writeStartElement("tst", "element", "testUri2");
+ writer.writeAttribute("tst", "testUri2", "attr", "1");
+ writer.writeCharacters("prefixed ns");
+ writer.writeEndElement();
+
+ writer.writeStartElement("testUri", "element");
+ writer.writeCharacters("same ns");
+ writer.writeEndElement();
+
+ writer.writeStartElement("element");
+ writer.writeCharacters("no ns");
+ writer.writeEndElement();
+
+ writer.writeEndElement();
+ writer.writeEndDocument();
+
+ doc = writer.getDocument();
+ }
+ finally{
+ writer.close();
+ }
+
+ assertNotNull("Should have root element", doc.getRootElement());
+ assertEquals("Should have correct ns", "testUri", doc.getRootElement().getNamespaceURI());
+
+ List<Namespace> declared = doc.getRootElement().getNamespacesIntroduced();
+ assertEquals("Should have declared prefixed ns", "testUri2", declared.get(1).getURI());
+ assertEquals("Should have declared prefixed ns", "tst", declared.get(1).getPrefix());
+
+ List<Element> content = doc.getRootElement().getChildren();
+ assertEquals("Should have correct ns", "testUri2", content.get(0).getNamespaceURI());
+ assertEquals("Should have correct prefix", "tst", content.get(0).getNamespacePrefix());
+
+ assertEquals("Should have correct ns", "testUri", content.get(1).getNamespaceURI());
+ assertEquals("Should have no prefix", "", content.get(1).getNamespacePrefix());
+
+ assertEquals("Should have no ns", "", content.get(2).getNamespaceURI());
+ assertEquals("Should have no prefix", "", content.get(2).getNamespacePrefix());
+
+ }//end testElementsWithNamespace
+}
View
226 test/src/java/org/jdom2/test/cases/output/TestJDOMStreamReader.java
@@ -0,0 +1,226 @@
+/*--
+
+ Copyright (C) 2000-2012 Jason Hunter & Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "JDOM" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact <request_AT_jdom_DOT_org>.
+
+ 4. Products derived from this software may not be called "JDOM", nor
+ may "JDOM" appear in their name, without prior written permission
+ from the JDOM Project Management <request_AT_jdom_DOT_org>.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed by the
+ JDOM Project (http://www.jdom.org/)."
+ Alternatively, the acknowledgment may be graphical using the logos
+ available at http://www.jdom.org/images/logos.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ This software consists of voluntary contributions made by many
+ individuals on behalf of the JDOM Project and was originally
+ created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
+ Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
+ on the JDOM Project, please see <http://www.jdom.org/>.
+
+ */
+package org.jdom2.test.cases.output;
+
+import java.util.List;
+import org.jdom2.CDATA;
+import org.jdom2.Content;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.Namespace;
+import org.jdom2.Text;
+import org.jdom2.contrib.output.JDOMStreamReader;
+import org.jdom2.input.StAXStreamBuilder;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Tests for {@link JDOMStreamReader}
+ * @author gordon burgett https://github.com/gburgett
+ */
+public class TestJDOMStreamReader {
+
+ public TestJDOMStreamReader() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testSimpleDocument_BuildsFromReader_SameDocument() throws Exception {
+ System.out.println("testSimpleDocument_BuildsFromReader_SameDocument");
+
+ Document doc = new Document();
+ doc.setRootElement(new Element("simple"));
+
+ Document read;
+ JDOMStreamReader instance = new JDOMStreamReader(doc);
+ try{
+ StAXStreamBuilder builder = new StAXStreamBuilder();
+ read = builder.build(instance);
+ }
+ finally{
+ instance.close();
+ }
+
+ assertNotNull("Should have built a doc", read);
+ assertEquals("Should have correct root element", "simple", read.getRootElement().getName());
+ }//end testSimpleDocument_BuildsFromReader_SameDocument
+
+ @Test
+ public void testSimpleDocWithNamespace_BuildsFromReader_SameDocument() throws Exception {
+ System.out.println("testSimpleDocWithNamespace_BuildsFromReader_SameDocument");
+
+ Document doc = new Document();
+ doc.setRootElement(new Element("simple", Namespace.getNamespace("testns")));
+ doc.getRootElement().addNamespaceDeclaration(Namespace.getNamespace("tst", "test2"));
+
+ Element content = new Element("test2ns", Namespace.getNamespace("tst", "test2"));
+ content.setText("some text");
+ doc.getRootElement().addContent(content);
+
+ content = new Element("testNoNs", Namespace.NO_NAMESPACE);
+ content.setText("other text");
+ doc.getRootElement().addContent(content);
+
+ Document read;
+ JDOMStreamReader instance = new JDOMStreamReader(doc);
+ try{
+ StAXStreamBuilder builder = new StAXStreamBuilder();
+ read = builder.build(instance);
+ }
+ finally{
+ instance.close();
+ }
+
+ assertNotNull("Should have built a doc", read);
+ assertEquals("Should have correct root element", "simple", read.getRootElement().getName());
+ assertEquals("Should have correct root element", "testns", read.getRootElement().getNamespaceURI());
+
+ List<Namespace> additional = read.getRootElement().getAdditionalNamespaces();
+ assertEquals("Should have declared the additional ns", 2, additional.size());
+ assertEquals("Should be right ns", "test2", additional.get(1).getURI());
+ assertEquals("Should be right prefix", "tst", additional.get(1).getPrefix());
+
+ List<Element> children = read.getRootElement().getChildren();
+ assertEquals("Should have 2 kids", 2, children.size());
+ assertEquals("Should be right kids in right order", "test2ns", children.get(0).getName());
+ assertEquals("Should be right kids in right order", "test2", children.get(0).getNamespaceURI());
+ assertEquals("Should be right kids in right order", "tst", children.get(0).getNamespacePrefix());
+ assertEquals("Should be right kids in right order", "some text", children.get(0).getText());
+
+ assertEquals("Should be right kids in right order", "testNoNs", children.get(1).getName());
+ assertEquals("Should be right kids in right order", "", children.get(1).getNamespaceURI());
+ assertEquals("Should be right kids in right order", "", children.get(1).getNamespacePrefix());
+ assertEquals("Should be right kids in right order", "other text", children.get(1).getText());
+ }//end testSimpleDocWithNamespace_BuildsFromReader_SameDocument
+
+ @Test
+ public void testDocWithAttributes_HasAttributes() throws Exception {
+ System.out.println("testDocWithAttributes_HasAttributes");
+
+ Document doc = new Document();
+ doc.setRootElement(new Element("simple"));
+
+ Element content = new Element("hasAtt");
+ content.setAttribute("nons", "nons value");
+ content.setAttribute("testns", "testns value", Namespace.getNamespace("tst", "testNs"));
+ doc.getRootElement().addContent(content);
+
+ Document read;
+ JDOMStreamReader instance = new JDOMStreamReader(doc);
+ try{
+ StAXStreamBuilder builder = new StAXStreamBuilder();
+ read = builder.build(instance);
+ }
+ finally{
+ instance.close();
+ }
+
+ assertNotNull("Should have built a doc", read);
+ assertEquals("Should have correct root element", "simple", read.getRootElement().getName());
+
+ Element hasAtt = read.getRootElement().getChild("hasAtt");
+ assertEquals("should have no-ns attr", "nons value", hasAtt.getAttributeValue("nons"));
+ assertEquals("should have test-ns attr", "testns value", hasAtt.getAttributeValue("testns", Namespace.getNamespace("testNs")));
+ }//end testDocWithAttributes_HasAttributes
+
+
+ @Test
+ public void testDocWithMixedContent_HandlesMixedContent() throws Exception {
+ System.out.println("testDocWithMixedContent_HandlesMixedContent");
+
+
+ Document doc = new Document();
+ doc.setRootElement(new Element("simple"));
+
+ doc.getRootElement().addContent(new Text("pre-element text"));
+ Element el = new Element("junk");
+ el.setText("in-element text");
+ doc.getRootElement().addContent(el);
+ doc.getRootElement().addContent(new CDATA("post-element text"));
+
+ Document read;
+ JDOMStreamReader instance = new JDOMStreamReader(doc);
+ try{
+ StAXStreamBuilder builder = new StAXStreamBuilder();
+ read = builder.build(instance);
+ }
+ finally{
+ instance.close();
+ }
+
+ assertNotNull("Should have built a doc", read);
+ assertEquals("Should have correct root element", "simple", read.getRootElement().getName());
+
+ List<Content> content = read.getRootElement().getContent();
+ assertEquals("first content should be text", Content.CType.Text, content.get(0).getCType());
+ assertEquals("second content should be element", Content.CType.Element, content.get(1).getCType());
+ assertEquals("third content should be CDATA", Content.CType.CDATA, content.get(2).getCType());
+
+ assertEquals("pre-element text", content.get(0).getValue());
+ assertEquals("in-element text", content.get(1).getValue());
+ assertEquals("post-element text", content.get(2).getValue());
+ }//end testDocWithMixedContent_HandlesMixedContent
+
+}
+
+

0 comments on commit ac5f25a

Please sign in to comment.
Something went wrong with that request. Please try again.