com.ctc.wstx.api.WriterConfig Maven / Gradle / Ivy
Go to download
Woodstox is a high-performance XML processor that
implements Stax (JSR-173) and SAX2 APIs
package com.ctc.wstx.api;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import javax.xml.stream.*;
import org.codehaus.stax2.XMLOutputFactory2; // for property consts
import org.codehaus.stax2.XMLStreamProperties;
import org.codehaus.stax2.io.EscapingWriterFactory;
import com.ctc.wstx.api.WstxOutputProperties;
import com.ctc.wstx.cfg.OutputConfigFlags;
import com.ctc.wstx.io.BufferRecycler;
import com.ctc.wstx.util.ArgUtil;
import com.ctc.wstx.util.DataUtil;
/**
* Simple configuration container class; passed by reader factory to reader
* instance created.
*/
public final class WriterConfig
extends CommonConfig
implements OutputConfigFlags
{
// // // Constants for standard Stax properties:
protected final static String DEFAULT_AUTOMATIC_NS_PREFIX = "wstxns";
// // // First, standard Stax writer properties
final static int PROP_AUTOMATIC_NS = 1; // standard property ("repairing")
// // // And then additional Stax2 properties:
// General output settings
final static int PROP_AUTOMATIC_EMPTY_ELEMENTS = 2;
final static int PROP_AUTO_CLOSE_OUTPUT = 3;
// Namespace settings:
final static int PROP_ENABLE_NS = 4;
final static int PROP_AUTOMATIC_NS_PREFIX = 5;
// Escaping text content/attr values:
final static int PROP_TEXT_ESCAPER = 6;
final static int PROP_ATTR_VALUE_ESCAPER = 7;
// Problem checking/reporting options
final static int PROP_PROBLEM_REPORTER = 8;
// // // And then custom Wstx properties:
// Output settings:
final static int PROP_OUTPUT_CDATA_AS_TEXT = 11;
final static int PROP_COPY_DEFAULT_ATTRS = 12;
final static int PROP_ESCAPE_CR = 13;
final static int PROP_ADD_SPACE_AFTER_EMPTY_ELEM = 14;
final static int PROP_AUTOMATIC_END_ELEMENTS = 15;
// Validation flags:
final static int PROP_VALIDATE_STRUCTURE = 16;
final static int PROP_VALIDATE_CONTENT = 17;
final static int PROP_VALIDATE_ATTR = 18;
final static int PROP_VALIDATE_NAMES = 19;
final static int PROP_FIX_CONTENT = 20;
// Other:
final static int PROP_OUTPUT_INVALID_CHAR_HANDLER = 21;
final static int PROP_OUTPUT_EMPTY_ELEMENT_HANDLER = 22;
// Per-writer instance information
final static int PROP_UNDERLYING_STREAM = 30;
final static int PROP_UNDERLYING_WRITER = 31;
// // // Default settings for additional properties:
final static boolean DEFAULT_OUTPUT_CDATA_AS_TEXT = false;
final static boolean DEFAULT_COPY_DEFAULT_ATTRS = false;
/* 26-Dec-2006, TSa: Since CRs have been auto-escaped so far, let's
* retain the defaults when adding new properties/features.
*/
final static boolean DEFAULT_ESCAPE_CR = true;
/**
* 09-Aug-2007, TSa: Space has always been added after empty
* element (before closing "/>"), but now it is configurable.
* 31-Dec-2009, TSa: Intention was to leave it enabled for backwards
* compatibility: but due to a bug this was NOT the case... ugh.
*/
final static boolean DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM = false;
/* How about validation? Let's turn them mostly off by default, since
* there are some performance hits when enabling them.
*/
// Structural checks are easy, cheap and useful...
final static boolean DEFAULT_VALIDATE_STRUCTURE = true;
/* 17-May-2006, TSa: Since content validation is now much cheaper
* (due to integrated transcoders) than it used to be, let's
* just enable content validation too.
*/
final static boolean DEFAULT_VALIDATE_CONTENT = true;
final static boolean DEFAULT_VALIDATE_ATTR = false;
final static boolean DEFAULT_VALIDATE_NAMES = false;
// This only matters if content validation is enabled...
/**
* As per [WSTX-120], default was changed to false,
* from true (default prior to wstx 4.0)
*/
//final static boolean DEFAULT_FIX_CONTENT = true;
final static boolean DEFAULT_FIX_CONTENT = false;
/**
* Default config flags are converted from individual settings,
* to conform to Stax 1.0 specifications.
*/
final static int DEFAULT_FLAGS_J2ME =
0
// Stax 1.0 mandated:
// namespace-awareness assumed; repairing disabled by default:
// | CFG_AUTOMATIC_NS
| CFG_ENABLE_NS
// Usually it's good to allow writer to produce empty elems
// (note: default for woodstox 1.x was false)
| CFG_AUTOMATIC_EMPTY_ELEMENTS
| (DEFAULT_OUTPUT_CDATA_AS_TEXT ? CFG_OUTPUT_CDATA_AS_TEXT : 0)
| (DEFAULT_COPY_DEFAULT_ATTRS ? CFG_COPY_DEFAULT_ATTRS : 0)
| (DEFAULT_ESCAPE_CR ? CFG_ESCAPE_CR : 0)
| (DEFAULT_ADD_SPACE_AFTER_EMPTY_ELEM ? CFG_ADD_SPACE_AFTER_EMPTY_ELEM : 0)
| CFG_AUTOMATIC_END_ELEMENTS
| (DEFAULT_VALIDATE_STRUCTURE ? CFG_VALIDATE_STRUCTURE : 0)
| (DEFAULT_VALIDATE_CONTENT ? CFG_VALIDATE_CONTENT : 0)
| (DEFAULT_VALIDATE_ATTR ? CFG_VALIDATE_ATTR : 0)
| (DEFAULT_VALIDATE_NAMES ? CFG_VALIDATE_NAMES : 0)
| (DEFAULT_FIX_CONTENT ? CFG_FIX_CONTENT : 0)
// As per Stax 1.0 specs, we can not enable this by default:
//| CFG_AUTO_CLOSE_INPUT);
;
/**
* For now, full instances start with same settings as J2ME subset
*/
final static int DEFAULT_FLAGS_FULL = DEFAULT_FLAGS_J2ME;
// // //
/**
* Map to use for converting from String property ids to ints
* described above; useful to allow use of switch later on.
*/
final static HashMap sProperties = new HashMap(8);
static {
// // Stax (1.0) standard ones:
sProperties.put(XMLOutputFactory.IS_REPAIRING_NAMESPACES,
DataUtil.Integer(PROP_AUTOMATIC_NS));
// // Stax2 standard ones:
// Namespace support
sProperties.put(XMLStreamProperties.XSP_NAMESPACE_AWARE,
DataUtil.Integer(PROP_ENABLE_NS));
// Generic output
sProperties.put(XMLOutputFactory2.P_AUTOMATIC_EMPTY_ELEMENTS,
DataUtil.Integer(PROP_AUTOMATIC_EMPTY_ELEMENTS));
sProperties.put(XMLOutputFactory2.P_AUTO_CLOSE_OUTPUT,
DataUtil.Integer(PROP_AUTO_CLOSE_OUTPUT));
// Namespace support
sProperties.put(XMLOutputFactory2.P_AUTOMATIC_NS_PREFIX,
DataUtil.Integer(PROP_AUTOMATIC_NS_PREFIX));
// Text/attr value escaping (customized escapers)
sProperties.put(XMLOutputFactory2.P_TEXT_ESCAPER,
DataUtil.Integer(PROP_TEXT_ESCAPER));
sProperties.put(XMLOutputFactory2.P_ATTR_VALUE_ESCAPER,
DataUtil.Integer(PROP_ATTR_VALUE_ESCAPER));
// Problem checking/reporting options
sProperties.put(XMLStreamProperties.XSP_PROBLEM_REPORTER,
DataUtil.Integer(PROP_PROBLEM_REPORTER));
// // Woodstox-specifics:
// Output conversions
sProperties.put(WstxOutputProperties.P_OUTPUT_CDATA_AS_TEXT,
DataUtil.Integer(PROP_OUTPUT_CDATA_AS_TEXT));
sProperties.put(WstxOutputProperties.P_COPY_DEFAULT_ATTRS,
DataUtil.Integer(PROP_COPY_DEFAULT_ATTRS));
sProperties.put(WstxOutputProperties.P_OUTPUT_ESCAPE_CR,
DataUtil.Integer(PROP_ESCAPE_CR));
sProperties.put(WstxOutputProperties.P_ADD_SPACE_AFTER_EMPTY_ELEM
,
DataUtil.Integer(PROP_ADD_SPACE_AFTER_EMPTY_ELEM));
sProperties.put(WstxOutputProperties.P_AUTOMATIC_END_ELEMENTS,
DataUtil.Integer(PROP_AUTOMATIC_END_ELEMENTS));
sProperties.put(WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER,
DataUtil.Integer(PROP_OUTPUT_INVALID_CHAR_HANDLER));
sProperties.put(WstxOutputProperties.P_OUTPUT_EMPTY_ELEMENT_HANDLER,
DataUtil.Integer(PROP_OUTPUT_EMPTY_ELEMENT_HANDLER));
// Validation settings:
sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_STRUCTURE,
DataUtil.Integer(PROP_VALIDATE_STRUCTURE));
sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_CONTENT,
DataUtil.Integer(PROP_VALIDATE_CONTENT));
sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_ATTR,
DataUtil.Integer(PROP_VALIDATE_ATTR));
sProperties.put(WstxOutputProperties.P_OUTPUT_VALIDATE_NAMES,
DataUtil.Integer(PROP_VALIDATE_NAMES));
sProperties.put(WstxOutputProperties.P_OUTPUT_FIX_CONTENT,
DataUtil.Integer(PROP_FIX_CONTENT));
// Underlying stream/writer access
sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
DataUtil.Integer(PROP_UNDERLYING_STREAM));
sProperties.put(WstxOutputProperties.P_OUTPUT_UNDERLYING_STREAM,
DataUtil.Integer(PROP_UNDERLYING_STREAM));
}
/*
//////////////////////////////////////////////////////////
// Current config state:
//////////////////////////////////////////////////////////
*/
final boolean mIsJ2MESubset;
protected int mConfigFlags;
/*
//////////////////////////////////////////////////////////
// More special(ized) configuration objects
//////////////////////////////////////////////////////////
*/
//protected String mAutoNsPrefix;
//protected EscapingWriterFactory mTextEscaperFactory = null;
//protected EscapingWriterFactory mAttrValueEscaperFactory = null;
//protected XMLReporter mProblemReporter = null;
//protected InvalidCharHandler mInvalidCharHandler = null;
Object[] mSpecialProperties = null;
private final static int SPEC_PROC_COUNT = 6;
private final static int SP_IX_AUTO_NS_PREFIX = 0;
private final static int SP_IX_TEXT_ESCAPER_FACTORY = 1;
private final static int SP_IX_ATTR_VALUE_ESCAPER_FACTORY = 2;
private final static int SP_IX_PROBLEM_REPORTER = 3;
private final static int SP_IX_INVALID_CHAR_HANDLER = 4;
private final static int SP_IX_EMPTY_ELEMENT_HANDLER = 5;
/*
//////////////////////////////////////////////////////////
// Buffer recycling:
//////////////////////////////////////////////////////////
*/
/**
* This ThreadLocal
contains a {@link SoftRerefence}
* to a {@link BufferRecycler} used to provide a low-cost
* buffer recycling between Reader instances.
*/
final static ThreadLocal mRecyclerRef = new ThreadLocal();
/**
* This is the actually container of the recyclable buffers. It
* is obtained via ThreadLocal/SoftReference combination, if one
* exists, when Config instance is created. If one does not
* exists, it will created first time a buffer is returned.
*/
BufferRecycler mCurrRecycler = null;
/*
//////////////////////////////////////////////////////////
// Life-cycle:
//////////////////////////////////////////////////////////
*/
private WriterConfig(boolean j2meSubset, int flags, Object[] specProps)
{
mIsJ2MESubset = j2meSubset;
mConfigFlags = flags;
mSpecialProperties = specProps;
/* Ok, let's then see if we can find a buffer recycler. Since they
* are lazily constructed, and since GC may just flush them out
* on its whims, it's possible we might not find one. That's ok;
* we can reconstruct one if and when we are to return one or more
* buffers.
*/
SoftReference ref = (SoftReference) mRecyclerRef.get();
if (ref != null) {
mCurrRecycler = (BufferRecycler) ref.get();
}
}
public static WriterConfig createJ2MEDefaults()
{
return new WriterConfig(true, DEFAULT_FLAGS_J2ME, null);
}
public static WriterConfig createFullDefaults()
{
return new WriterConfig(true, DEFAULT_FLAGS_FULL, null);
}
public WriterConfig createNonShared()
{
Object[] specProps;
if (mSpecialProperties != null) {
int len = mSpecialProperties.length;
specProps = new Object[len];
System.arraycopy(mSpecialProperties, 0, specProps, 0, len);
} else {
specProps = null;
}
return new WriterConfig(mIsJ2MESubset, mConfigFlags, specProps);
}
/*
//////////////////////////////////////////////////////////
// Implementation of abstract methods
//////////////////////////////////////////////////////////
*/
protected int findPropertyId(String propName)
{
Integer I = (Integer) sProperties.get(propName);
return (I == null) ? -1 : I.intValue();
}
/*
//////////////////////////////////////////////////////////
// Public API
//////////////////////////////////////////////////////////
*/
public Object getProperty(int id)
{
switch (id) {
// First, Stax 1.0 properties:
case PROP_AUTOMATIC_NS:
return automaticNamespacesEnabled() ? Boolean.TRUE : Boolean.FALSE;
// Then Stax2 properties:
// First, properties common to input/output factories:
case PROP_ENABLE_NS:
return willSupportNamespaces() ? Boolean.TRUE : Boolean.FALSE;
case PROP_PROBLEM_REPORTER:
return getProblemReporter();
// Then output-specific properties:
case PROP_AUTOMATIC_EMPTY_ELEMENTS:
return automaticEmptyElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
case PROP_AUTO_CLOSE_OUTPUT:
return willAutoCloseOutput() ? Boolean.TRUE : Boolean.FALSE;
case PROP_AUTOMATIC_NS_PREFIX:
return getAutomaticNsPrefix();
case PROP_TEXT_ESCAPER:
return getTextEscaperFactory();
case PROP_ATTR_VALUE_ESCAPER:
return getAttrValueEscaperFactory();
// // // Then Woodstox-specific properties:
case PROP_OUTPUT_CDATA_AS_TEXT:
return willOutputCDataAsText() ? Boolean.TRUE : Boolean.FALSE;
case PROP_COPY_DEFAULT_ATTRS:
return willCopyDefaultAttrs() ? Boolean.TRUE : Boolean.FALSE;
case PROP_ESCAPE_CR:
return willEscapeCr() ? Boolean.TRUE : Boolean.FALSE;
case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
return willAddSpaceAfterEmptyElem() ? Boolean.TRUE : Boolean.FALSE;
case PROP_AUTOMATIC_END_ELEMENTS:
return automaticEndElementsEnabled() ? Boolean.TRUE : Boolean.FALSE;
case PROP_VALIDATE_STRUCTURE:
return willValidateStructure() ? Boolean.TRUE : Boolean.FALSE;
case PROP_VALIDATE_CONTENT:
return willValidateContent() ? Boolean.TRUE : Boolean.FALSE;
case PROP_VALIDATE_ATTR:
return willValidateAttributes() ? Boolean.TRUE : Boolean.FALSE;
case PROP_VALIDATE_NAMES:
return willValidateNames() ? Boolean.TRUE : Boolean.FALSE;
case PROP_FIX_CONTENT:
return willFixContent() ? Boolean.TRUE : Boolean.FALSE;
case PROP_OUTPUT_INVALID_CHAR_HANDLER:
return getInvalidCharHandler();
case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
return getEmptyElementHandler();
// And then per-instance properties: not valid via config object
case PROP_UNDERLYING_STREAM:
case PROP_UNDERLYING_WRITER:
throw new IllegalStateException("Can not access per-stream-writer properties via factory");
}
throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
}
/**
* @return True, if the specified property was succesfully
* set to specified value; false if its value was not changed
*/
public boolean setProperty(String name, int id, Object value)
{
switch (id) {
// First, Stax 1.0 properties:
case PROP_AUTOMATIC_NS:
enableAutomaticNamespaces(ArgUtil.convertToBoolean(name, value));
break;
// // // Then Stax2 ones:
case PROP_ENABLE_NS:
doSupportNamespaces(ArgUtil.convertToBoolean(name, value));
break;
case PROP_PROBLEM_REPORTER:
setProblemReporter((XMLReporter) value);
break;
case PROP_AUTOMATIC_EMPTY_ELEMENTS:
enableAutomaticEmptyElements(ArgUtil.convertToBoolean(name, value));
break;
case PROP_AUTO_CLOSE_OUTPUT:
doAutoCloseOutput(ArgUtil.convertToBoolean(name, value));
break;
case PROP_AUTOMATIC_NS_PREFIX:
// value should be a String, but let's verify that:
setAutomaticNsPrefix(value.toString());
break;
case PROP_TEXT_ESCAPER:
setTextEscaperFactory((EscapingWriterFactory) value);
break;
case PROP_ATTR_VALUE_ESCAPER:
setAttrValueEscaperFactory((EscapingWriterFactory) value);
break;
// // // Then Woodstox-specific ones:
case PROP_OUTPUT_CDATA_AS_TEXT:
doOutputCDataAsText(ArgUtil.convertToBoolean(name, value));
break;
case PROP_COPY_DEFAULT_ATTRS:
doCopyDefaultAttrs(ArgUtil.convertToBoolean(name, value));
break;
case PROP_ESCAPE_CR:
doEscapeCr(ArgUtil.convertToBoolean(name, value));
break;
case PROP_ADD_SPACE_AFTER_EMPTY_ELEM:
doAddSpaceAfterEmptyElem(ArgUtil.convertToBoolean(name, value));
break;
case PROP_AUTOMATIC_END_ELEMENTS:
enableAutomaticEndElements(ArgUtil.convertToBoolean(name, value));
break;
case PROP_VALIDATE_STRUCTURE:
doValidateStructure(ArgUtil.convertToBoolean(name, value));
break;
case PROP_VALIDATE_CONTENT:
doValidateContent(ArgUtil.convertToBoolean(name, value));
break;
case PROP_VALIDATE_ATTR:
doValidateAttributes(ArgUtil.convertToBoolean(name, value));
break;
case PROP_VALIDATE_NAMES:
doValidateNames(ArgUtil.convertToBoolean(name, value));
break;
case PROP_FIX_CONTENT:
doFixContent(ArgUtil.convertToBoolean(name, value));
break;
case PROP_OUTPUT_INVALID_CHAR_HANDLER:
setInvalidCharHandler((InvalidCharHandler) value);
break;
case PROP_OUTPUT_EMPTY_ELEMENT_HANDLER:
setEmptyElementHandler((EmptyElementHandler) value);
break;
case PROP_UNDERLYING_STREAM:
case PROP_UNDERLYING_WRITER:
throw new IllegalStateException("Can not modify per-stream-writer properties via factory");
default:
throw new IllegalStateException("Internal error: no handler for property with internal id "+id+".");
}
return true;
}
/*
//////////////////////////////////////////////////////////
// Extended Woodstox API, accessors/modifiers
//////////////////////////////////////////////////////////
*/
// // // "Raw" accessors for on/off properties:
public int getConfigFlags() { return mConfigFlags; }
// // // Accessors, standard properties:
public boolean automaticNamespacesEnabled() {
return hasConfigFlag(CFG_AUTOMATIC_NS);
}
// // // Accessors, Woodstox properties:
public boolean automaticEmptyElementsEnabled() {
return hasConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS);
}
public boolean willAutoCloseOutput() {
return hasConfigFlag(CFG_AUTO_CLOSE_OUTPUT);
}
public boolean willSupportNamespaces() {
return hasConfigFlag(CFG_ENABLE_NS);
}
public boolean willOutputCDataAsText() {
return hasConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT);
}
public boolean willCopyDefaultAttrs() {
return hasConfigFlag(CFG_COPY_DEFAULT_ATTRS);
}
public boolean willEscapeCr() {
return hasConfigFlag(CFG_ESCAPE_CR);
}
public boolean willAddSpaceAfterEmptyElem() {
return hasConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM);
}
public boolean automaticEndElementsEnabled() {
return hasConfigFlag(CFG_AUTOMATIC_END_ELEMENTS);
}
public boolean willValidateStructure() {
return hasConfigFlag(CFG_VALIDATE_STRUCTURE);
}
public boolean willValidateContent() {
return hasConfigFlag(CFG_VALIDATE_CONTENT);
}
public boolean willValidateAttributes() {
return hasConfigFlag(CFG_VALIDATE_ATTR);
}
public boolean willValidateNames() {
return hasConfigFlag(CFG_VALIDATE_NAMES);
}
public boolean willFixContent() {
return hasConfigFlag(CFG_FIX_CONTENT);
}
/**
* @return Prefix to use as the base for automatically generated
* namespace prefixes ("namespace prefix prefix", so to speak).
* Defaults to "wstxns".
*/
public String getAutomaticNsPrefix() {
String prefix = (String) getSpecialProperty(SP_IX_AUTO_NS_PREFIX);
if (prefix == null) {
prefix = DEFAULT_AUTOMATIC_NS_PREFIX;
}
return prefix;
}
public EscapingWriterFactory getTextEscaperFactory() {
return (EscapingWriterFactory) getSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY);
}
public EscapingWriterFactory getAttrValueEscaperFactory() {
return (EscapingWriterFactory) getSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY);
}
public XMLReporter getProblemReporter() {
return (XMLReporter) getSpecialProperty(SP_IX_PROBLEM_REPORTER);
}
public InvalidCharHandler getInvalidCharHandler() {
return (InvalidCharHandler) getSpecialProperty(SP_IX_INVALID_CHAR_HANDLER);
}
public EmptyElementHandler getEmptyElementHandler() {
return (EmptyElementHandler) getSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER);
}
// // // Mutators:
// Standard properies:
public void enableAutomaticNamespaces(boolean state) {
setConfigFlag(CFG_AUTOMATIC_NS, state);
}
// Wstx properies:
public void enableAutomaticEmptyElements(boolean state) {
setConfigFlag(CFG_AUTOMATIC_EMPTY_ELEMENTS, state);
}
public void doAutoCloseOutput(boolean state) {
setConfigFlag(CFG_AUTO_CLOSE_OUTPUT, state);
}
public void doSupportNamespaces(boolean state) {
setConfigFlag(CFG_ENABLE_NS, state);
}
public void doOutputCDataAsText(boolean state) {
setConfigFlag(CFG_OUTPUT_CDATA_AS_TEXT, state);
}
public void doCopyDefaultAttrs(boolean state) {
setConfigFlag(CFG_COPY_DEFAULT_ATTRS, state);
}
public void doEscapeCr(boolean state) {
setConfigFlag(CFG_ESCAPE_CR, state);
}
public void doAddSpaceAfterEmptyElem(boolean state) {
setConfigFlag(CFG_ADD_SPACE_AFTER_EMPTY_ELEM, state);
}
public void enableAutomaticEndElements(boolean state) {
setConfigFlag(CFG_AUTOMATIC_END_ELEMENTS, state);
}
public void doValidateStructure(boolean state) {
setConfigFlag(CFG_VALIDATE_STRUCTURE, state);
}
public void doValidateContent(boolean state) {
setConfigFlag(CFG_VALIDATE_CONTENT, state);
}
public void doValidateAttributes(boolean state) {
setConfigFlag(CFG_VALIDATE_ATTR, state);
}
public void doValidateNames(boolean state) {
setConfigFlag(CFG_VALIDATE_NAMES, state);
}
public void doFixContent(boolean state) {
setConfigFlag(CFG_FIX_CONTENT, state);
}
/**
* @param prefix Prefix to use as the base for automatically generated
* namespace prefixes ("namespace prefix prefix", so to speak).
*/
public void setAutomaticNsPrefix(String prefix) {
setSpecialProperty(SP_IX_AUTO_NS_PREFIX, prefix);
}
public void setTextEscaperFactory(EscapingWriterFactory f) {
setSpecialProperty(SP_IX_TEXT_ESCAPER_FACTORY, f);
}
public void setAttrValueEscaperFactory(EscapingWriterFactory f) {
setSpecialProperty(SP_IX_ATTR_VALUE_ESCAPER_FACTORY, f);
}
public void setProblemReporter(XMLReporter rep) {
setSpecialProperty(SP_IX_PROBLEM_REPORTER, rep);
}
public void setInvalidCharHandler(InvalidCharHandler h) {
setSpecialProperty(SP_IX_INVALID_CHAR_HANDLER, h);
}
public void setEmptyElementHandler(EmptyElementHandler h) {
setSpecialProperty(SP_IX_EMPTY_ELEMENT_HANDLER, h);
}
/*
//////////////////////////////////////////////////////////
// Extended Woodstox API, profiles
//////////////////////////////////////////////////////////
*/
/**
* For Woodstox, this profile enables all basic well-formedness checks,
* including checking for name validity.
*/
public void configureForXmlConformance()
{
doValidateAttributes(true);
doValidateContent(true);
doValidateStructure(true);
doValidateNames(true);
}
/**
* For Woodstox, this profile enables all basic well-formedness checks,
* including checking for name validity, and also enables all matching
* "fix-me" properties (currently only content-fixing property exists).
*/
public void configureForRobustness()
{
doValidateAttributes(true);
doValidateStructure(true);
doValidateNames(true);
/* This the actual "meat": we do want to not only check if the
* content is ok, but also "fix" it if not, and if there's a way
* to fix it:
*/
doValidateContent(true);
doFixContent(true);
}
/**
* For Woodstox, setting this profile disables most checks for validity;
* specifically anything that can have measurable performance impact.
*
*/
public void configureForSpeed()
{
doValidateAttributes(false);
doValidateContent(false);
doValidateNames(false);
// Structural validation is cheap: can be left enabled (if already so)
//doValidateStructure(false);
}
/*
/////////////////////////////////////////////////////
// Buffer recycling:
/////////////////////////////////////////////////////
*/
/**
* Method called to allocate intermediate recyclable copy buffers
*/
public char[] allocMediumCBuffer(int minSize)
{
if (mCurrRecycler != null) {
char[] result = mCurrRecycler.getMediumCBuffer(minSize);
if (result != null) {
return result;
}
}
return new char[minSize];
}
public void freeMediumCBuffer(char[] buffer)
{
// Need to create (and assign) the buffer?
if (mCurrRecycler == null) {
mCurrRecycler = createRecycler();
}
mCurrRecycler.returnMediumCBuffer(buffer);
}
public char[] allocFullCBuffer(int minSize)
{
if (mCurrRecycler != null) {
char[] result = mCurrRecycler.getFullCBuffer(minSize);
if (result != null) {
return result;
}
}
return new char[minSize];
}
public void freeFullCBuffer(char[] buffer)
{
// Need to create (and assign) the buffer?
if (mCurrRecycler == null) {
mCurrRecycler = createRecycler();
}
mCurrRecycler.returnFullCBuffer(buffer);
}
public byte[] allocFullBBuffer(int minSize)
{
if (mCurrRecycler != null) {
byte[] result = mCurrRecycler.getFullBBuffer(minSize);
if (result != null) {
return result;
}
}
return new byte[minSize];
}
public void freeFullBBuffer(byte[] buffer)
{
// Need to create (and assign) the buffer?
if (mCurrRecycler == null) {
mCurrRecycler = createRecycler();
}
mCurrRecycler.returnFullBBuffer(buffer);
}
static int Counter = 0;
private BufferRecycler createRecycler()
{
BufferRecycler recycler = new BufferRecycler();
// No way to reuse/reset SoftReference, have to create new always:
mRecyclerRef.set(new SoftReference(recycler));
return recycler;
}
/*
//////////////////////////////////////////////////////////
// Internal methods
//////////////////////////////////////////////////////////
*/
private void setConfigFlag(int flag, boolean state) {
if (state) {
mConfigFlags |= flag;
} else {
mConfigFlags &= ~flag;
}
}
private final boolean hasConfigFlag(int flag) {
return ((mConfigFlags & flag) == flag);
}
private final Object getSpecialProperty(int ix)
{
if (mSpecialProperties == null) {
return null;
}
return mSpecialProperties[ix];
}
private final void setSpecialProperty(int ix, Object value)
{
if (mSpecialProperties == null) {
mSpecialProperties = new Object[SPEC_PROC_COUNT];
}
mSpecialProperties[ix] = value;
}
}