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 29. September 2004 by James Strachan
011: */
012: package com.thoughtworks.xstream.io.xml;
013:
014: import java.io.InputStream;
015: import java.io.OutputStream;
016: import java.io.Reader;
017: import java.io.Writer;
018:
019: import javax.xml.stream.XMLInputFactory;
020: import javax.xml.stream.XMLOutputFactory;
021: import javax.xml.stream.XMLStreamException;
022: import javax.xml.stream.XMLStreamReader;
023: import javax.xml.stream.XMLStreamWriter;
024:
025: import com.thoughtworks.xstream.io.HierarchicalStreamReader;
026: import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
027: import com.thoughtworks.xstream.io.StreamException;
028:
029: /**
030: * A driver using the StAX API
031: *
032: * @author James Strachan
033: * @version $Revision: 1345 $
034: */
035: public class StaxDriver extends AbstractXmlDriver {
036:
037: private static boolean libraryPresent;
038:
039: private QNameMap qnameMap;
040: private XMLInputFactory inputFactory;
041: private XMLOutputFactory outputFactory;
042:
043: public StaxDriver() {
044: this .qnameMap = new QNameMap();
045: }
046:
047: public StaxDriver(QNameMap qnameMap) {
048: this (qnameMap, false);
049: }
050:
051: /**
052: * @deprecated since 1.2, use an explicit call to {@link #setRepairingNamespace(boolean)}
053: */
054: public StaxDriver(QNameMap qnameMap, boolean repairingNamespace) {
055: this (qnameMap, new XmlFriendlyReplacer());
056: setRepairingNamespace(repairingNamespace);
057: }
058:
059: /**
060: * @since 1.2
061: */
062: public StaxDriver(QNameMap qnameMap, XmlFriendlyReplacer replacer) {
063: super (replacer);
064: this .qnameMap = qnameMap;
065: }
066:
067: /**
068: * @since 1.2
069: */
070: public StaxDriver(XmlFriendlyReplacer replacer) {
071: this (new QNameMap(), replacer);
072: }
073:
074: public HierarchicalStreamReader createReader(Reader xml) {
075: loadLibrary();
076: try {
077: return createStaxReader(createParser(xml));
078: } catch (XMLStreamException e) {
079: throw new StreamException(e);
080: }
081: }
082:
083: public HierarchicalStreamReader createReader(InputStream in) {
084: loadLibrary();
085: try {
086: return createStaxReader(createParser(in));
087: } catch (XMLStreamException e) {
088: throw new StreamException(e);
089: }
090: }
091:
092: private void loadLibrary() {
093: if (!libraryPresent) {
094: try {
095: Class.forName("javax.xml.stream.XMLStreamReader");
096: } catch (ClassNotFoundException e) {
097: throw new IllegalArgumentException(
098: "StAX API is not present. Specify another driver."
099: + " For example: new XStream(new DomDriver())");
100: }
101: libraryPresent = true;
102: }
103: }
104:
105: public HierarchicalStreamWriter createWriter(Writer out) {
106: try {
107: return createStaxWriter(getOutputFactory()
108: .createXMLStreamWriter(out));
109: } catch (XMLStreamException e) {
110: throw new StreamException(e);
111: }
112: }
113:
114: public HierarchicalStreamWriter createWriter(OutputStream out) {
115: try {
116: return createStaxWriter(getOutputFactory()
117: .createXMLStreamWriter(out));
118: } catch (XMLStreamException e) {
119: throw new StreamException(e);
120: }
121: }
122:
123: public AbstractPullReader createStaxReader(XMLStreamReader in) {
124: return new StaxReader(qnameMap, in, xmlFriendlyReplacer());
125: }
126:
127: public StaxWriter createStaxWriter(XMLStreamWriter out,
128: boolean writeStartEndDocument) throws XMLStreamException {
129: return new StaxWriter(qnameMap, out, writeStartEndDocument,
130: isRepairingNamespace(), xmlFriendlyReplacer());
131: }
132:
133: public StaxWriter createStaxWriter(XMLStreamWriter out)
134: throws XMLStreamException {
135: return createStaxWriter(out, true);
136: }
137:
138: // Properties
139: //-------------------------------------------------------------------------
140: public QNameMap getQnameMap() {
141: return qnameMap;
142: }
143:
144: public void setQnameMap(QNameMap qnameMap) {
145: this .qnameMap = qnameMap;
146: }
147:
148: public XMLInputFactory getInputFactory() {
149: if (inputFactory == null) {
150: inputFactory = XMLInputFactory.newInstance();
151: }
152: return inputFactory;
153: }
154:
155: public XMLOutputFactory getOutputFactory() {
156: if (outputFactory == null) {
157: outputFactory = XMLOutputFactory.newInstance();
158: }
159: return outputFactory;
160: }
161:
162: public boolean isRepairingNamespace() {
163: return Boolean.TRUE.equals(getOutputFactory().getProperty(
164: XMLOutputFactory.IS_REPAIRING_NAMESPACES));
165: }
166:
167: /**
168: * @since 1.2
169: */
170: public void setRepairingNamespace(boolean repairing) {
171: getOutputFactory().setProperty(
172: XMLOutputFactory.IS_REPAIRING_NAMESPACES,
173: repairing ? Boolean.TRUE : Boolean.FALSE);
174: }
175:
176: // Implementation methods
177: //-------------------------------------------------------------------------
178: protected XMLStreamReader createParser(Reader xml)
179: throws XMLStreamException {
180: return getInputFactory().createXMLStreamReader(xml);
181: }
182:
183: protected XMLStreamReader createParser(InputStream xml)
184: throws XMLStreamException {
185: return getInputFactory().createXMLStreamReader(xml);
186: }
187: }
|