package com.fasterxml.aalto.out;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.validation.*;
import org.codehaus.stax2.ri.Stax2WriterImpl;
import org.codehaus.stax2.ri.typed.AsciiValueEncoder;
import org.codehaus.stax2.ri.typed.ValueEncoderFactory;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import com.fasterxml.aalto.ValidationException;
import com.fasterxml.aalto.impl.ErrorConsts;
import com.fasterxml.aalto.impl.IoStreamException;
import com.fasterxml.aalto.impl.LocationImpl;
import com.fasterxml.aalto.impl.StreamExceptionBase;
import com.fasterxml.aalto.util.TextUtil;
import com.fasterxml.aalto.util.XmlConsts;
public abstract class StreamWriterBase
extends Stax2WriterImpl
implements NamespaceContext, ValidationContext
{
protected enum State { PROLOG, TREE, EPILOG };
protected final WriterConfig _config;
protected NamespaceContext _rootNsContext;
protected boolean _cfgCheckStructure;
protected boolean _cfgCheckContent;
protected boolean _cfgCheckAttrs;
protected final boolean _cfgCDataAsText;
protected WNameTable _symbols;
protected final XmlWriter _xmlWriter;
protected ValueEncoderFactory _valueEncoderFactory;
protected XMLValidator _validator = null;
protected int _vldContent = XMLValidator.CONTENT_ALLOW_ANY_TEXT;
protected ValidationProblemHandler _vldProblemHandler = null;
protected State _state = State.PROLOG;
protected OutputElement _currElem = OutputElement.createRoot();
protected boolean _stateAnyOutput = false;
protected boolean _stateStartElementOpen = false;
protected boolean _stateEmptyElement = false;
protected String _dtdRootElemName = null;
protected OutputElement _outputElemPool = null;
final static int MAX_POOL_SIZE = 8;
protected int _poolSize = 0;
protected StreamWriterBase(WriterConfig cfg, XmlWriter writer,
WNameTable symbols)
{
_config = cfg;
_xmlWriter = writer;
_symbols = symbols;
_cfgCheckStructure = cfg.willCheckStructure();
_cfgCheckContent = cfg.willCheckContent();
_cfgCheckAttrs = cfg.willCheckAttributes();
_cfgCDataAsText = false;
}
@Override
public void close() throws XMLStreamException
{
_finishDocument(false);
}
@Override
public void flush() throws XMLStreamException
{
try {
_xmlWriter.flush();
} catch (IOException ie) {
throw new IoStreamException(ie);
}
}
@Override
public final NamespaceContext getNamespaceContext() {
return this;
}
@Override
public Object getProperty(String name) {
return _config.getProperty(name, true);
}
@Override
public abstract void setDefaultNamespace(String uri)
throws XMLStreamException;
@Override
public void setNamespaceContext(NamespaceContext ctxt)
throws XMLStreamException
{
if (_state != State.PROLOG) {
throwOutputError("Called setNamespaceContext() after having already output root element.");
}
_rootNsContext = ctxt;
}
@Override
public final void setPrefix(String prefix, String uri)
throws XMLStreamException
{
if (prefix == null) {
throw new NullPointerException();
}
if (prefix.length() == 0) {
setDefaultNamespace(uri);
return;
}
if (uri == null) {
throw new NullPointerException();
}
{
if (prefix.equals("xml")) {
if (!uri.equals(XMLConstants.XML_NS_URI)) {
throwOutputError(ErrorConsts.ERR_NS_REDECL_XML, uri);
}
} else if (prefix.equals("xmlns")) {
if (!uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS, uri);
}
} else {
if (uri.equals(XMLConstants.XML_NS_URI)) {
throwOutputError(ErrorConsts.ERR_NS_REDECL_XML_URI, prefix);
} else if (uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
throwOutputError(ErrorConsts.ERR_NS_REDECL_XMLNS_URI, prefix);
}
}
if (uri.length() == 0) {
if (!_config.isXml11()) {
throwOutputError(ErrorConsts.ERR_NS_EMPTY);
}
}
}
_setPrefix(prefix, uri);
}
protected abstract void _setPrefix(String prefix, String uri);
@Override
public final void writeAttribute(String localName, String value)
throws XMLStreamException
{
if (!_stateStartElementOpen) {
throwOutputError(ErrorConsts.WERR_ATTR_NO_ELEM);
}
_writeAttribute(_symbols.findSymbol(localName), value);
}
@Override
public abstract void writeAttribute(String nsURI, String localName, String value)
throws XMLStreamException;
@Override
public abstract void writeAttribute(String prefix, String nsURI,
String localName, String value) throws XMLStreamException;
@Override
public void writeCData(String data) throws XMLStreamException
{
if (_cfgCDataAsText) {
writeCharacters(data);
return;
}
_verifyWriteCData();
if ((_vldContent == XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT)
&& (_validator != null)) {
_validator.validateText(data, false);
}
try {
int ix = _xmlWriter.writeCData(data);
if (ix >= 0) {
_reportNwfContent(ErrorConsts.WERR_CDATA_CONTENT, Integer.valueOf(ix));
}
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeCharacters(char[] text, int start, int len)
throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (inPrologOrEpilog()) {
writeSpace(text, start, len);
return;
}
if (_vldContent <= XMLValidator.CONTENT_ALLOW_WS) {
if (_vldContent == XMLValidator.CONTENT_ALLOW_NONE) {
_reportInvalidContent(CHARACTERS);
} else {
if (!TextUtil.isAllWhitespace(text, start, len, _config.isXml11())) {
_reportInvalidContent(CHARACTERS);
}
}
} else if (_vldContent == XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT) {
if (_validator != null) {
_validator.validateText(text, start, len, false);
}
}
if (len > 0) {
try {
_xmlWriter.writeCharacters(text, start, len);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
}
@Override
public void writeCharacters(String text) throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (inPrologOrEpilog()) {
writeSpace(text);
return;
}
if (_vldContent <= XMLValidator.CONTENT_ALLOW_WS) {
if (_vldContent == XMLValidator.CONTENT_ALLOW_NONE) {
_reportInvalidContent(CHARACTERS);
} else {
if (!TextUtil.isAllWhitespace(text, _config.isXml11())) {
_reportInvalidContent(CHARACTERS);
}
}
} else if (_vldContent == XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT) {
if (_validator != null) {
_validator.validateText(text, false);
}
}
try {
_xmlWriter.writeCharacters(text);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void (String data) throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (_vldContent == XMLValidator.CONTENT_ALLOW_NONE) {
_reportInvalidContent(COMMENT);
}
try {
int ix = _xmlWriter.writeComment(data);
if (ix >= 0) {
_reportNwfContent(ErrorConsts.WERR_COMMENT_CONTENT, Integer.valueOf(ix));
}
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public abstract void writeDefaultNamespace(String nsURI) throws XMLStreamException;
@Override
public final void writeDTD(String dtd) throws XMLStreamException
{
_verifyWriteDTD();
_dtdRootElemName = "";
try {
_xmlWriter.writeDTD(dtd);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeEmptyElement(String localName) throws XMLStreamException
{
_verifyStartElement(null, localName);
WName name = _symbols.findSymbol(localName);
if (_validator != null) {
_validator.validateElementStart(localName, "", "");
}
_writeStartTag(name, true);
}
@Override
public abstract void writeEmptyElement(String nsURI, String localName)
throws XMLStreamException;
@Override
public abstract void writeEmptyElement(String prefix, String localName, String nsURI)
throws XMLStreamException;
@Override
public void writeEndDocument() throws XMLStreamException {
_finishDocument(false);
}
@Override
public void writeEndElement() throws XMLStreamException
{
if (_stateStartElementOpen && _stateEmptyElement) {
_stateEmptyElement = false;
_closeStartElement(true);
}
if (_state != State.TREE) {
_reportNwfStructure("No open start element, when trying to write end element");
}
OutputElement thisElem = _currElem;
_currElem = thisElem.getParent();
if (_poolSize < MAX_POOL_SIZE) {
thisElem.addToPool(_outputElemPool);
_outputElemPool = thisElem;
++_poolSize;
}
if (_cfgCheckStructure) {
}
try {
if (_stateStartElementOpen) {
_stateStartElementOpen = false;
_xmlWriter.writeStartTagEmptyEnd();
} else {
_xmlWriter.writeEndTag(thisElem.getName());
}
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
if (_currElem.isRoot()) {
_state = State.EPILOG;
}
if (_validator != null) {
_vldContent = _validator.validateElementEnd(thisElem.getLocalName(), thisElem.getNonNullPrefix(),
thisElem.getNonNullNamespaceURI());
}
}
@Override
public void writeEntityRef(String name)
throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (_cfgCheckStructure) {
if (inPrologOrEpilog()) {
_reportNwfStructure(ErrorConsts.WERR_PROLOG_ENTITY);
}
}
if (_vldContent == XMLValidator.CONTENT_ALLOW_NONE) {
_reportInvalidContent(ENTITY_REFERENCE);
}
try {
_xmlWriter.writeEntityReference(_symbols.findSymbol(name));
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public abstract void writeNamespace(String prefix, String nsURI)
throws XMLStreamException;
@Override
public void writeProcessingInstruction(String target) throws XMLStreamException {
writeProcessingInstruction(target, null);
}
@Override
public void writeProcessingInstruction(String target, String data)
throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (_vldContent == XMLValidator.CONTENT_ALLOW_NONE) {
_reportInvalidContent(PROCESSING_INSTRUCTION);
}
try {
int ix = _xmlWriter.writePI(_symbols.findSymbol(target), data);
if (ix >= 0) {
_reportNwfContent(ErrorConsts.WERR_PI_CONTENT, Integer.valueOf(ix));
}
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeStartDocument() throws XMLStreamException
{
String enc = _config.getActualEncoding();
if (enc == null) {
enc = XmlConsts.STAX_DEFAULT_OUTPUT_ENCODING;
_config.setActualEncodingIfNotSet(enc);
}
_writeStartDocument(XmlConsts.STAX_DEFAULT_OUTPUT_VERSION, enc, null);
}
@Override
public void writeStartDocument(String version)
throws XMLStreamException
{
_writeStartDocument(version, _config.getActualEncoding(), null);
}
@Override
public void writeStartDocument(String encoding, String version)
throws XMLStreamException
{
_writeStartDocument(version, encoding, null);
}
@Override
public void writeStartElement(String localName)
throws XMLStreamException
{
_verifyStartElement(null, localName);
WName name = _symbols.findSymbol(localName);
if (_validator != null) {
_validator.validateElementStart(localName, "", "");
}
_writeStartTag(name, false);
}
@Override
public abstract void writeStartElement(String nsURI, String localName)
throws XMLStreamException;
@Override
public abstract void writeStartElement(String prefix, String localName,
String nsURI)
throws XMLStreamException;
@Override
public String getNamespaceURI(String prefix)
{
String uri = _currElem.getNamespaceURI(prefix);
if (uri == null) {
if (_rootNsContext != null) {
uri = _rootNsContext.getNamespaceURI(prefix);
}
}
return uri;
}
@Override
public String getPrefix(String uri)
{
String prefix = _currElem.getPrefix(uri);
if (prefix == null) {
if (_rootNsContext != null) {
prefix = _rootNsContext.getPrefix(uri);
}
}
return prefix;
}
@Override
public Iterator<String> getPrefixes(String uri)
{
return _currElem.getPrefixes(uri, _rootNsContext);
}
@Override
public void writeBoolean(boolean b)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getScalarEncoder(b ? "true" : "false"));
}
@Override
public void writeInt(int value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value));
}
@Override
public void writeLong(long value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value));
}
@Override
public void writeFloat(float value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value));
}
@Override
public void writeDouble(double value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value));
}
@Override
public void writeInteger(BigInteger value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
}
@Override
public void writeDecimal(BigDecimal value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getScalarEncoder(value.toString()));
}
@Override
public void writeQName(QName value)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getScalarEncoder(_serializeQName(value)));
}
@Override
public final void writeIntArray(int[] value, int from, int length)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
}
@Override
public void writeLongArray(long[] value, int from, int length)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
}
@Override
public void writeFloatArray(float[] value, int from, int length)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
}
@Override
public void writeDoubleArray(double[] value, int from, int length)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(value, from, length));
}
@Override
public void writeBinary(byte[] value, int from, int length)
throws XMLStreamException
{
Base64Variant v = Base64Variants.getDefaultVariant();
writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
}
@Override
public void writeBinary(Base64Variant v, byte[] value, int from, int length)
throws XMLStreamException
{
writeTypedElement(valueEncoderFactory().getEncoder(v, value, from, length));
}
private final void writeTypedElement(AsciiValueEncoder enc)
throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
try {
_xmlWriter.writeTypedValue(enc);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public final void writeBooleanAttribute(String prefix, String nsURI, String localName, boolean value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value));
}
@Override
public final void writeIntAttribute(String prefix, String nsURI, String localName, int value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value));
}
@Override
public final void writeLongAttribute(String prefix, String nsURI, String localName, long value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value));
}
@Override
public final void writeFloatAttribute(String prefix, String nsURI, String localName, float value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value));
}
@Override
public final void writeDoubleAttribute(String prefix, String nsURI, String localName, double value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value));
}
@Override
public final void writeIntegerAttribute(String prefix, String nsURI, String localName, BigInteger value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getScalarEncoder(value.toString()));
}
@Override
public final void writeDecimalAttribute(String prefix, String nsURI, String localName, BigDecimal value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getScalarEncoder(value.toString()));
}
@Override
public final void writeQNameAttribute(String prefix, String nsURI, String localName, QName value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, _serializeQName(value));
}
@Override
public void writeIntArrayAttribute(String prefix, String nsURI, String localName, int[] value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value, 0, value.length));
}
@Override
public void writeLongArrayAttribute(String prefix, String nsURI, String localName, long[] value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value, 0, value.length));
}
@Override
public void writeFloatArrayAttribute(String prefix, String nsURI, String localName, float[] value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value, 0, value.length));
}
@Override
public void writeDoubleArrayAttribute(String prefix, String nsURI, String localName, double[] value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(value, 0, value.length));
}
@Override
public void writeBinaryAttribute(String prefix, String nsURI, String localName, byte[] value)
throws XMLStreamException
{
Base64Variant v = Base64Variants.getDefaultVariant();
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(v, value, 0, value.length));
}
@Override
public void writeBinaryAttribute(Base64Variant v, String prefix, String nsURI, String localName, byte[] value)
throws XMLStreamException
{
writeTypedAttribute(prefix, nsURI, localName,
valueEncoderFactory().getEncoder(v, value, 0, value.length));
}
public abstract void writeTypedAttribute(String prefix, String nsURI, String localName,
AsciiValueEncoder enc)
throws XMLStreamException;
protected abstract String _serializeQName(QName name)
throws XMLStreamException;
@Override
public void writeSpace(String text) throws XMLStreamException
{
try {
_xmlWriter.writeSpace(text);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeSpace(char[] cbuf, int offset, int len) throws XMLStreamException
{
try {
_xmlWriter.writeSpace(cbuf, offset, len);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void closeCompletely() throws XMLStreamException
{
_finishDocument(true);
}
@Override
public boolean isPropertySupported(String name) {
return _config.isPropertySupported(name);
}
@Override
public boolean setProperty(String name, Object value)
{
return _config.setProperty(name, value);
}
@Override
public XMLValidator validateAgainst(XMLValidationSchema schema) throws XMLStreamException
{
XMLValidator vld = schema.createValidator(this);
if (_validator == null) {
_cfgCheckStructure = true;
_cfgCheckAttrs = true;
_validator = vld;
} else {
_validator = new ValidatorPair(_validator, vld);
}
return vld;
}
@Override
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema) throws XMLStreamException
{
XMLValidator[] results = new XMLValidator[2];
XMLValidator found = null;
if (ValidatorPair.removeValidator(_validator, schema, results)) {
found = results[0];
_validator = results[1];
found.validationCompleted(false);
if (_validator == null) {
resetValidationFlags();
}
}
return found;
}
@Override
public XMLValidator stopValidatingAgainst(XMLValidator validator) throws XMLStreamException
{
XMLValidator[] results = new XMLValidator[2];
XMLValidator found = null;
if (ValidatorPair.removeValidator(_validator, validator, results)) {
found = results[0];
_validator = results[1];
found.validationCompleted(false);
if (_validator == null) {
resetValidationFlags();
}
}
return found;
}
@Override
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
ValidationProblemHandler oldH = _vldProblemHandler;
_vldProblemHandler = h;
return oldH;
}
private void resetValidationFlags()
{
_cfgCheckStructure = _config.willCheckStructure();
_cfgCheckAttrs = _config.willCheckAttributes();
}
@Override
public XMLStreamLocation2 getLocation()
{
return new LocationImpl(null, null,
_xmlWriter.getAbsOffset(), _xmlWriter.getRow(), _xmlWriter.getColumn());
}
@Override
public String getEncoding() {
return _config.getActualEncoding();
}
@Override
public void writeCData(char[] cbuf, int start, int len)
throws XMLStreamException
{
if (_cfgCDataAsText) {
writeCharacters(cbuf, start, len);
return;
}
_verifyWriteCData();
int ix;
try {
ix = _xmlWriter.writeCData(cbuf, start, len);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
if (ix >= 0) {
_reportNwfContent(ErrorConsts.WERR_CDATA_CONTENT, Integer.valueOf(ix));
}
}
public void writeDTD(DTDInfo info)
throws XMLStreamException
{
writeDTD(info.getDTDRootName(),
info.getDTDSystemId(),
info.getDTDPublicId(), info.getDTDInternalSubset());
}
@Override
public void writeDTD(String rootName, String systemId, String publicId,
String internalSubset)
throws XMLStreamException
{
_verifyWriteDTD();
_dtdRootElemName = rootName;
try {
_xmlWriter.writeDTD(_symbols.findSymbol(rootName), systemId, publicId, internalSubset);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeFullEndElement() throws XMLStreamException
{
if (_stateStartElementOpen && _stateEmptyElement) {
_stateEmptyElement = false;
_closeStartElement(true);
}
writeEndElement();
}
@Override
public void writeStartDocument(String version, String encoding,
boolean standAlone)
throws XMLStreamException
{
_writeStartDocument(version, encoding, standAlone ? "yes" : "no");
}
@Override
public void writeRaw(String text) throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
try {
_xmlWriter.writeRaw(text, 0, text.length());
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeRaw(String text, int start, int offset) throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
try {
_xmlWriter.writeRaw(text, start, offset);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public void writeRaw(char[] text, int offset, int length) throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
try {
_xmlWriter.writeRaw(text, offset, length);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
@Override
public String getXmlVersion() {
return _config.isXml11() ? "1.1" : "1.0";
}
@Override
public QName getCurrentElementName() {
return _currElem.getQName();
}
@Override
public String getBaseUri() {
return null;
}
@Override
public Location getValidationLocation() {
return getLocation();
}
@Override
public void reportProblem(XMLValidationProblem prob) throws XMLStreamException
{
if (_vldProblemHandler != null) {
_vldProblemHandler.reportProblem(prob);
return;
}
if (prob.getSeverity() >= XMLValidationProblem.SEVERITY_ERROR) {
throw ValidationException.create(prob);
}
}
@Override
public int addDefaultAttribute(String localName, String uri, String prefix,
String value)
{
return -1;
}
@Override
public boolean isNotationDeclared(String name) { return false; }
@Override
public boolean isUnparsedEntityDeclared(String name) { return false; }
@Override
public int getAttributeCount() { return 0; }
@Override
public String getAttributeLocalName(int index) { return null; }
@Override
public String getAttributeNamespace(int index) { return null; }
@Override
public String getAttributePrefix(int index) { return null; }
@Override
public String getAttributeValue(int index) { return null; }
@Override
public String getAttributeValue(String nsURI, String localName) {
return null;
}
@Override
public String getAttributeType(int index) {
return "";
}
@Override
public int findAttributeIndex(String nsURI, String localName) {
return -1;
}
protected void _closeStartElement(boolean emptyElem)
throws XMLStreamException
{
_stateStartElementOpen = false;
try {
if (emptyElem) {
_xmlWriter.writeStartTagEmptyEnd();
} else {
_xmlWriter.writeStartTagEnd();
}
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
if (emptyElem) {
OutputElement thisElem = _currElem;
_currElem = thisElem.getParent();
if (_currElem.isRoot()) {
_state = State.EPILOG;
}
if (_poolSize < MAX_POOL_SIZE) {
thisElem.addToPool(_outputElemPool);
_outputElemPool = thisElem;
++_poolSize;
}
}
}
protected final boolean inPrologOrEpilog() {
return (_state != State.TREE);
}
protected final ValueEncoderFactory valueEncoderFactory()
{
if (_valueEncoderFactory == null) {
_valueEncoderFactory = new ValueEncoderFactory();
}
return _valueEncoderFactory;
}
protected final void _writeAttribute(WName name, String value)
throws XMLStreamException
{
if (_cfgCheckAttrs) {
_verifyWriteAttr(name);
}
try {
_xmlWriter.writeAttribute(name, value);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
protected final void _writeAttribute(WName name, AsciiValueEncoder enc)
throws XMLStreamException
{
if (_cfgCheckAttrs) {
_verifyWriteAttr(name);
}
try {
_xmlWriter.writeAttribute(name, enc);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
protected final void _writeDefaultNamespace(String uri)
throws XMLStreamException
{
WName name = _symbols.findSymbol("xmlns");
try {
_xmlWriter.writeAttribute(name, uri);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
protected final void _writeNamespace(String prefix, String uri)
throws XMLStreamException
{
WName name = _symbols.findSymbol("xmlns", prefix);
try {
_xmlWriter.writeAttribute(name, uri);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
protected void _writeStartDocument(String version, String encoding,
String standAlone)
throws XMLStreamException
{
if (_cfgCheckStructure) {
if (_stateAnyOutput) {
_reportNwfStructure(ErrorConsts.WERR_DUP_XML_DECL);
}
}
_stateAnyOutput = true;
if (_cfgCheckContent) {
if (version != null && version.length() > 0) {
if (!(version.equals(XmlConsts.XML_V_10_STR)
|| version.equals(XmlConsts.XML_V_11_STR))) {
_reportNwfContent("Illegal version argument ('"+version
+"'); should only use '"+XmlConsts.XML_V_10_STR
+"' or '"+XmlConsts.XML_V_11_STR+"'");
}
}
}
if (version == null || version.length() == 0) {
version = XmlConsts.STAX_DEFAULT_OUTPUT_VERSION;
}
if (XmlConsts.XML_V_11_STR.equals(version)) {
_config.enableXml11();
_xmlWriter.enableXml11();
}
if (encoding != null && encoding.length() > 0) {
_config.setActualEncodingIfNotSet(encoding);
}
try {
_xmlWriter.writeXmlDeclaration(version, encoding, standAlone);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
}
protected void _writeStartTag(WName name, boolean isEmpty)
throws XMLStreamException
{
_stateAnyOutput = true;
_stateStartElementOpen = true;
if (_outputElemPool != null) {
OutputElement newCurr = _outputElemPool;
_outputElemPool = newCurr.reuseAsChild(_currElem, name);
--_poolSize;
_currElem = newCurr;
} else {
_currElem = _currElem.createChild(name);
}
try {
_xmlWriter.writeStartTagStart(name);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
_stateEmptyElement = isEmpty;
}
protected void _writeStartTag(WName name, boolean isEmpty, String uri)
throws XMLStreamException
{
_stateAnyOutput = true;
_stateStartElementOpen = true;
if (uri == null) {
uri = "";
}
if (_outputElemPool != null) {
OutputElement newCurr = _outputElemPool;
_outputElemPool = newCurr.reuseAsChild(_currElem, name, uri);
--_poolSize;
_currElem = newCurr;
} else {
_currElem = _currElem.createChild(name, uri);
}
try {
_xmlWriter.writeStartTagStart(name);
} catch (IOException ioe) {
throw new IoStreamException(ioe);
}
_stateEmptyElement = isEmpty;
}
protected final void _verifyWriteAttr(WName name)
{
}
protected void _verifyStartElement(String prefix, String localName)
throws XMLStreamException
{
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
} else if (_state == State.PROLOG) {
_verifyRootElement(prefix, localName);
} else if (_state == State.EPILOG) {
if (_cfgCheckStructure) {
String name = (prefix == null) ? localName : (prefix+":"+localName);
_reportNwfStructure(ErrorConsts.WERR_PROLOG_SECOND_ROOT, name);
}
_state = State.TREE;
}
}
protected final void _verifyWriteCData()
throws XMLStreamException
{
_stateAnyOutput = true;
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
if (_cfgCheckStructure) {
if (inPrologOrEpilog()) {
_reportNwfStructure(ErrorConsts.WERR_PROLOG_CDATA);
}
}
}
protected final void _verifyWriteDTD()
throws XMLStreamException
{
if (_cfgCheckStructure) {
if (_state != State.PROLOG) {
throw new XMLStreamException("Can not write DOCTYPE declaration (DTD) when not in prolog any more (state "+_state+"; start element(s) written)");
}
if (_dtdRootElemName != null) {
throw new XMLStreamException("Trying to write multiple DOCTYPE declarations");
}
}
}
protected void _verifyRootElement(String prefix, String localName)
throws XMLValidationException
{
_state = State.TREE;
}
protected static void throwOutputError(String msg)
throws XMLStreamException
{
throw new StreamExceptionBase(msg);
}
protected static void throwOutputError(String format, Object arg)
throws XMLStreamException
{
String msg = MessageFormat.format(format, new Object[] { arg });
throwOutputError(msg);
}
protected static void reportIllegalMethod(String msg)
throws XMLStreamException
{
throwOutputError(msg);
}
protected static void _reportNwfStructure(String msg)
throws XMLStreamException
{
throwOutputError(msg);
}
protected static void _reportNwfStructure(String msg, Object arg)
throws XMLStreamException
{
throwOutputError(msg, arg);
}
protected static void _reportNwfContent(String msg)
throws XMLStreamException
{
throwOutputError(msg);
}
protected static void _reportNwfContent(String msg, Object arg)
throws XMLStreamException
{
throwOutputError(msg, arg);
}
protected static void _reportNwfAttr(String msg)
throws XMLStreamException
{
throwOutputError(msg);
}
protected static void _reportNwfAttr(String msg, Object arg)
throws XMLStreamException
{
throwOutputError(msg, arg);
}
protected static void _reportNwfName(String msg)
throws XMLStreamException
{
throwOutputError(msg);
}
protected static void throwFromIOE(IOException ioe)
throws XMLStreamException
{
throw new IoStreamException(ioe);
}
protected static void reportIllegalArg(String msg)
throws IllegalArgumentException
{
throw new IllegalArgumentException(msg);
}
protected void _reportInvalidContent(int evtType)
throws XMLStreamException
{
switch (_vldContent) {
case XMLValidator.CONTENT_ALLOW_NONE:
_reportValidationProblem(MessageFormat.format
(ErrorConsts.VERR_EMPTY, _currElem.getNameDesc(), ErrorConsts.tokenTypeDesc(evtType)));
break;
case XMLValidator.CONTENT_ALLOW_WS:
_reportValidationProblem(MessageFormat.format
(ErrorConsts.VERR_NON_MIXED, _currElem.getNameDesc()));
break;
case XMLValidator.CONTENT_ALLOW_VALIDATABLE_TEXT:
case XMLValidator.CONTENT_ALLOW_ANY_TEXT:
_reportValidationProblem(MessageFormat.format
(ErrorConsts.VERR_ANY, _currElem.getNameDesc(), ErrorConsts.tokenTypeDesc(evtType)));
break;
default:
_reportValidationProblem("Internal error: trying to report invalid content for "+evtType);
}
}
public void _reportValidationProblem(String msg) throws XMLStreamException
{
reportProblem(new XMLValidationProblem(getValidationLocation(),
msg,
XMLValidationProblem.SEVERITY_ERROR));
}
private final void _finishDocument(boolean forceRealClose)
throws XMLStreamException
{
if (_state != State.EPILOG) {
if (_cfgCheckStructure && _state == State.PROLOG) {
_reportNwfStructure(ErrorConsts.WERR_PROLOG_NO_ROOT);
}
if (_stateStartElementOpen) {
_closeStartElement(_stateEmptyElement);
}
while (_state != State.EPILOG) {
writeEndElement();
}
}
if (_symbols.maybeDirty()) {
_symbols.mergeToParent();
}
try {
_xmlWriter.close(forceRealClose);
} catch (IOException ie) {
throw new IoStreamException(ie);
}
}
@Override
public String toString()
{
return "[StreamWriter: "+getClass()+", underlying outputter: "
+((_xmlWriter == null) ? "NULL" : _xmlWriter.toString());
}
}