package com.fasterxml.aalto.stax;
import java.io.*;
import javax.xml.stream.*;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import org.codehaus.stax2.XMLOutputFactory2;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.io.Stax2Result;
import org.codehaus.stax2.ri.Stax2EventWriterImpl;
import org.codehaus.stax2.ri.Stax2WriterAdapter;
import com.fasterxml.aalto.dom.DOMWriterImpl;
import com.fasterxml.aalto.impl.IoStreamException;
import com.fasterxml.aalto.impl.StreamExceptionBase;
import com.fasterxml.aalto.out.*;
import com.fasterxml.aalto.util.CharsetNames;
import com.fasterxml.aalto.util.URLUtil;
import com.fasterxml.aalto.util.XmlConsts;
public final class OutputFactoryImpl
extends XMLOutputFactory2
{
protected final WriterConfig _config;
public OutputFactoryImpl() {
_config = new WriterConfig();
}
@Override
public XMLEventWriter createXMLEventWriter(OutputStream out)
throws XMLStreamException
{
return createXMLEventWriter(out, null);
}
@Override
public XMLEventWriter createXMLEventWriter(OutputStream out, String enc)
throws XMLStreamException
{
return new Stax2EventWriterImpl(createSW(out, null, enc, false));
}
@Override
public XMLEventWriter createXMLEventWriter(javax.xml.transform.Result result)
throws XMLStreamException
{
return new Stax2EventWriterImpl(createSW(result));
}
@Override
public XMLEventWriter createXMLEventWriter(Writer w)
throws XMLStreamException
{
return new Stax2EventWriterImpl(createSW(null, w, null, false));
}
@Override
public XMLStreamWriter createXMLStreamWriter(OutputStream out)
throws XMLStreamException
{
return createXMLStreamWriter(out, null);
}
@Override
public XMLStreamWriter createXMLStreamWriter(OutputStream out, String enc)
throws XMLStreamException
{
return createSW(out, null, enc, false);
}
@Override
public XMLStreamWriter createXMLStreamWriter(javax.xml.transform.Result result)
throws XMLStreamException
{
return createSW(result);
}
@Override
public XMLStreamWriter createXMLStreamWriter(Writer w)
throws XMLStreamException
{
return createSW(null, w, null, false);
}
@Override
public Object getProperty(String name)
{
return _config.getProperty(name, true);
}
@Override
public boolean isPropertySupported(String name) {
return _config.isPropertySupported(name);
}
@Override
public void setProperty(String name, Object value)
{
_config.setProperty(name, value);
}
@Override
public XMLEventWriter createXMLEventWriter(Writer w, String enc)
throws XMLStreamException
{
return new Stax2EventWriterImpl(createSW(null, w, enc, false));
}
@Override
public XMLEventWriter createXMLEventWriter(XMLStreamWriter sw)
throws XMLStreamException
{
XMLStreamWriter2 sw2 = Stax2WriterAdapter.wrapIfNecessary(sw);
return new Stax2EventWriterImpl(sw2);
}
@Override
public XMLStreamWriter2 createXMLStreamWriter(Writer w, String enc)
throws XMLStreamException
{
return createSW(null, w, enc, false);
}
@Override
public void configureForXmlConformance()
{
_config.configureForXmlConformance();
}
@Override
public void configureForRobustness()
{
_config.configureForRobustness();
}
@Override
public void configureForSpeed()
{
_config.configureForSpeed();
}
private XMLStreamWriter2 createSW(OutputStream out, Writer w, String enc,
boolean forceAutoClose)
throws XMLStreamException
{
WriterConfig cfg = _config.createNonShared();
if (forceAutoClose) {
cfg.doAutoCloseOutput(true);
}
XmlWriter xw;
WNameTable symbols;
if (w == null) {
if (enc == null) {
enc = XmlConsts.STAX_DEFAULT_OUTPUT_ENCODING;
} else {
if (enc != CharsetNames.CS_UTF8
&& enc != CharsetNames.CS_ISO_LATIN1
&& enc != CharsetNames.CS_US_ASCII) {
enc = CharsetNames.normalize(enc);
}
}
cfg.setActualEncodingIfNotSet(enc);
try {
if (enc == CharsetNames.CS_UTF8) {
xw = new Utf8XmlWriter(cfg, out);
symbols = _config.getUtf8Symbols(xw);
} else if (enc == CharsetNames.CS_ISO_LATIN1) {
xw = new Latin1XmlWriter(cfg, out);
symbols = _config.getLatin1Symbols(xw);
} else if (enc == CharsetNames.CS_US_ASCII) {
xw = new AsciiXmlWriter(cfg, out);
symbols = _config.getAsciiSymbols(xw);
} else {
w = new OutputStreamWriter(out, enc);
xw = new CharXmlWriter(cfg, w);
symbols = _config.getCharSymbols(xw);
}
} catch (IOException ioe) {
throw new XMLStreamException(ioe);
}
} else {
if (enc == null) {
enc = CharsetNames.findEncodingFor(w);
}
if (enc != null) {
cfg.setActualEncodingIfNotSet(enc);
}
xw = new CharXmlWriter(cfg, w);
symbols = _config.getCharSymbols(xw);
}
if (cfg.willRepairNamespaces()) {
return new RepairingStreamWriter(cfg, xw, symbols);
}
return new NonRepairingStreamWriter(cfg, xw, symbols);
}
private XMLStreamWriter2 createSW(Result res) throws XMLStreamException
{
OutputStream out = null;
Writer w = null;
String encoding = null;
boolean autoclose;
String sysId = null;
if (res instanceof Stax2Result) {
Stax2Result sr = (Stax2Result) res;
try {
out = sr.constructOutputStream();
if (out == null) {
w = sr.constructWriter();
}
} catch (IOException ioe) {
throw new StreamExceptionBase(ioe);
}
autoclose = true;
} else if (res instanceof StreamResult) {
StreamResult sr = (StreamResult) res;
sysId = sr.getSystemId();
out = sr.getOutputStream();
if (out == null) {
w = sr.getWriter();
}
autoclose = false;
} else if (res instanceof SAXResult) {
SAXResult sr = (SAXResult) res;
sysId = sr.getSystemId();
if (sysId == null || sysId.length() == 0) {
throw new StreamExceptionBase("Can not create a stream writer for a SAXResult that does not have System Id (support for using SAX input source not implemented)");
}
autoclose = true;
} else if (res instanceof DOMResult) {
return DOMWriterImpl.createFrom(_config.createNonShared(), (DOMResult) res);
} else {
throw new IllegalArgumentException("Can not create XMLStreamWriter for Result type "+res.getClass()+" (unrecognized type)");
}
if (out != null) {
return createSW(out, null, encoding, autoclose);
}
if (w != null) {
return createSW(null, w, encoding, autoclose);
}
if (sysId != null && sysId.length() > 0) {
autoclose = true;
try {
out = URLUtil.outputStreamFromURL(URLUtil.urlFromSystemId(sysId));
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
return createSW(out, null, encoding, autoclose);
}
throw new StreamExceptionBase("Can not create XMLStreamWriter for passed-in Result -- neither writer, output stream nor system id (to create one) was accessible");
}
}