001: /*
002: * $Id: ZephyrWriterFactory.java,v 1.6 2007/03/02 19:32:51 spericas Exp $
003: */
004:
005: /*
006: * The contents of this file are subject to the terms
007: * of the Common Development and Distribution License
008: * (the License). You may not use this file except in
009: * compliance with the License.
010: *
011: * You can obtain a copy of the license at
012: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
013: * See the License for the specific language governing
014: * permissions and limitations under the License.
015: *
016: * When distributing Covered Code, include this CDDL
017: * Header Notice in each file and include the License file
018: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
019: * If applicable, add the following below the CDDL Header,
020: * with the fields enclosed by brackets [] replaced by
021: * you own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * [Name of File] [ver.__] [Date]
025: *
026: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
027: */
028:
029: package com.sun.xml.stream;
030:
031: import com.sun.xml.stream.writers.XMLDOMWriterImpl;
032: import com.sun.xml.stream.writers.XMLEventWriterImpl;
033: import com.sun.xml.stream.writers.XMLStreamWriterImpl;
034:
035: import javax.xml.stream.XMLOutputFactory;
036: import javax.xml.stream.XMLStreamException;
037: import javax.xml.stream.XMLStreamWriter;
038: import javax.xml.stream.XMLEventWriter;
039: import javax.xml.transform.Result;
040: import javax.xml.transform.dom.DOMResult;
041: import javax.xml.transform.stream.StreamResult;
042: import java.io.OutputStream;
043: import java.io.Writer;
044:
045: /**
046: * This class provides the implementation of {@link XMLOutputFactory}.
047: *
048: * <p>
049: * As long as {@link #fReuseInstance} is off, this implementation
050: * is thread-safe, and the {@code create} methods can be invoked concurrently
051: * from multiple threads safely.
052: *
053: * TODO: revisit if the instance reuse really makes sense.
054: *
055: * @author Neeraj Bajaj,
056: * @author k.venugopal@sun.com
057: */
058: public class ZephyrWriterFactory extends XMLOutputFactory {
059:
060: //List of supported properties and default values.
061: private PropertyManager fPropertyManager = new PropertyManager(
062: PropertyManager.CONTEXT_WRITER);
063:
064: //cache the instance of XMLStreamWriterImpl
065: private XMLStreamWriterImpl fStreamWriter = null;
066:
067: /**
068: * TODO: at the current time, XMLStreamWriters are not Thread safe.
069: */
070: boolean fReuseInstance = false;
071:
072: public ZephyrWriterFactory() {
073: }
074:
075: public XMLEventWriter createXMLEventWriter(OutputStream outputStream)
076: throws XMLStreamException {
077: return createXMLEventWriter(outputStream, null);
078: }
079:
080: public XMLEventWriter createXMLEventWriter(
081: OutputStream outputStream, String encoding)
082: throws XMLStreamException {
083: return new XMLEventWriterImpl(createXMLStreamWriter(
084: outputStream, encoding));
085: }
086:
087: public XMLEventWriter createXMLEventWriter(Result result)
088: throws XMLStreamException {
089: return new XMLEventWriterImpl(createXMLStreamWriter(result));
090: }
091:
092: public XMLEventWriter createXMLEventWriter(Writer writer)
093: throws XMLStreamException {
094: return new XMLEventWriterImpl(createXMLStreamWriter(writer));
095: }
096:
097: public XMLStreamWriter createXMLStreamWriter(Result result)
098: throws XMLStreamException {
099:
100: if (result instanceof StreamResult) {
101: return createXMLStreamWriter((StreamResult) result, null);
102: } else if (result instanceof DOMResult) {
103: return new XMLDOMWriterImpl((DOMResult) result);
104: } else if (result instanceof Result) {
105: return createXMLStreamWriter(new StreamResult(result
106: .getSystemId()));
107: }
108: throw new java.lang.UnsupportedOperationException(
109: "result of type " + result + " is not supported");
110: }
111:
112: public XMLStreamWriter createXMLStreamWriter(Writer writer)
113: throws XMLStreamException {
114: return createXMLStreamWriter(
115: toStreamResult(null, writer, null), null);
116: }
117:
118: public XMLStreamWriter createXMLStreamWriter(
119: OutputStream outputStream) throws XMLStreamException {
120: return createXMLStreamWriter(outputStream, null);
121: }
122:
123: public XMLStreamWriter createXMLStreamWriter(
124: OutputStream outputStream, String encoding)
125: throws XMLStreamException {
126: return createXMLStreamWriter(toStreamResult(outputStream, null,
127: null), encoding);
128: }
129:
130: public Object getProperty(String name)
131: throws IllegalArgumentException {
132: if (name == null) {
133: throw new IllegalArgumentException("Property not supported");
134: }
135: if (fPropertyManager.containsProperty(name))
136: return fPropertyManager.getProperty(name);
137: throw new IllegalArgumentException("Property not supported");
138: }
139:
140: public boolean isPropertySupported(String name) {
141: if (name == null) {
142: return false;
143: } else {
144: return fPropertyManager.containsProperty(name);
145: }
146: }
147:
148: public void setProperty(String name, Object value)
149: throws IllegalArgumentException {
150: if (name == null || value == null
151: || !fPropertyManager.containsProperty(name)) {
152: throw new IllegalArgumentException("Property " + name
153: + "is not supported");
154: }
155: if (name == Constants.REUSE_INSTANCE
156: || name.equals(Constants.REUSE_INSTANCE)) {
157: fReuseInstance = ((Boolean) value).booleanValue();
158: if (DEBUG)
159: System.out.println("fReuseInstance is set to "
160: + fReuseInstance);
161:
162: // TODO: XMLStreamWriters are not Thread safe,
163: // don't let application think it is optimizing
164: if (fReuseInstance) {
165: throw new IllegalArgumentException(
166: "Property "
167: + name
168: + " is not supported: XMLStreamWriters are not Thread safe");
169: }
170: } else {//for any other property set the flag
171: //REVISIT: Even in this case instance can be reused, by passing PropertyManager
172: fPropertyChanged = true;
173: }
174: fPropertyManager.setProperty(name, value);
175: }
176:
177: private StreamResult toStreamResult(OutputStream os, Writer writer,
178: String systemId) {
179: StreamResult sr = new StreamResult();
180: sr.setOutputStream(os);
181: sr.setWriter(writer);
182: sr.setSystemId(systemId);
183: return sr;
184: }
185:
186: XMLStreamWriter createXMLStreamWriter(StreamResult sr,
187: String encoding) throws XMLStreamException {
188: //if factory is configured to reuse the instance & this instance can be reused
189: //& the setProperty() hasn't been called
190: try {
191: if (fReuseInstance && fStreamWriter != null
192: && fStreamWriter.canReuse() && !fPropertyChanged) {
193: fStreamWriter.reset();
194: fStreamWriter.setOutput(sr, encoding);
195: if (DEBUG)
196: System.out.println("reusing instance, object id : "
197: + fStreamWriter);
198: return fStreamWriter;
199: }
200: return fStreamWriter = new XMLStreamWriterImpl(sr,
201: encoding, new PropertyManager(fPropertyManager));
202: } catch (java.io.IOException io) {
203: throw new XMLStreamException(io);
204: }
205: }//createXMLStreamWriter(StreamResult,String)
206:
207: private static final boolean DEBUG = false;
208:
209: /** This flag indicates the change of property. If true,
210: * <code>PropertyManager</code> should be passed when creating
211: * <code>XMLStreamWriterImpl</code> */
212: private boolean fPropertyChanged;
213: }//ZephyrWriterFactory
|