Browse files

Updated to latest JDOMStreamReader/Writer from JDOM dev branch

Signed-off-by: gburgett <gordon.burgett@gmail.com>
  • Loading branch information...
1 parent 453e83a commit 83c16617bdbb356298ff9cf37de5b52b5b274405 @gburgett committed Jan 26, 2013
View
23 java/XFlat/src/org/gburgett/xflat/convert/converters/JAXBPojoConverter.java
@@ -23,12 +23,12 @@
import org.gburgett.xflat.convert.Converter;
import org.gburgett.xflat.convert.PojoConverter;
import org.gburgett.xflat.db.IdAccessor;
-import org.gburgett.xflat.util.JDOMStreamReader;
-import org.gburgett.xflat.util.JDOMStreamWriter;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.filter.Filters;
+import org.jdom2.jaxb.JDOMStreamReader;
+import org.jdom2.jaxb.JDOMStreamWriter;
import org.jdom2.output.XMLOutputter;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;
@@ -262,11 +262,15 @@ public JAXBMarshallingConverter(Class<T> clazz, Marshaller marshaller){
public Element convert(T source) throws ConversionException {
try{
Document doc;
- try(JDOMStreamWriter out = new JDOMStreamWriter()){
+ JDOMStreamWriter out = new JDOMStreamWriter();
+ try{
this.marshaller.marshal(source, out);
doc = out.getDocument();
}
+ finally{
+ out.close();
+ }
return doc.detachRootElement();
@@ -293,14 +297,21 @@ public T convert(Element source) throws ConversionException {
Document doc = new Document();
doc.setRootElement(source.detach());
- try(JDOMStreamReader in = new JDOMStreamReader(doc)){
+ JDOMStreamReader in = new JDOMStreamReader(doc);
+ try{
T ret = (T)unmarshaller.unmarshal(in);
return ret;
}
- catch(JAXBException | XMLStreamException | ClassCastException ex){
+ catch(JAXBException | ClassCastException ex){
throw new ConversionException("Unable to convert element to " + clazz, ex);
}
-
+ finally{
+ try{
+ in.close();
+ }catch(XMLStreamException ex){
+ //ignore
+ }
+ }
}
}
View
59 java/XFlat/src/org/gburgett/xflat/util/JDOMNamespaceContext.java
@@ -1,59 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.gburgett.xflat.util;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import javax.xml.namespace.NamespaceContext;
-import org.jdom2.Namespace;
-
-/**
- *
- * @author gordon
- */
-public class JDOMNamespaceContext implements NamespaceContext {
-
- private List<Namespace> namespaces;
-
- public JDOMNamespaceContext(List<Namespace> namespaces){
- this.namespaces = new ArrayList<>(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<>();
- for(Namespace n : namespaces){
- if(n.getURI().equals(namespaceURI)){
- ret.add(n.getPrefix());
- }
- }
-
- return ret.iterator();
- }
-
-}
View
750 java/XFlat/src/org/gburgett/xflat/util/JDOMStreamReader.java
@@ -1,750 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.gburgett.xflat.util;
-
-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;
-
-/**
- *
- * @author gordon
- */
-public class JDOMStreamReader implements XMLStreamReader, AutoCloseable {
-
- 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 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();
- }
-
- 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 attributes remaining
-// if(toWalk.getAttributes().size() > attributeIndex){
-// 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;
- }
- }
-
-// //walk namespaces
-// if(this.toWalk.getNamespacesIntroduced().size() > this.namespaceIndex){
-// this.currentNamespace = this.toWalk.getNamespacesIntroduced().get(this.namespaceIndex++);
-// return NAMESPACE;
-// }
-// else{
-// this.currentNamespace = null;
-// }
-//
-// //walk attributes
-// if(this.toWalk.getAttributes().size() > this.attributeIndex){
-// this.currentAttribute = this.toWalk.getAttributes().get(this.attributeIndex++);
-// return ATTRIBUTE;
-// }
-// else{
-// this.currentAttribute = null;
-// }
-
- 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:
- throw new UnsupportedOperationException("Entity references not 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());
- }
- }
-
- private enum ReaderState{
- START_DOCUMENT,
- START_ROOT_ELEMENT,
- WALKING_TREE,
- END_ROOT_ELEMENT,
- END_DOCUMENT,
- CLOSED
- }
-}
View
415 java/XFlat/src/org/gburgett/xflat/util/JDOMStreamWriter.java
@@ -1,415 +0,0 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.gburgett.xflat.util;
-
-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;
-
-/**
- *
- * @author gordon
- */
-public class JDOMStreamWriter implements XMLStreamWriter, AutoCloseable {
-
- private Document document;
- private Stack<Element> elementStack = new Stack<>();
-
- private Element root;
-
- private String encoding, version;
-
- private StreamWriterState state = StreamWriterState.BEFORE_DOCUMENT_START;
-
- 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("1.0");
- }
-
- @Override
- public void writeStartDocument(String version) throws XMLStreamException {
- this.writeStartDocument("UTF-8", 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.encoding = encoding;
- this.version = version;
- this.document = new Document();
-
- 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 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
164 java/XFlat/src/org/jdom2/jaxb/JDOMNamespaceContext.java
@@ -0,0 +1,164 @@
+/*--
+
+ 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.jaxb;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.namespace.NamespaceContext;
+
+import org.jdom2.JDOMConstants;
+import org.jdom2.Namespace;
+import org.jdom2.internal.ArrayCopy;
+
+/**
+ * A Read-Only {@link NamespaceContext} that describes namespaces found
+ * in a JDOM node.
+ * @author gordon burgett https://github.com/gburgett
+ */
+public final class JDOMNamespaceContext implements NamespaceContext {
+
+ private final Namespace[] namespacearray;
+
+ /**
+ * Create a read-only representation of the input namespace list.
+ * @param namespaces the Namespace instances to represent.
+ */
+ public JDOMNamespaceContext(final Namespace[] namespaces){
+ if (namespaces == null) {
+ throw new IllegalArgumentException("Cannot process a null Namespace list");
+ }
+ this.namespacearray = ArrayCopy.copyOf(namespaces, namespaces.length);
+ for (int i = 1; i < namespacearray.length; i++) {
+ final Namespace n = namespacearray[i];
+ if (n == null) {
+ throw new IllegalArgumentException("Cannot process null namespace at position " + i);
+ }
+ final String p = n.getPrefix();
+ for (int j = 0; j < i; j++) {
+ if (p.equals(namespacearray[j].getPrefix())) {
+ throw new IllegalArgumentException("Cannot process multiple namespaces with the prefix '" + p + "'.");
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getNamespaceURI(final String prefix) {
+ if (prefix == null) {
+ throw new IllegalArgumentException("NamespaceContext requires a non-null prefix");
+ }
+ if (JDOMConstants.NS_PREFIX_XML.equals(prefix)) {
+ return JDOMConstants.NS_URI_XML;
+ }
+ if (JDOMConstants.NS_PREFIX_XMLNS.equals(prefix)) {
+ return JDOMConstants.NS_URI_XMLNS;
+ }
+
+ for(final Namespace n : namespacearray){
+ if(n.getPrefix().equals(prefix)){
+ return n.getURI();
+ }
+ }
+
+ return "";
+ }
+
+ @Override
+ public String getPrefix(final String namespaceURI) {
+ if (namespaceURI == null) {
+ throw new IllegalArgumentException("NamespaceContext requires a non-null Namespace URI");
+ }
+ if (JDOMConstants.NS_URI_XML.equals(namespaceURI)) {
+ return JDOMConstants.NS_PREFIX_XML;
+ }
+ if (JDOMConstants.NS_URI_XMLNS.equals(namespaceURI)) {
+ return JDOMConstants.NS_PREFIX_XMLNS;
+ }
+
+ for(final Namespace n : namespacearray){
+ if(n.getURI().equals(namespaceURI)){
+ return n.getPrefix();
+ }
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Iterator getPrefixes(final String namespaceURI) {
+ if (namespaceURI == null) {
+ throw new IllegalArgumentException("NamespaceContext requires a non-null Namespace URI");
+ }
+ if (JDOMConstants.NS_URI_XML.equals(namespaceURI)) {
+ return Collections.singleton(JDOMConstants.NS_PREFIX_XML).iterator();
+ }
+ if (JDOMConstants.NS_URI_XMLNS.equals(namespaceURI)) {
+ return Collections.singleton(JDOMConstants.NS_PREFIX_XMLNS).iterator();
+ }
+
+ final List<String> ret = new ArrayList<String>();
+ for(final Namespace n : namespacearray){
+ if(n.getURI().equals(namespaceURI)){
+ ret.add(n.getPrefix());
+ }
+ }
+
+ return Collections.unmodifiableCollection(ret).iterator();
+ }
+
+}
View
802 java/XFlat/src/org/jdom2/jaxb/JDOMStreamReader.java
@@ -0,0 +1,802 @@
+/*--
+
+ 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.jaxb;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+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.Verifier;
+import org.jdom2.internal.ArrayCopy;
+import org.jdom2.output.Format;
+import org.jdom2.output.Format.TextMode;
+import org.jdom2.output.XMLOutputter;
+import org.jdom2.output.support.AbstractOutputProcessor;
+import org.jdom2.output.support.FormatStack;
+import org.jdom2.output.support.Walker;
+import org.jdom2.jaxb.NamespaceStack;
+
+/**
+ * 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 extends AbstractOutputProcessor implements XMLStreamReader {
+
+ private static final class DocumentWalker implements Walker {
+
+ private final Content[] data;
+ private int pos = 0;
+
+ public DocumentWalker(final Document doc) {
+ data = doc.getContent().toArray(new Content[doc.getContentSize()]);
+ }
+
+ @Override
+ public boolean isAllText() {
+ return false;
+ }
+
+ @Override
+ public boolean isAllWhitespace() {
+ return false;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return pos < data.length;
+ }
+
+ @Override
+ public Content next() {
+ return data[pos++];
+ }
+
+ @Override
+ public String text() {
+ return null;
+ }
+
+ @Override
+ public boolean isCDATA() {
+ return false;
+ }
+
+ }
+
+ private final FormatStack formatstack;
+ private final NamespaceStack nsstack = new NamespaceStack();
+
+ private Document document;
+
+ private String curi = null, clocalname = null, cprefix = null,
+ ctext = null, ctarget = null, cdata = null;
+ private Element [] emtstack = new Element[32];
+ private Walker[] stack = new Walker[32];
+ private int depth = 0;
+
+ private int currentEvt = START_DOCUMENT;
+
+ /**
+ * Create a new JDOMStreamReader that outputs a JDOM Document as an XMLStream.
+ * @param document the document to output.
+ * @param format The output format to use.
+ */
+ public JDOMStreamReader(Document document, Format format){
+ this.document = document;
+ this.formatstack = new FormatStack(format);
+ stack[0] = new DocumentWalker(document);
+ }
+
+ /**
+ * Create a new JDOMStreamReader that outputs a JDOM Document as an XMLStream using
+ * the Format.getRawFormat() format.
+ * @param document the document to output.
+ */
+ public JDOMStreamReader(Document document) {
+ this(document, Format.getRawFormat());
+ }
+
+ @Override
+ public boolean hasNext() throws XMLStreamException {
+ return depth >= 0;
+ }
+
+ @Override
+ public int next() throws XMLStreamException {
+ if (depth < 0) {
+ throw new NoSuchElementException("No more data available.");
+ }
+
+ curi = null;
+ clocalname = null;
+ cprefix = null;
+ ctext = null;
+ ctarget = null;
+ cdata = null;
+
+ if (currentEvt == END_ELEMENT) {
+ nsstack.pop();
+ formatstack.pop();
+ emtstack[depth + 1] = null;
+ }
+
+ // confirm next walker item.
+ if (!stack[depth].hasNext()) {
+ // no more items at this level.
+ stack[depth] = null;
+ // we kill the element stack at the end of the END_ELEMENT event.
+ // emtstack[depth] = null
+ depth--;
+ return currentEvt = (depth < 0 ? END_DOCUMENT : END_ELEMENT);
+ }
+
+ final Content c = stack[depth].next();
+ if (c == null) {
+ // formatted text or CDATA.
+ ctext = stack[depth].text();
+ return currentEvt = stack[depth].isCDATA() ? CDATA : CHARACTERS;
+ }
+
+ switch (c.getCType()) {
+ case CDATA:
+ ctext = c.getValue();
+ return currentEvt = CDATA;
+ case Text:
+ ctext = c.getValue();
+ return currentEvt = CHARACTERS;
+ case Comment:
+ ctext = c.getValue();
+ return currentEvt = COMMENT;
+ case DocType:
+ // format doctype appropriately.
+ XMLOutputter xout = new XMLOutputter();
+ ctext = xout.outputString((DocType)c);
+ return currentEvt = DTD;
+ case EntityRef:
+ clocalname = ((EntityRef)c).getName();
+ ctext = "";
+ return currentEvt = ENTITY_REFERENCE;
+ case ProcessingInstruction:
+ final ProcessingInstruction pi = (ProcessingInstruction)c;
+ ctarget = pi.getTarget();
+ cdata = pi.getData();
+ return currentEvt = PROCESSING_INSTRUCTION;
+ case Element:
+ // great
+ // we deal with Element outside the switch statement.
+ break;
+ default:
+ throw new IllegalStateException("Unexpected content " + c);
+ }
+ // OK, we break out here if we are an Element start.
+ final Element emt = (Element)c;
+ clocalname = emt.getName();
+ cprefix = emt.getNamespacePrefix();
+ curi = emt.getNamespaceURI();
+
+ nsstack.push(emt);
+ formatstack.push();
+ final String space = emt.getAttributeValue("space", Namespace.XML_NAMESPACE);
+ // Check for xml:space and adjust format settings
+ if ("default".equals(space)) {
+ formatstack.setTextMode(formatstack.getDefaultMode());
+ }
+ else if ("preserve".equals(space)) {
+ formatstack.setTextMode(TextMode.PRESERVE);
+ }
+
+ depth++;
+ if (depth >= stack.length) {
+ stack = ArrayCopy.copyOf(stack, depth + 32);
+ emtstack = ArrayCopy.copyOf(emtstack, depth+32);
+ }
+
+ emtstack[depth] = emt;
+ stack[depth] = buildWalker(formatstack, emt.getContent(), false);
+
+ return currentEvt = START_ELEMENT;
+
+ }
+
+ @Override
+ public int getEventType() {
+ return currentEvt;
+ }
+
+ @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() {
+ switch (currentEvt) {
+ case SPACE :
+ return true;
+ case CDATA:
+ case CHARACTERS:
+ return Verifier.isAllXMLWhitespace(ctext);
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
+ if(type != getEventType()){
+ throw new XMLStreamException("required event " + type + " but got event " + getEventType());
+ }
+
+ if(localName != null){
+ if(!localName.equals(clocalname)){
+ throw new XMLStreamException("required name " + localName + " but got name " + clocalname);
+ }
+ }
+
+ if(namespaceURI != null){
+ if(!namespaceURI.equals(curi)){
+ throw new XMLStreamException("required namespace " + namespaceURI + " but got namespace " + curi);
+ }
+ }
+ }
+
+ @Override
+ public QName getName() {
+ switch (currentEvt) {
+ case START_ELEMENT:
+ case END_ELEMENT:
+ final Element emt = emtstack[depth];
+ return new QName(emt.getNamespaceURI(), emt.getName(), emt.getNamespacePrefix());
+ default:
+ throw new IllegalStateException("getName not supported for event " + currentEvt);
+ }
+ }
+
+ @Override
+ public String getLocalName() {
+ switch (currentEvt) {
+ case START_ELEMENT:
+ case END_ELEMENT:
+ case ENTITY_REFERENCE:
+ return clocalname;
+ default:
+ throw new IllegalStateException("getLocalName not supported for event " + currentEvt);
+ }
+ }
+
+ @Override
+ public boolean hasName() {
+ return currentEvt == START_ELEMENT || currentEvt == END_ELEMENT;
+ }
+
+ @Override
+ public String getNamespaceURI() {
+ switch (currentEvt) {
+ case START_ELEMENT:
+ case END_ELEMENT:
+ return curi;
+ default:
+ throw new IllegalStateException("getNamespaceURI not supported for event " + currentEvt);
+ }
+ }
+
+ @Override
+ public String getPrefix() {
+ switch (currentEvt) {
+ case START_ELEMENT:
+ case END_ELEMENT:
+ return cprefix;
+ default:
+ throw new IllegalStateException("getPrefix not supported for event " + currentEvt);
+ }
+ }
+
+ @Override
+ public String getPITarget() {
+ switch (currentEvt) {
+ case PROCESSING_INSTRUCTION:
+ return ctarget;
+ default:
+ throw new IllegalStateException("getPITarget not supported for event " + currentEvt);
+ }
+ }
+
+ @Override
+ public String getPIData() {
+ switch (currentEvt) {
+ case PROCESSING_INSTRUCTION:
+ return cdata;
+ default:
+ throw new IllegalStateException("getPIData not supported for event " + currentEvt);
+ }
+ }
+
+
+ @Override
+ public String getElementText() throws XMLStreamException {
+ // copied from documentation.
+ if(getEventType() != XMLStreamConstants.START_ELEMENT) {
+ throw new XMLStreamException("parser must be on START_ELEMENT to read next text");
+ }
+
+ int eventType = next();
+ StringBuilder buf = new StringBuilder();
+ 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 void close() throws XMLStreamException {
+ currentEvt = END_DOCUMENT;
+ while (depth >= 0) {
+ stack[depth] = null;
+ emtstack[depth] = null;
+ depth--;
+ }
+ cdata = null;
+ clocalname = null;
+ cprefix = null;
+ ctarget = null;
+ ctext = null;
+ curi = null;
+ this.document = null;
+ }
+
+ @Override
+ public String getNamespaceURI(String prefix) {
+ final Namespace ns = nsstack.getNamespaceForPrefix(prefix);
+ return ns == null ? null : ns.getURI();
+ }
+
+ @Override
+ public String getAttributeValue(String namespaceURI, String localName) {
+ if(currentEvt != START_ELEMENT){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ final Element e = emtstack[depth];
+ if (!e.hasAttributes()) {
+ return null;
+ }
+
+ 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){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+ return emtstack[depth].getAttributes().size();
+ }
+
+ @Override
+ public QName getAttributeName(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ final Attribute a = emtstack[depth].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);
+ }
+
+ final Attribute a = emtstack[depth].getAttributes().get(index);
+ return a.getNamespaceURI();
+ }
+
+ @Override
+ public String getAttributeLocalName(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ final Attribute a = emtstack[depth].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);
+ }
+
+ final Attribute a = emtstack[depth].getAttributes().get(index);
+ return a.getNamespacePrefix();
+ }
+
+ @Override
+ public String getAttributeType(int index) {
+ if(currentEvt != START_ELEMENT && currentEvt != ATTRIBUTE){
+ throw new IllegalStateException("getAttributeCount not supported for event " + currentEvt);
+ }
+
+ final Attribute a = emtstack[depth].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);
+ }
+
+ final Attribute a = emtstack[depth].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);
+ }
+
+ final Attribute a = emtstack[depth].getAttributes().get(index);
+ return a.isSpecified();
+ }
+
+ @Override
+ public int getNamespaceCount() {
+ switch(currentEvt){
+ case START_ELEMENT:
+ case END_ELEMENT:
+ final Iterator<?> it = nsstack.addedForward().iterator();
+ int cnt = 0;
+ while (it.hasNext()) {
+ cnt++;
+ it.next();
+ }
+ return cnt;
+ }
+
+ throw new IllegalStateException("getNamespaceCount not supported for event " + currentEvt);
+ }
+
+ private final Namespace getNamespaceByIndex(int index) {
+ final Iterator<Namespace> it = nsstack.addedForward().iterator();
+ int cnt = 0;
+ while (it.hasNext()) {
+ if (cnt == index) {
+ return it.next();
+ }
+ it.next();
+ cnt++;
+ }
+ throw new NoSuchElementException("No Namespace with index " + index +
+ " (there are only " + cnt + ").");
+ }
+
+ @Override
+ public String getNamespacePrefix(int index) {
+ switch(currentEvt){
+ case START_ELEMENT:
+ case END_ELEMENT:
+ return getNamespaceByIndex(index).getPrefix();
+ }
+
+ 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:
+ return getNamespaceByIndex(index).getURI();
+ }
+
+ throw new IllegalStateException("getNamespaceURI not supported for event " + currentEvt);
+ }
+
+ @Override
+ public NamespaceContext getNamespaceContext() {
+ return new JDOMNamespaceContext(nsstack.getScope());
+ }
+
+ @Override
+ public boolean hasText() {
+ switch(currentEvt){
+ case CDATA:
+ case CHARACTERS:
+ case COMMENT:
+ case DTD:
+ case ENTITY_REFERENCE:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public String getText() {
+ switch(currentEvt){
+ case CDATA:
+ case CHARACTERS:
+ case COMMENT:
+ case DTD:
+ case ENTITY_REFERENCE:
+ return ctext;
+ default:
+ 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 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 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 Object getProperty(final String name) throws IllegalArgumentException {
+ if (name == null) {
+ throw new IllegalArgumentException("Property name is not allowed to be null");
+ }
+ if (XMLInputFactory.ALLOCATOR.equals(name)) {
+ return null;
+ }
+ if (XMLInputFactory.IS_COALESCING.equals(name)) {
+ return formatstack.getDefaultMode() != TextMode.PRESERVE;
+ }
+ if (XMLInputFactory.IS_NAMESPACE_AWARE.equals(name)) {
+ return Boolean.TRUE;
+ }
+ if (XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES.equals(name)) {
+ return Boolean.FALSE;
+ }
+ if (XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES.equals(name)) {
+ return Boolean.FALSE;
+ }
+ if (XMLInputFactory.IS_VALIDATING.equals(name)) {
+ return Boolean.TRUE;
+ }
+ if (XMLInputFactory.REPORTER.equals(name)) {
+ return null;
+ }
+ if (XMLInputFactory.RESOLVER.equals(name)) {
+ return null;
+ }
+ return null;
+ }
+}
View
713 java/XFlat/src/org/jdom2/jaxb/JDOMStreamWriter.java
@@ -0,0 +1,713 @@
+/*--
+
+ 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.jaxb;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.jdom2.DefaultJDOMFactory;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMConstants;
+import org.jdom2.JDOMFactory;
+import org.jdom2.Namespace;
+import org.jdom2.Parent;
+import org.jdom2.Text;
+import org.jdom2.jaxb.NamespaceStack;
+
+/**
+ * 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 static final DefaultJDOMFactory DEFFAC = new DefaultJDOMFactory();
+
+ // The optional global namespace context for namespace bindings.
+ private NamespaceContext globalcontext = null;
+
+ // The active Element NamespaceStack of actual used Namespaces.
+ private NamespaceStack usednsstack = new NamespaceStack();
+ // The stack of namespace bindings which may not necessarily be used in an element
+ private NamespaceStack boundstack = new NamespaceStack();
+
+ // The namespaces pending in the current Element that need to be actively bound.
+ private LinkedList<Namespace> pendingns = new LinkedList<Namespace>();
+
+ // Are we throwing exceptions for namespace problems, or fixing them.
+ private final boolean repairnamespace;
+
+ private Document document = null;
+ private boolean done = false;
+ private Parent parent = null;
+ private Element activeelement = null;
+ private boolean isempty = false;
+ private Text activetext = null;
+
+ private int genprefix = 0;
+
+ private final JDOMFactory factory;
+
+ /**
+ * Create a JDOMStreamWriter with the default JDOMFactory for creating JDOM
+ * Content.
+ */
+ public JDOMStreamWriter() {
+ this(DEFFAC, true);
+ }
+
+ /**
+ * Create a JDOMStreamWriter with the specified JDOMFactory for creating
+ * JDOM Content.
+ *
+ * @param fac
+ * The JDOMFactory to use.
+ * @param repairnamespace
+ * If true, then repair namespace errors.
+ */
+ public JDOMStreamWriter(final JDOMFactory fac, final boolean repairnamespace) {
+ this.factory = fac;
+ this.repairnamespace = repairnamespace;
+ // create an empty level in the namespace stack.
+ boundstack.push(new Namespace[0]);
+ }
+
+ /**
+ * Gets the {@link Document} that was created by this writer. Only available
+ * after {@link #writeEndDocument() } has been called, and before the Writer
+ * is closed.
+ *
+ * @return The created {@link Document}
+ */
+ public Document getDocument() {
+ if (done && document != null) {
+ return document;
+ }
+
+ if (done) {
+ throw new IllegalStateException("Writer is closed");
+ }
+
+ throw new IllegalStateException(
+ "Cannot get Document until writer has ended the document");
+
+ }
+
+ @Override
+ public void writeStartDocument() throws XMLStreamException {
+ this.writeStartDocument(null, null);
+ }
+
+ @Override
+ public void writeStartDocument(final String version)
+ throws XMLStreamException {
+ this.writeStartDocument(null, version);
+ }
+
+ @Override
+ public void writeStartDocument(final String encoding, final String version)
+ throws XMLStreamException {
+
+ // JDOM has no support for XML Version specification/handling
+ // ignore version.