001: /*
002: Copyright (c) 2004, Dennis M. Sosnoski
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.extras;
030:
031: import java.io.IOException;
032:
033: import org.jdom.CDATA;
034: import org.jdom.Comment;
035: import org.jdom.DocType;
036: import org.jdom.Document;
037: import org.jdom.Element;
038: import org.jdom.EntityRef;
039: import org.jdom.Namespace;
040: import org.jdom.ProcessingInstruction;
041: import org.jdom.Text;
042: import org.jibx.runtime.impl.XMLWriterNamespaceBase;
043:
044: /**
045: * JDOM implementation of XML writer interface. The <code>Document</code> that is
046: * created can be accessed by using <code>getDocument()</code>.
047: *
048: * @author Andreas Brenk
049: * @version 1.0
050: */
051: public class JDOMWriter extends XMLWriterNamespaceBase {
052:
053: /**
054: * The JDOM <code>Document</code> this writer is creating.
055: */
056: private Document document;
057:
058: /**
059: * The currently open <code>Element</code> that is used for add* methods.
060: */
061: private Element currentElement;
062:
063: /**
064: * Creates a new instance with the given namespace URIs.
065: */
066: public JDOMWriter(String[] namespaces) {
067: super (namespaces);
068: reset();
069: }
070:
071: /**
072: * Creates a new instance with the given Document as target for marshalling.
073: *
074: * @param document must not be null
075: */
076: public JDOMWriter(String[] namespaces, Document document) {
077: this (namespaces);
078: this .document = document;
079: if (document.hasRootElement()) {
080: this .currentElement = document.getRootElement();
081: }
082: }
083:
084: /**
085: * Creates a new instance with the given Element as target for marshalling.
086: *
087: * @param currentElement must not be null
088: */
089: public JDOMWriter(String[] namespaces, Element currentElement) {
090: this (namespaces, currentElement.getDocument());
091: this .currentElement = currentElement;
092: }
093:
094: /**
095: * Does nothing.
096: */
097: public void setIndentSpaces(int count, String newline, char indent) {
098: // do nothing
099: }
100:
101: /**
102: * Does nothing.
103: */
104: public void writeXMLDecl(String version, String encoding,
105: String standalone) throws IOException {
106: // do nothing
107: }
108:
109: public void startTagOpen(int index, String name) throws IOException {
110: Element newElement = new Element(name, getNamespace(index));
111:
112: if (this .currentElement == null) {
113: this .document.setRootElement(newElement);
114: } else {
115: this .currentElement.addContent(newElement);
116: }
117:
118: this .currentElement = newElement;
119: }
120:
121: public void startTagNamespaces(int index, String name, int[] nums,
122: String[] prefs) throws IOException {
123: // find the namespaces actually being declared
124: int[] deltas = openNamespaces(nums, prefs);
125:
126: // create the start tag for element
127: startTagOpen(index, name);
128:
129: // add namespace declarations to open element
130: for (int i = 0; i < deltas.length; i++) {
131: int slot = deltas[i];
132: this .currentElement
133: .addNamespaceDeclaration(getNamespace(slot));
134: }
135: }
136:
137: public void addAttribute(int index, String name, String value)
138: throws IOException {
139: this .currentElement.setAttribute(name, value,
140: getNamespace(index));
141: }
142:
143: public void closeStartTag() throws IOException {
144: incrementNesting();
145: }
146:
147: public void closeEmptyTag() throws IOException {
148: incrementNesting();
149: decrementNesting();
150: this .currentElement = this .currentElement.getParentElement();
151: }
152:
153: public void startTagClosed(int index, String name)
154: throws IOException {
155: startTagOpen(index, name);
156: closeStartTag();
157: }
158:
159: public void endTag(int index, String name) throws IOException {
160: decrementNesting();
161: this .currentElement = this .currentElement.getParentElement();
162: }
163:
164: public void writeTextContent(String text) throws IOException {
165: this .currentElement.addContent(new Text(text));
166: }
167:
168: public void writeCData(String text) throws IOException {
169: this .currentElement.addContent(new CDATA(text));
170: }
171:
172: public void writeComment(String text) throws IOException {
173: this .currentElement.addContent(new Comment(text));
174: }
175:
176: public void writeEntityRef(String name) throws IOException {
177: this .currentElement.addContent(new EntityRef(name));
178: }
179:
180: public void writeDocType(String name, String sys, String pub,
181: String subset) throws IOException {
182: DocType docType;
183: if (null != pub) {
184: docType = new DocType(name, pub, sys);
185: } else if (null != sys) {
186: docType = new DocType(name, sys);
187: } else {
188: docType = new DocType(name);
189: }
190: if (null != subset) {
191: docType.setInternalSubset(subset);
192: }
193: this .document.setDocType(docType);
194: }
195:
196: public void writePI(String target, String data) throws IOException {
197: this .currentElement.addContent(new ProcessingInstruction(
198: target, data));
199: }
200:
201: /**
202: * Does nothing.
203: */
204: public void indent() throws IOException {
205: // do nothing
206: }
207:
208: /**
209: * Does nothing.
210: */
211: public void flush() throws IOException {
212: // do nothing
213: }
214:
215: /**
216: * Does nothing.
217: */
218: public void close() throws IOException {
219: // do nothing
220: }
221:
222: public void reset() {
223: super .reset();
224: this .document = new Document();
225: this .currentElement = null;
226: }
227:
228: /**
229: * @return the JDOM <code>Document</code> this writer created.
230: */
231: public Document getDocument() {
232: return document;
233: }
234:
235: /**
236: * Does nothing.
237: */
238: protected void defineNamespace(int index, String prefix)
239: throws IOException {
240: // do nothing
241: }
242:
243: /**
244: * Does nothing.
245: */
246: protected void undefineNamespace(int index) {
247: // do nothing
248: }
249:
250: /**
251: * This will retrieve (if in existence) or create (if not) a
252: * <code>Namespace</code> for the supplied namespace index.
253: */
254: private Namespace getNamespace(int index) {
255: String prefix = getNamespacePrefix(index);
256: String uri = getNamespaceUri(index);
257: if (prefix == null) {
258: return Namespace.getNamespace(uri);
259: } else {
260: return Namespace.getNamespace(prefix, uri);
261: }
262: }
263: }
|