001: /*
002: * Copyright (C) 2004, 2005, 2006 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 07. March 2004 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.io.xml;
013:
014: import com.thoughtworks.xstream.core.util.FastStack;
015: import com.thoughtworks.xstream.io.StreamException;
016:
017: import org.dom4j.Element;
018: import org.dom4j.io.XMLWriter;
019: import org.dom4j.tree.DefaultElement;
020: import org.xml.sax.SAXException;
021: import org.xml.sax.helpers.AttributesImpl;
022:
023: import java.io.IOException;
024:
025: public class Dom4JXmlWriter extends AbstractXmlWriter {
026:
027: private final XMLWriter writer;
028: private final FastStack elementStack;
029: private AttributesImpl attributes;
030: private boolean started;
031: private boolean children;
032:
033: public Dom4JXmlWriter(XMLWriter writer) {
034: this (writer, new XmlFriendlyReplacer());
035: }
036:
037: /**
038: * @since 1.2
039: */
040: public Dom4JXmlWriter(XMLWriter writer, XmlFriendlyReplacer replacer) {
041: super (replacer);
042: this .writer = writer;
043: this .elementStack = new FastStack(16);
044: this .attributes = new AttributesImpl();
045: try {
046: writer.startDocument();
047: } catch (SAXException e) {
048: throw new StreamException(e);
049: }
050: }
051:
052: public void startNode(String name) {
053: if (elementStack.size() > 0) {
054: try {
055: startElement();
056: } catch (SAXException e) {
057: throw new StreamException(e);
058: }
059: started = false;
060: }
061: elementStack.push(escapeXmlName(name));
062: children = false;
063: }
064:
065: public void setValue(String text) {
066: char[] value = text.toCharArray();
067: if (value.length > 0) {
068: try {
069: startElement();
070: writer.characters(value, 0, value.length);
071: } catch (SAXException e) {
072: throw new StreamException(e);
073: }
074: children = true;
075: }
076: }
077:
078: public void addAttribute(String key, String value) {
079: attributes.addAttribute("", "", escapeXmlName(key), "string",
080: value);
081: }
082:
083: public void endNode() {
084: try {
085: if (!children) {
086: Element element = new DefaultElement(
087: (String) elementStack.pop());
088: for (int i = 0; i < attributes.getLength(); ++i) {
089: element.addAttribute(attributes.getQName(i),
090: attributes.getValue(i));
091: }
092: writer.write(element);
093: attributes.clear();
094: children = true; // node just closed is child of node on top of stack
095: started = true;
096: } else {
097: startElement();
098: writer.endElement("", "", (String) elementStack.pop());
099: }
100: } catch (SAXException e) {
101: throw new StreamException(e);
102: } catch (IOException e) {
103: throw new StreamException(e);
104: }
105: }
106:
107: public void flush() {
108: // nothing to do
109: }
110:
111: public void close() {
112: try {
113: writer.endDocument();
114: } catch (SAXException e) {
115: throw new StreamException(e);
116: }
117: }
118:
119: private void startElement() throws SAXException {
120: if (!started) {
121: writer.startElement("", "", (String) elementStack.peek(),
122: attributes);
123: attributes.clear();
124: started = true;
125: }
126: }
127: }
|