stax2-3.1.1/ 40755 0 0 0 11520453235 7607 5 ustar 0 0 stax2-3.1.1/src/ 40755 0 0 0 11520453235 10376 5 ustar 0 0 stax2-3.1.1/src/java/ 40755 0 0 0 11520453235 11317 5 ustar 0 0 stax2-3.1.1/src/java/org/ 40755 0 0 0 11520453235 12106 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/ 40755 0 0 0 11520453235 13701 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/ 40755 0 0 0 11520453235 14742 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/evt/ 40755 0 0 0 11520453235 15540 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/io/ 40755 0 0 0 11520453235 15351 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/osgi/ 40755 0 0 0 11520453235 15703 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/ri/ 40755 0 0 0 11520453235 15354 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/ri/dom/ 40755 0 0 0 11520453235 16133 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/ 40755 0 0 0 11520453235 16152 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/ 40755 0 0 0 11520453235 16501 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/typed/ 40755 0 0 0 11520453235 16067 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/util/ 40755 0 0 0 11520453235 15717 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/validation/ 40755 0 0 0 11520453235 17074 5 ustar 0 0 stax2-3.1.1/src/java/org/codehaus/stax2/AttributeInfo.java 100644 0 0 4060 11520453235 20461 0 ustar 0 0 package org.codehaus.stax2; /** * Interface that specifies additional access methods for accessing * combined attribute information reader has, after parsing individual * and combining that with DTD information (if any available; depends on * parser's mode). *
* Note: instances of AttributeInfo are only guaranteed to persist as long * as the (stream) reader points to the START_ELEMENT event, during * which attribute information was parsed. It is possible that some * implementations persist instances afterwards, but it's equally * possible that instances get reused, and as such information * may change. */ public interface AttributeInfo { // // // Generic methods; some duplication from main stream reader /** * @return Number of all attributes accessible (including ones created * from the default values, if any) using this Object. */ public int getAttributeCount(); // // // Methods for finding index of specific attributes /** * @return Index of the specified attribute, if the current element * has such an attribute (explicit, or one created via default * value expansion); -1 if not. */ public int findAttributeIndex(String nsURI, String localName); /** * Returns the index of the id attribute (attribute with any name, * type ID from DTD) of current (start) element, if any. Note that * DTD only allows at most one such attribute per element. * * @return Index of the ID attribute of current element, * if the current element has such an * attribute defined; -1 if not. */ public int getIdAttributeIndex(); /** * Returns the index of the notation attribute (attribute with any name, * type NOTATION from DTD) of current (start) element, if any. Note that * DTD only allows at most one such attribute per element. * * @return Index of the NOTATION attribute of current element, * if the current element has such an * attribute defined; -1 if not. */ public int getNotationAttributeIndex(); } stax2-3.1.1/src/java/org/codehaus/stax2/DTDInfo.java 100644 0 0 3460 11520453235 17134 0 ustar 0 0 package org.codehaus.stax2; import org.codehaus.stax2.validation.DTDValidationSchema; /** * Interface that specifies additional access functionality to parsed DTD * information (if any); these methods are encapsulated on a separate * interface to keep the main reader interface from exploding. *
* Note: instances of DTDInfo are not guaranteed to persist when the reader * that returned it is asked to provide the next event. Some implementations * may let it persist, others might not. */ public interface DTDInfo { // // // Stax2, v1.0 /** * @return If current event is DTD, DTD support is enabled, * and reader supports DTD processing, returns an internal * Object implementation uses for storing/processing DTD; * otherwise returns null. */ public Object getProcessedDTD(); /** * @return If current event is DTD, returns the full root name * (including prefix, if any); otherwise returns null */ public String getDTDRootName(); /** * @return If current event is DTD, and has a system id, returns the * system id; otherwise returns null. */ public String getDTDSystemId(); /** * @return If current event is DTD, and has a public id, returns the * public id; otherwise returns null. */ public String getDTDPublicId(); /** * @return If current event is DTD, and has an internal subset, * returns the internal subset; otherwise returns null. */ public String getDTDInternalSubset(); // // // Stax2, v2.0 /** * Method similar to {@link #getProcessedDTD}, but type-safe. Will * return the DTD schema instance that was read, if we are in mode * where it does get read (at least dtd-aware). */ public DTDValidationSchema getProcessedDTDSchema(); } stax2-3.1.1/src/java/org/codehaus/stax2/LocationInfo.java 100644 0 0 16662 11520453235 20321 0 ustar 0 0 package org.codehaus.stax2; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; /** * Interface that specifies additional access methods for accessing * full location information of an input location within a stream reader. * Access interface may be directly implemented by the reader, or by * another (reusable or per-call-instantiated) helper object. *
* Note: instances of LocationInfo are only guaranteed to persist as long
* as the (stream) reader points to the current element (whatever it is).
* After next call to streamReader.next
, it it possible that
* the previously accessed LocationInfo points to the old information, new
* information, or may even contain just garbage. That is, for each new
* event, getLocationInfo
should be called separately.
*/
public interface LocationInfo
{
/*
/////////////////////////////////////////////////////
// Low-level extended "raw" location access methods
/////////////////////////////////////////////////////
*/
/**
* Method that can be used to get exact byte offset (number of bytes
* read from the stream right before getting to this location) in the
* stream that is pointed to by this reader, right before the start
* of the current event.
*
* Note: this value MAY be the same as the one returned by * {@link #getStartingCharOffset}, but usually only for single-byte * character streams (Ascii, ISO-Latin). * * @return Byte offset (== number of bytes reader so far) within the * underlying stream, if the stream and stream reader are able to * provide this (separate from the character offset, for variable-byte * encodings); -1 if not. */ public long getStartingByteOffset(); /** * Method that can be used to get exact character offset (number of chars * read from the stream right before getting to this location) in the * stream that is pointed to by this reader, right before the start * of the current event. *
* Note: this value MAY be the same as the one returned by * {@link #getStartingByteOffset}; this is the case for single-byte * character streams (Ascii, ISO-Latin), as well as for streams for * which byte offset information is not available (Readers, Strings). * * @return Character offset (== number of bytes reader so far) within the * underlying stream, if the stream and stream reader are able to * provide this (separate from byte offset, for variable-byte * encodings); -1 if not. */ public long getStartingCharOffset(); /** * Method that can be used to get exact byte offset (number of bytes * read from the stream right before getting to this location) in the * stream that is pointed to by this reader, right after the end * of the current event. *
* Note: this value MAY be the same as the one returned by * {@link #getEndingCharOffset}, but usually only for single-byte * character streams (Ascii, ISO-Latin). *
* Note: for lazy-loading implementations, calling this method may * require the underlying stream to be advanced and contents parsed; * this is why it is possible that an exception be thrown. * * @return Byte offset (== number of bytes reader so far) within the * underlying stream, if the stream and stream reader are able to * provide this (separate from the character offset, for variable-byte * encodings); -1 if not. */ public long getEndingByteOffset() throws XMLStreamException; /** * Method that can be used to get exact character offset (number of chars * read from the stream right before getting to this location) in the * stream that is pointed to by this reader, right after the end * of the current event. *
* Note: this value MAY be the same as the one returned by * {@link #getEndingByteOffset}; this is the case for single-byte * character streams (Ascii, ISO-Latin), as well as for streams for * which byte offset information is not available (Readers, Strings). *
* Note: for lazy-loading implementations, calling this method may * require the underlying stream to be advanced and contents parsed; * this is why it is possible that an exception be thrown. * * @return Character offset (== number of bytes reader so far) within the * underlying stream, if the stream and stream reader are able to * provide this (separate from byte offset, for variable-byte * encodings); -1 if not. */ public long getEndingCharOffset() throws XMLStreamException; /* ///////////////////////////////////////////////////// // Object-oriented location access methods ///////////////////////////////////////////////////// */ // // // Existing method from XMLStreamReader: public Location getLocation(); // // // New methods: /** * An optional method that either returns the location object that points the * starting position of the current event, or null if implementation * does not keep track of it (some may return only end location; and * some no location at all). *
* Note: since it is assumed that the start location must either have * been collected by now, or is not accessible (i.e. implementation * [always] returns null), no exception is allowed to be throws, as * no parsing should ever need to be done (unlike with * {@link #getEndLocation}). * * @return Location of the first character of the current event in * the input source (which will also be the starting location * of the following event, if any, or EOF if not), or null (if * implementation does not track locations). */ public XMLStreamLocation2 getStartLocation(); /** * A method that returns the current location of the stream reader * at the input source. This is somewhere between the start * and end locations (inclusive), depending on how parser does it * parsing (for non-lazy implementations it's always the end location; * for others something else). *
* Since this location information should always be accessible, no * further parsing is to be done, and no exceptions can be thrown. * * @return Location of the next character reader will parse in the * input source. */ public XMLStreamLocation2 getCurrentLocation(); /** * An optional method that either returns the location object that points the * ending position of the current event, or null if implementation * does not keep track of it (some may return only start location; and * some no location at all). *
* Note: since some implementations may not yet know the end location
* (esp. ones that do lazy loading), this call may require further
* parsing. As a result, this method may throw a parsing or I/O
* errors.
*
* @return Location right after the end
* of the current event (which will also be the start location of
* the next event, if any, or of EOF otherwise).
*
* @throws XMLStreamException If the stream reader had to advance to
* the end of the event (to find the location), it may encounter a
* parsing (or I/O) error; if so, that gets thrown
*/
public XMLStreamLocation2 getEndLocation()
throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLEventReader2.java 100644 0 0 4634 11520453235 20560 0 ustar 0 0 package org.codehaus.stax2;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
/**
* Extended interface that implements functionality that is missing
* from {@link XMLEventReader}, based on findings on trying to
* implement Stax API v1.0.
*/
public interface XMLEventReader2
extends XMLEventReader
{
/**
* Method that is similar to {@link #hasNext}, except that it can
* throw a {@link XMLStreamException}. This is important distinction,
* since the underlying stream reader is NOT allowed to throw such an
* exception when its
* hasNext()
gets called; but the underlying parser
* may well need to advance the input stream and in doing so may
* encounter an exception. This exception should be propagated to
* the caller, as it may signal a problem with the input stream
* or xml content.
*/
public boolean hasNextEvent() throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Configuration
///////////////////////////////////////////////////////////
*/
/**
* Method similar to {@link javax.xml.stream.XMLInputFactory#isPropertySupported}, used
* to determine whether a property is supported by the Reader
* instance. This means that this method may return false
* for some properties that the input factory does support: specifically,
* it should only return true if the value is mutable on per-instance
* basis. False means that either the property is not recognized, or
* is not mutable via reader instance.
*
* @since 3.0
*/
public boolean isPropertySupported(String name);
/**
* Method that can be used to set per-reader properties; a subset of
* properties one can set via matching
* {@link org.codehaus.stax2.XMLInputFactory2}
* instance. Exactly which methods are mutable is implementation
* specific.
*
* @param name Name of the property to set
* @param value Value to set property to.
*
* @return True, if the specified property was succesfully
* set to specified value; false if its value was not changed
*
* @throws InvalidArgumentException if the property is not supported
* (or recognized) by the stream reader implementation
*
* @since 3.0
*/
public boolean setProperty(String name, Object value);
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLInputFactory2.java 100644 0 0 35223 11520453235 21021 0 ustar 0 0 package org.codehaus.stax2;
import java.io.File;
import java.net.URL;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
/**
* Extension of {@link XMLInputFactory} that adds some convenience factory
* methods as new standard properties that conforming stream
* reader factory and instance implementations need to
* recognize, and preferably support. There are also some profile-based
* configuration methods which allow implementations to set proper goal-based
* values for custom properties.
*
* NOTE: although actual values for the property names are
* visible, implementations should try to use the symbolic constants
* defined here instead, to avoid typos.
*
* @version 3.0 01/21/2007
* @author Tatu Saloranta (tatu.saloranta@iki.fi)
*/
public abstract class XMLInputFactory2
extends XMLInputFactory
implements XMLStreamProperties
{
/*
///////////////////////////////////////////////////////////
// We share some options with other factories
///////////////////////////////////////////////////////////
*/
//public final static String XSP_IMPLEMENTATION_NAME
//public final static String XSP_IMPLEMENTATION_VERSION
//public final static String XSP_SUPPORTS_XML11
//public final static String XSP_NAMESPACE_AWARE
//public final static String XSP_PROBLEM_REPORTER
//public final static String XSP_SUPPORT_XMLID
/*
///////////////////////////////////////////////////////////
// Additional standard configuration properties
///////////////////////////////////////////////////////////
*/
// // // Parsing settings
/**
* Whether reader will generate 'ignorable white space' events during
* prolog and epilog (before and after the main XML root element);
* if true, will generate those events; if false,
* will just ignore white space in these parts of the parsed document.
*
* Turning this feature off may give slight performance improvement, * although usually effect should be negligible. This option is usually * only turned on when round-trip output should be as similar to input * as possible. *
* Default value for this setting is implementation dependant. */ public final static String P_REPORT_PROLOG_WHITESPACE = "org.codehaus.stax2.reportPrologWhitespace"; /** * Whether cursor-based reader will ever generate CDATA events; if true, * CDATA events may be generated for non-coalesced CDATA sections. If * false, all CDATA sections are reported as CHARACTERS types. It may * still be possible for event methods to distinguish between underlying * type, but event type code will be reported as CHARACTERS. *
* State of property does not have any effect on performance. *
* Default value for this setting is implementation dependant. */ public final static String P_REPORT_CDATA = "http://java.sun.com/xml/stream/properties/report-cdata-event"; /** * Whether stream readers are allowed to do lazy parsing, meaning * to parse minimal part of the event when * {@link XMLStreamReader#next} is called, and only parse the rest * as needed (or skip remainder of no extra information is needed). * Alternative to lazy parsing is called "eager parsing", and is * what most xml parsers use by default. *
* Enabling lazy parsing can improve performance for tasks where * number of textual events are skipped. The downside is that * not all well-formedness problems are reported when * {@link XMLStreamReader#next} is called, but only when the * rest of event are read or skipped. *
* Default value for this setting is implementation dependant. */ public final static String P_LAZY_PARSING = "com.ctc.wstx.lazyParsing"; // // // Optimization settings /** * Whether name symbols (element, attribute, entity and notation names, * namespace prefixes) * stream reader returns are guaranteed to have been String.intern()ed. * Interning generally makes access faster (both internal and externally), * and saves memory, but can add some overhead for processing. * It may also be problematic for large symbol spaces; especially * if xml content has unbounded value space for names. *
* Default value for this setting is implementation dependant. * Additionally implementations may have use different default for * different types of stream readers. */ public final static String P_INTERN_NAMES = "org.codehaus.stax2.internNames"; /** * Whether namespace URIs * stream reader returns are guaranteed to have been String.intern()ed. * Interning can make access by fully-qualified name faster as well * as save memory, but it can also add * some overhead when encountering a namespace URI for the first * time. *
* Default value for this setting is implementation dependant. */ public final static String P_INTERN_NS_URIS = "org.codehaus.stax2.internNsUris"; /** * Property that determines whether stream reader instances are required * to try to keep track of the parser Location in the input documents. *
* When turned on, the stream reader should try to do its best to keep
* track of the locations, to be able to properly create
* XMLEvent
objects with accurate Location information.
* Similarly, implementation should keep track of the location for
* error reporting purposes, and include this information within
* XMLStreamException
instances.
*
* When turned off, implementations are allowed to optimize things,
* and only keep/pass partial Location information, or even none at
* all. Implementations are still encouraged to keep some location
* information for error reporting purposes, even if they do not
* maintain accurate
* XMLEvent
locations, or exact byte/character offsets.
*
* Default value for this setting is true. */ public final static String P_PRESERVE_LOCATION = "org.codehaus.stax2.preserveLocation"; // // // Input source settings /** * Whether stream reader is to close the underlying input source (input * stream, reader) when stream reader is closed. Basic StAX2 * specification mandates this feature to be set to false by default * (for sources that are passed by the application). *
* Note: if set to true, readers are also allowed (but not required) to * close the underlying input source when they do not need it any more, * for example when encountering EOF, or when throwing an unrecoverable * parsing exception */ public final static String P_AUTO_CLOSE_INPUT = "org.codehaus.stax2.closeInputSource"; // // // Validation settings /** * Property used to specify the source for DTD external subset to use * instead of DTD specified by the XML document itself (if any). */ public final static String P_DTD_OVERRIDE = "org.codehaus.stax2.propDtdOverride"; /* /////////////////////////////////////////////////////////// // Life-cycle /////////////////////////////////////////////////////////// */ protected XMLInputFactory2() { super(); } // // // New event reader creation methods: /** * Factory method that allows for parsing a document accessible via * specified URL. Note that URL may refer to all normal URL accessible * resources, from files to web- and ftp-accessible documents. */ public abstract XMLEventReader2 createXMLEventReader(URL src) throws XMLStreamException; /** * Convenience factory method that allows for parsing a document * stored in the specified file. */ public abstract XMLEventReader2 createXMLEventReader(File f) throws XMLStreamException; // // // New stream reader creation methods: /** * Factory method that allows for parsing a document accessible via * specified URL. Note that URL may refer to all normal URL accessible * resources, from files to web- and ftp-accessible documents. */ public abstract XMLStreamReader2 createXMLStreamReader(URL src) throws XMLStreamException; /** * Convenience factory method that allows for parsing a document * stored in the specified file. */ public abstract XMLStreamReader2 createXMLStreamReader(File f) throws XMLStreamException; /* /////////////////////////////////////////////////////////// // Configuring using profiles /////////////////////////////////////////////////////////// */ /** * Method to call to make Reader created conform as closely to XML * standard as possible, doing all checks and transformations mandated * by the XML specification (linefeed conversions, attr value * normalizations). *
* Regarding the default StAX property settings, * implementations are suggested to do following: *
SUPPORT_DTD
property.
* IS_NAMESPACE_AWARE
* IS_REPLACING_ENTITY_REFERENCES
* IS_SUPPORTING_EXTERNAL_ENTITIES
* * In addition, implementations should set implementation-dependant * settings appropriately, to be as strict as possible with regards * to XML specification mandated checks and transformations. */ public abstract void configureForXmlConformance(); /** * Method to call to make Reader created be as "convenient" to use * as possible; ie try to avoid having to deal with some of things * like segmented text chunks. This may incur some slight performance * penalties, but should not affect XML conformance. *
* Regarding the default StAX property settings, * implementations are suggested to do following: *
IS_COALESCING
(text coalescing)
* IS_REPLACING_ENTITY_REFERENCES
* P_REPORT_PROLOG_WHITESPACE
(StAX2); so
* that the application need not skip possible SPACE
* (and COMMENT
, PROCESSING_INSTRUCTION
)
* events.
* P_REPORT_ALL_TEXT_AS_CHARACTERS
(StAX2)
* P_PRESERVE_LOCATION
(StAX2)
* * In addition, implementations should set implementation-dependant * settings appropriately as well. */ public abstract void configureForConvenience(); /** * Method to call to make the Reader created be as fast as possible reading * documents, especially for long-running processes where caching is * likely to help. This means reducing amount of information collected * (ignorable white space in prolog/epilog, accurate Location information * for Event API), and possibly even including simplifying handling * of XML-specified transformations (skip attribute value and text * linefeed normalization). * Potential downsides are somewhat increased memory usage * (for full-sized input buffers), and reduced XML conformance (will not * do some of transformations). *
* Regarding the default StAX property settings, * implementations are suggested to do following: *
IS_COALESCING
(text coalescing)
* P_PRESERVE_LOCATION
(StAX2)
* P_REPORT_PROLOG_WHITESPACE
(StAX2)
* P_INTERN_NAMES
(StAX2)
* P_INTERN_NS_URIS
(StAX2)
* * In addition, implementations should set implementation-dependant * settings appropriately as well. */ public abstract void configureForSpeed(); /** * Method to call to minimize the memory usage of the stream/event reader; * both regarding Objects created, and the temporary memory usage during * parsing. * This generally incurs some performance penalties, due to using * smaller input buffers. *
* Regarding the default StAX property settings, * implementations are suggested to do following: *
IS_COALECING
(text coalescing, can force
* longer internal result buffers to be used)
* P_PRESERVE_LOCATION
(StAX) to reduce
* temporary memory usage.
* * In addition, implementations should set implementation-dependant * settings appropriately so that the memory usage is minimized. */ public abstract void configureForLowMemUsage(); /** * Method to call to make Reader try to preserve as much of input * formatting as possible, so that round-tripping would be as lossless * as possible. This means that the matching writer should be able to * reproduce output as closely matching input format as possible * (most implementations won't be able to provide 100% vis-a-vis; * white space between attributes is generally lost, as well as use * of character entities). *
* Regarding the default StAX property settings, * implementations are suggested to do following: *
IS_COALESCING
(to prevent CDATA and Text
* segments from getting combined)
* IS_REPLACING_ENTITY_REFERENCES
to allow for
* preserving explicitly declared general entity references (that is,
* there is no way to preserve character entities, or pre-defined
* entities like 'gt', 'lt', 'amp', 'apos' and 'quot').
* P_REPORT_ALL_TEXT_AS_CHARACTERS
(StAX2)
* (so that CDATA sections are not reported as 'normal' text)
* P_REPORT_PROLOG_WHITESPACE
(StAX2)
* * In addition, implementations should set implementation-dependant * settings appropriately as well. */ public abstract void configureForRoundTripping(); } stax2-3.1.1/src/java/org/codehaus/stax2/XMLOutputFactory2.java 100644 0 0 17526 11520453235 21230 0 ustar 0 0 package org.codehaus.stax2; import java.io.Writer; import javax.xml.stream.XMLEventWriter; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; // only for javadoc import org.codehaus.stax2.io.EscapingWriterFactory; /** * Extension of {@link javax.xml.stream.XMLInputFactory} to add * missing functionality. *
* Also contains extended standard properties that conforming stream
* writer factory and instance implementations should at least
* recognize, and preferably support.
*
* NOTE: although actual values for the property names are
* visible, implementations should try to use the symbolic constants
* defined here instead, to avoid typos.
*
* Notes about properties that output factories should support: *
* Default value for implementations should be 'true'; both values should * be recognized, and 'false' must be honored. However, 'true' value * is only a suggestion, and need not be implemented (since there is * the explicit 'writeEmptyElement()' method). */ public final static String P_AUTOMATIC_EMPTY_ELEMENTS = "org.codehaus.stax2.automaticEmptyElements"; // // // Output stream/writer settings /** * Whether stream writer is to close the underlying output * destination (output stream, reader) when stream writer is closed. * Basic StAX2 specification mandates this feature to be set to * false by default * (for destinations that are passed by the application and for which * it has access to). *
* Note: if set to true, writers are also allowed (but not required) to * close the underlying destination when they do not need it any more, * for example when throwing an (unrecoverable) exception */ public final static String P_AUTO_CLOSE_OUTPUT = "org.codehaus.stax2.autoCloseOutput"; // // Namespace options: /** * Prefix to use for automatically created namespace prefixes, when * namespace support is enabled, the writer is in "repairing" * mode, and a new prefix name is needed. The value is a String, * and needs to be a valid namespace prefix in itself, as defined * by the namespace specification. Will be prepended by a trailing * part (often a sequence number), in order to make it unique to * be usable as a temporary non-colliding prefix. */ public final static String P_AUTOMATIC_NS_PREFIX = "org.codehaus.stax2.automaticNsPrefix"; // // Text/attribute value escaping options: /** * Property that can be set if a custom output escaping for textual * content is needed. * The value set needs to be of type {@link EscapingWriterFactory}. * When set, the factory will be used to create a per-writer * instance used to escape all textual content written, both * via explicit {@link XMLStreamWriter#writeCharacters} methods, * and via copy methods ({@link XMLStreamWriter2#copyEventFromReader}). */ public final static String P_TEXT_ESCAPER = "org.codehaus.stax2.textEscaper"; /** * Property that can be set if a custom output escaping for attribute * value content is needed. * The value set needs to be of type {@link EscapingWriterFactory}. * When set, the factory will be used to create a per-writer * instance used to escape all attribute values written, both * via explicit {@link XMLStreamWriter#writeAttribute} methods, * and via copy methods ({@link XMLStreamWriter2#copyEventFromReader}). */ public final static String P_ATTR_VALUE_ESCAPER = "org.codehaus.stax2.attrValueEscaper"; /* /////////////////////////////////////////////////////////// // Life-cycle /////////////////////////////////////////////////////////// */ protected XMLOutputFactory2() { super(); } public abstract XMLEventWriter createXMLEventWriter(Writer w, String encoding) throws XMLStreamException; public abstract XMLEventWriter createXMLEventWriter(XMLStreamWriter sw) throws XMLStreamException; public abstract XMLStreamWriter2 createXMLStreamWriter(Writer w, String encoding) throws XMLStreamException; /* /////////////////////////////////////////////////////////// // Configuring using profiles /////////////////////////////////////////////////////////// */ /** * Method call to make writer be as strict with output as possible, * ie maximize validation it does to try to catch any well-formedness * or validity problems. *
* This configuration does add some overhead to output process, since * it enables content checks that are overhead. *
* None of currently defined standard properties should be affected, * but implementations are likely to enable/disable custom * properties related to validation. */ public abstract void configureForXmlConformance(); /** * Method call to make writer be as robust as possible, that is, to * make it both check AND fix problems if it can. *
* Like {@link #configureForXmlConformance}, this configuration adds * some overhead to output process. *
* None of currently defined standard properties should be affected, * but implementations are likely to enable/disable custom * properties related to validation. */ public abstract void configureForRobustness(); /** * Method call to make writer optimize its operation for speed. This * generally disably additional checks (if any) writer does, and is * likely to disable many things that {@link #configureForXmlConformance} * (and {@link #configureForRobustness}) enables. *
* None of currently defined standard properties should be affected. */ public abstract void configureForSpeed(); } stax2-3.1.1/src/java/org/codehaus/stax2/XMLReporter2.java 100644 0 0 2677 11520453235 20163 0 ustar 0 0 package org.codehaus.stax2; import javax.xml.stream.XMLReporter; import javax.xml.stream.XMLStreamException; import org.codehaus.stax2.validation.XMLValidationProblem; /** * Extension of {@link XMLReporter} to allow for better access to * information about the actual problem. *
* Note on type of problems reported: although type is * {@link XMLValidationProblem}, it is not strictly related to (optional) * validation process. That is, non-fatal problems related to well-formedness * (mostly in areas of DTD definition, or in some cases problems that would * be fatal normally but have been suppressed by the calling app) will * also be reported through this interface if registered. *
* Stax2 implementations are encouraged to always try to call the improved
* report
method, and only call the base interface version if
* registered report is not of type {@link XMLReporter2}.
*
* @since 3.0
*/
public interface XMLReporter2
extends XMLReporter
{
// From base interface:
//public void report(String message, String errorType, Object relatedInformation, Location location)
/**
* Reporting method called with reference to object that defines
* exact problem being encountered. Implementor is free to
* quietly handle the problem, or to throw an exception
* to cause abnormal termination of xml processing.
*/
public void report(XMLValidationProblem problem) throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLStreamLocation2.java 100644 0 0 2741 11520453235 21275 0 ustar 0 0 package org.codehaus.stax2;
import javax.xml.stream.Location;
/**
* Extension of {@link Location} that adds accessor to retrieve nested
* location information.
*/
public interface XMLStreamLocation2
extends Location
{
/**
* "Dummy" Location implementation and instance that can be return
* instead of null, when no location information is available.
*/
public final static XMLStreamLocation2 NOT_AVAILABLE = new XMLStreamLocation2() {
public XMLStreamLocation2 getContext() {
return null;
}
public int getCharacterOffset() {
return -1;
}
public int getColumnNumber() {
return -1;
}
public int getLineNumber() {
return -1;
}
public String getPublicId() {
return null;
}
public String getSystemId() {
return null;
}
};
/**
* Method that can be used to traverse nested locations, like ones
* created when expanding entities (especially external entities).
* If so, single location object only contains information about
* specific offsets and ids, and a link to its context. Outermost
* location will return null to indicate there is no more information
* to retrieve.
*
* @return Location in the context (parent input source), if any;
* null for locations in the outermost known context
*/
public XMLStreamLocation2 getContext();
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLStreamProperties.java 100644 0 0 12415 11520453235 21616 0 ustar 0 0 package org.codehaus.stax2;
/**
* This interface defines configuration properties shared by multiple
* kinds of factories (input, output, validation) or instances produces
* (readers, writers, validators).
*
* Some of the properties here are same as ones earlier defined in
* {@link javax.xml.stream.XMLInputFactory} and
* {@link javax.xml.stream.XMLOutputFactory}, and are redeclared here
* to emphasize the fact they are usable with broader context (esp.
* properties that use to be only used with input factories but can
* now be used with output or validation factories).
*/
public interface XMLStreamProperties
{
// // // Information about implementation
/**
* This read-only property returns name of the implementation. It
* can be used to determine implementation-specific feature sets,
* in case other methods (calling isPropertySupported
)
* does not work adequately.
*/
public final static String XSP_IMPLEMENTATION_NAME = "org.codehaus.stax2.implName";
/**
* This read-only property returns the version of the implementation,
* and is to be used with implementation name
* ({@link #XSP_IMPLEMENTATION_NAME}) property.
*/
public final static String XSP_IMPLEMENTATION_VERSION = "org.codehaus.stax2.implVersion";
/**
* This read-only property indicates whether the implementation
* supports xml 1.1 content; Boolean.TRUE indicates it does,
* Boolean.FALSE that it does not.
*/
public final static String XSP_SUPPORTS_XML11 = "org.codehaus.stax2.supportsXml11";
// // // Re-declared properties from XMLInputFactory
/**
* Property that can be set to indicate that namespace information is
* to be handled in conformance to the xml namespaces specifiation; or
* false to indicate no namespace handling should be done.
*/
public final static String XSP_NAMESPACE_AWARE = "javax.xml.stream.isNamespaceAware";
/**
* Property that can be set to specify a problem handler which will get
* notified of non-fatal problem (validation errors in non-validating mode,
* warnings). Its value has to be of type
* {@link javax.xml.stream.XMLReporter}
*/
public final static String XSP_PROBLEM_REPORTER = "javax.xml.stream.reporter";
// // // Generic XML feature support:
/**
* Read/write property that can be set to change the level of xml:id
* specification support, if the implementation implements xml:id
* specification. Value to set should be one of
* XSP_V_XMLID_xxx
constants (like
* {@link #XSP_V_XMLID_TYPING}).
*
* Default value is implementation-specific, but recommended default
* value is
* The main reason for specifying this value (as opposed to the full
* enabling) is that there is some overhead associated with
* validation (especially uniqueness constraints checking, which means
* that all values of xml:id attributes in the input document have to
* be kept in memory), whereas typing is a low overhead operation.
*/
public final static String XSP_V_XMLID_TYPING = "xmlidTyping";
/**
* Property value to use with property
* {@link #XSP_SUPPORT_XMLID}.
* Value indicates that both the attribute type assignment
* portion and the validation portion of xml:id should be supported.
* This validation is independent of the actual schema (DTD, RNG,
* W3C Schema) validation, in the sense that even if no such validation
* is enabled, xml:id value validation will still be done if this
* property value is used. Conversely, if schema-based validation
* is used, both xml:id and schema validation may be done (although
* schema validator instances may choose to ignore validity checks
* if they know that full xml:id support is enabled).
*/
public final static String XSP_V_XMLID_FULL = "xmlidFull";
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLStreamReader2.java 100644 0 0 31773 11520453235 20756 0 ustar 0 0 /* Stax2 extension for basic Stax API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2;
import java.io.IOException;
import java.io.Writer;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.codehaus.stax2.typed.TypedXMLStreamReader;
import org.codehaus.stax2.validation.Validatable;
/**
* Extended interface that implements functionality that is necessary
* to properly build event API on top of {@link XMLStreamReader}.
* It also adds limited number of methods that are important for
* efficient pass-through processing (such as one needed when routing
* SOAP-messages).
*
* The features supported via {@link #setFeature} are:
*
* Since version 3.0, stream writer will also implement "Typed Access API"
* on output side.
*
* @version 3.0.1 06-Nov-2008
* @author Tatu Saloranta (tatu.saloranta@iki.fi)
*/
public interface XMLStreamReader2
extends TypedXMLStreamReader,
Validatable
{
/**
* Feature used to specify the source for DTD external subset to use
* instead of DTD specified by the XML document itself (if any).
*
* @deprecated Use {@link XMLInputFactory2#P_DTD_OVERRIDE} instead.
*/
public final static String FEATURE_DTD_OVERRIDE = XMLInputFactory2.P_DTD_OVERRIDE;
/*
///////////////////////////////////////////////////////////
// Configuration
///////////////////////////////////////////////////////////
*/
/**
* Method similar to {@link javax.xml.stream.XMLInputFactory#isPropertySupported}, used
* to determine whether a property is supported by the Reader
* instance. This means that this method may return false
* for some properties that the input factory does support: specifically,
* it should only return true if the value is mutable on per-instance
* basis. False means that either the property is not recognized, or
* is not mutable via reader instance.
*/
public boolean isPropertySupported(String name);
/**
* Method that can be used to set per-reader properties; a subset of
* properties one can set via matching
* {@link org.codehaus.stax2.XMLInputFactory2}
* instance. Exactly which methods are mutable is implementation
* specific.
*
* @param name Name of the property to set
* @param value Value to set property to.
*
* @return True, if the specified property was succesfully
* set to specified value; false if its value was not changed
*
* @throws InvalidArgumentException if the property is not supported
* (or recognized) by the stream reader implementation
*/
public boolean setProperty(String name, Object value);
/**
* Method that can be used to get per-reader values; both generic
* ones (names for which are defined as constants in this class),
* and implementation dependant ones.
*
* Note: although some feature names are shared with
* {@link #setFeature}, not all are: some features are read-only,
* some write-only
*
* @deprecated Should use {@link #getProperty} instead
*
* @param name Name of the feature of which value to get
*
* @return Value of the feature (possibly null), if supported; null
* otherwise
*/
public Object getFeature(String name);
/**
* Method that can be used to set per-reader features such as configuration
* settings; both generic
* ones (names for which are defined as constants in this class),
* and implementation dependant ones.
*
* Note: although some feature names are shared with
* {@link #getFeature}, not all are: some features are read-only,
* some write-only
*
* @deprecated Should use {@link #setProperty} instead
*
* @param name Name of the feature to set
* @param value Value to set feature to.
*/
public void setFeature(String name, Object value);
/*
///////////////////////////////////////////////////////////
// Additional event traversing
///////////////////////////////////////////////////////////
*/
/**
* Method that will skip all the contents of the element that the
* stream currently points to. Current event when calling the method
* has to be START_ELEMENT (or otherwise {@link IllegalStateException}
* is thrown); after the call the stream will point to the matching
* END_ELEMENT event, having skipped zero or more intervening events
* for the contents.
*/
public void skipElement() throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Additional DTD access
///////////////////////////////////////////////////////////
*/
/**
* Method that can be called to get information about DOCTYPE declaration
* that the reader is currently pointing to, if the reader has parsed
* it. Implementations can also choose to return null to indicate they
* do not provide extra information; but they should not throw any
* exceptions beyond normal parsing exceptions.
*
* @return Information object for accessing further DOCTYPE information,
* iff the reader currently points to DTD event, AND is operating
* in mode that parses such information (DTD-aware at least, and
* usually also validating)
*/
public DTDInfo getDTDInfo() throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Additional attribute accessors
///////////////////////////////////////////////////////////
*/
/**
* Method that can be called to get additional information about
* attributes related to the current start element, as well as
* related DTD-based information if available. Note that the
* reader has to currently point to START_ELEMENT; if not,
* a {@link IllegalStateException} will be thrown.
*/
public AttributeInfo getAttributeInfo() throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Extended location information access
///////////////////////////////////////////////////////////
*/
public LocationInfo getLocationInfo();
/*
///////////////////////////////////////////////////////////
// Pass-through text accessors
///////////////////////////////////////////////////////////
*/
/**
* Method similar to {@link #getText()}, except
* that it just uses provided Writer to write all textual content,
* and that it works for wider range of event types.
* For further optimization, it may also be allowed to do true
* pass-through, thus possibly avoiding one temporary copy of the
* data. Finally, note that this method is also guaranteed NOT
* to return fragments, even when coalescing is not enabled and
* a parser is otherwised allowed to return partial segments: this
* requirement is due to there being little benefit in returning
* such short chunks when streaming. Coalescing property is still
* honored normally.
*
* Method can only be called on states CDATA, CHARACTERS, COMMENT,
* DTD, ENTITY_REFERENCE, SPACE and PROCESSING_INSTRUCTION; if called
* when reader is in another state,
* {@link IllegalStateException} will be thrown. Content written
* for elements is same as with {@link #getText()}.
*
* @param w Writer to use for writing textual contents
* @param preserveContents If true, reader has to preserve contents
* so that further calls to
* Note: method may need to read more data to know if the element
* is an empty one, and as such may throw an i/o or parsing exception
* (as {@link XMLStreamException}); however, it won't throw exceptions
* for non-START_ELEMENT event types.
*
* @return True, if current event is START_ELEMENT
* and is based on a parsed empty element; otherwise false
*/
public boolean isEmptyElement() throws XMLStreamException;
/**
* Method that returns the number of open elements in the stack; 0 when
* the reader is in prolog/epilog, 1 inside root element (including
* when pointing at the root element itself) and so on.
* Depth is same for matching start/end elements, as well as for the
* all children of an element.
*
* @return Number of open elements currently in the reader's stack,
* including current START_ELEMENT or END_ELEMENT (if pointing to one).
*/
public int getDepth();
/**
* This method returns a namespace context object that contains
* information identical to that returned by
* {@link javax.xml.stream.XMLStreamReader#getNamespaceContext()},
* but one that is
* not transient. That is, one that will remain valid and unchanged
* after its creation. This allows the namespace context to be used
* independent of its source documents life cycle. One possible use
* case is to use this namespace context for 'initializing' writers
* (especially ones that use repairing mode) with optimal/preferred name
* space bindings.
*
* @return Non-transient namespace context as explained above.
*/
public NamespaceContext getNonTransientNamespaceContext();
/**
* This method returns "prefix-qualified" name of the current
* element. In general, this means character-by-character exact
* name of the element in XML content, and may be useful in informational
* purposes, as well as when interacting with packages and APIs that
* use such names (such as what SAX may use as qnames).
*
* Note: implementations are encouraged to provide an implementation
* that would be more efficient than calling
* Since version 3.0, stream writer will also implement "Typed Access API"
* on output side.
*
* @version 3.0.1 06-Nov-2008
* @author Tatu Saloranta (tatu.saloranta@iki.fi)
*/
public interface XMLStreamWriter2
extends TypedXMLStreamWriter,
Validatable
{
/*
///////////////////////////////////////////////////////////
// Configuration
///////////////////////////////////////////////////////////
*/
/**
* Method similar to {@link javax.xml.stream.XMLOutputFactory#isPropertySupported}, used
* to determine whether a property is supported by the Writer
* instance. This means that this method may return false
* for some properties that the output factory does support: specifically,
* it should only return true if the value is mutable on per-instance
* basis. False means that either the property is not recognized, or
* is not mutable via writer instance.
*/
public boolean isPropertySupported(String name);
/**
* Method that can be used to set per-writer properties; a subset of
* properties one can set via matching
* {@link org.codehaus.stax2.XMLOutputFactory2}
* instance. Exactly which methods are mutable is implementation
* specific.
*
* @param name Name of the property to set
* @param value Value to set property to.
*
* @return True, if the specified property was succesfully
* set to specified value; false if its value was not changed
*
* @throws InvalidArgumentException if the property is not supported
* (or recognized) by the stream writer implementation
*/
public boolean setProperty(String name, Object value);
/*
///////////////////////////////////////////////////////////
// Other accessors, mutators
///////////////////////////////////////////////////////////
*/
/**
* Method that should return current output location, if the writer
* keeps track of it; null if it does not.
*/
public XMLStreamLocation2 getLocation();
/**
* Method that can be called to get information about encoding that
* this writer is using (or at least claims is using). That is,
* it returns name of encoding specified when (in order of priority):
*
* This method is useful for things like outputting indentation.
*
* @since 3.0
*/
public void writeSpace(String text)
throws XMLStreamException;
/**
* Method that can be called to write whitespace-only content.
* If so, it is to be written as is (with no escaping), and does
* not contain non-whitespace characters (writer may validate this,
* and throw an exception if it does).
*
* This method is useful for things like outputting indentation.
*
* @since 3.0
*/
public void writeSpace(char[] text, int offset, int length)
throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Pass-through methods
///////////////////////////////////////////////////////////
*/
/**
* Method that writes specified content as is, without encoding or
* deciphering it in any way. It will not update state of the writer
* (except by possibly flushing output of previous writes, like
* finishing a start element),
* nor be validated in any way. As such, care must be taken, if this
* method is used.
*
* Method is usually used when encapsulating output from another writer
* as a sub-tree, or when passing through XML fragments.
*
* NOTE: since text to be written may be anything, including markup,
* it can not be reliably validated. Because of this, validator(s)
* attached to the writer will NOT be informed about writes.
*/
public void writeRaw(String text)
throws XMLStreamException;
/**
* Method that writes specified content as is, without encoding or
* deciphering it in any way. It will not update state of the writer
* (except by possibly flushing output of previous writes, like
* finishing a start element),
* nor be validated in any way. As such, care must be taken, if this
* method is used.
*
* Method is usually used when encapsulating output from another writer
* as a sub-tree, or when passing through XML fragments.
*
* NOTE: since text to be written may be anything, including markup,
* it can not be reliably validated. Because of this, validator(s)
* attached to the writer will NOT be informed about writes.
*/
public void writeRaw(String text, int offset, int length)
throws XMLStreamException;
/**
* Method that writes specified content as is, without encoding or
* deciphering it in any way. It will not update state of the writer
* (except by possibly flushing output of previous writes, like
* finishing a start element),
* nor be validated in any way. As such, care must be taken, if this
* method is used.
*
* Method is usually used when encapsulating output from another writer
* as a sub-tree, or when passing through XML fragments.
*
* NOTE: since text to be written may be anything, including markup,
* it can not be reliably validated. Because of this, validator(s)
* attached to the writer will NOT be informed about writes.
*/
public void writeRaw(char[] text, int offset, int length)
throws XMLStreamException;
/**
* Method that essentially copies
* event that the specified reader has just read.
* This can be both more convenient
* (no need to worry about details) and more efficient
* than separately calling access methods of the reader and
* write methods of the writer, since writer may know more
* about reader than the application (and may be able to use
* non-public methods)
*
* @param r Reader to use for accessing event to copy
* @param preserveEventData If true, writer is not allowed to change
* the state of the reader (so that all the data associated with the
* current event has to be preserved); if false, writer is allowed
* to use methods that may cause some data to be discarded. Setting
* this to false may improve the performance, since it may allow
* full no-copy streaming of data, especially textual contents.
*/
public void copyEventFromReader(XMLStreamReader2 r, boolean preserveEventData)
throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Output handling
///////////////////////////////////////////////////////////
*/
/**
* Method similar to
* {@link javax.xml.stream.XMLStreamWriter#close()},
* except that this method also does close the underlying output
* destination (stream) if it has not yet been closed.
* It is specifically necessary to call this method if the parsing ends
* in an exception to ensure that the output destination does get
* properly closed, even if the stream writer would otherwise close
* it (as is the case for destinations it manages where calling
* application has no access)
*/
public void closeCompletely()
throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/evt/DTD2.java 100644 0 0 647 11520453235 17164 0 ustar 0 0 package org.codehaus.stax2.evt;
import javax.xml.stream.events.DTD;
/**
* Interface that extends basic {@link DTD} with methods that are
* necessary to completely reproduce actual DOCTYPE declaration
* constructs in xml documents.
*/
public interface DTD2
extends DTD
{
public String getRootName();
public String getSystemId();
public String getPublicId();
public String getInternalSubset();
}
stax2-3.1.1/src/java/org/codehaus/stax2/evt/NotationDeclaration2.java 100644 0 0 534 11520453235 22505 0 ustar 0 0 package org.codehaus.stax2.evt;
import javax.xml.stream.events.NotationDeclaration;
/**
* Interface that extends basic {@link NotationDeclaration} to add
* support for handling Base URI needed to resolve Notation references.
* This
*/
public interface NotationDeclaration2
extends NotationDeclaration
{
public String getBaseURI();
}
stax2-3.1.1/src/java/org/codehaus/stax2/evt/XMLEvent2.java 100644 0 0 1212 11520453235 20220 0 ustar 0 0 package org.codehaus.stax2.evt;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import org.codehaus.stax2.XMLStreamWriter2;
/**
* Interface that extends basic {@link XMLEvent2} with method(s)
* that are missing from it; specifically linkage that allows using
* a stream/event writer for outputting.
*
* NOTE: Unfortunately there is no way to cleanly retrofit this interface
* to actual implementation classes, so some casting is necessary to
* make use of new features.
*/
public interface XMLEvent2
extends XMLEvent
{
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/evt/XMLEventFactory2.java 100644 0 0 1221 11520453235 21550 0 ustar 0 0 package org.codehaus.stax2.evt;
import javax.xml.stream.XMLEventFactory;
/**
* Interface that adds missing (but required) methods to
* {@link XMLEventFactory}; especially ones for creating actual
* well-behaving DOCTYPE events.
*/
public abstract class XMLEventFactory2
extends XMLEventFactory
{
protected XMLEventFactory2() {
super();
}
public abstract DTD2 createDTD(String rootName, String sysId, String pubId,
String intSubset);
public abstract DTD2 createDTD(String rootName, String sysId, String pubId,
String intSubset, Object processedDTD);
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/EscapingWriterFactory.java 100644 0 0 4436 11520453235 22576 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
/**
* Interface that defines API for the factories stream writers use for
* creating "escaping writers". These factories are used when defining
* custom escaping of text (as well as possibly used by the
* implementations for default escaping too). Escaping in this context
* refers to the process of replacing individual text/attribute content
* character with pre-defined and character entities, as per XML
* specification (2.4, Appendix D).
*
* Typical escaping writers replace characters like '<' and '&',
* as well as some additional characters depending on context.
* Custom implementations may choose to escape additional characters,
* for example to make it easier to manually view or edit resulting
* serialized XML document.
*
* Note about implementing escaping writers: writers need to obey normal
* Writer semantics, and specifically they should pass calls to
*
* Note that no copy is made of the passed-in array, and that further
* there are direct access methods. Thus, although callers are not
* to modify contents of returned array, this can not be guaranteed;
* and as such if this would be a problem (security problem for example),
* caller has to make a copy of the array and pass that copy to the
* constructor.
*/
public class Stax2ByteArraySource
extends Stax2BlockSource
{
private final static String DEFAULT_ENCODING = "UTF-8";
final byte[] mBuffer;
final int mStart;
final int mLength;
public Stax2ByteArraySource(byte[] buf, int start, int len)
{
mBuffer = buf;
mStart = start;
mLength = len;
}
/*
/////////////////////////////////////////
// Implementation of the Public API
/////////////////////////////////////////
*/
/**
* Note: if encoding is not explicitly defined, UTF-8 is assumed.
*/
public Reader constructReader()
throws IOException
{
String enc = getEncoding();
InputStream in = constructInputStream();
if (enc == null || enc.length() == 0) {
/* 11-Nov-2008, TSa: Used to rely on platform default encoding, which
* doesn't make sense. XML assumes UTF-8 anyway.
*/
enc = DEFAULT_ENCODING;
}
return new InputStreamReader(in, enc);
}
public InputStream constructInputStream()
throws IOException
{
return new ByteArrayInputStream(mBuffer, mStart, mLength);
}
/*
/////////////////////////////////////////
// Additional API for this source
/////////////////////////////////////////
*/
public byte[] getBuffer() {
return mBuffer;
}
public int getBufferStart() {
return mStart;
}
public int getBufferLength() {
return mLength;
}
public int getBufferEnd() {
int end = mStart;
if (mLength > 0) {
end += mLength;
}
return end;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2CharArraySource.java 100644 0 0 3216 11520453235 22272 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* Simple implementation of {@link Stax2BlockSource} that encapsulates
* an char array.
*
* Note that no copy is made of the passed-in array, and that further
* there are direct access methods. Thus, although callers are not
* to modify contents of returned array, this can not be guaranteed;
* and as such if this would be a problem (security problem for example),
* caller has to make a copy of the array and pass that copy to the
* constructor.
*/
public class Stax2CharArraySource
extends Stax2BlockSource
{
final char[] mBuffer;
final int mStart;
final int mLength;
public Stax2CharArraySource(char[] buf, int start, int len)
{
mBuffer = buf;
mStart = start;
mLength = len;
}
/*
/////////////////////////////////////////
// Implementation of the Public API
/////////////////////////////////////////
*/
public Reader constructReader()
throws IOException
{
return new CharArrayReader(mBuffer, mStart, mLength);
}
public InputStream constructInputStream()
throws IOException
{
/* No obvious/easy way; if caller really wants an InputStream, it
* can get a Reader, add an encoders, and so on.
*/
return null;
}
/*
/////////////////////////////////////////
// Additional API for this source
/////////////////////////////////////////
*/
public char[] getBuffer() {
return mBuffer;
}
public int getBufferStart() {
return mStart;
}
public int getBufferLength() {
return mLength;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2FileResult.java 100644 0 0 2174 11520453235 21315 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* Simple implementation of {@link Stax2ReferentialResult}, which refers
* to the specific file.
*/
public class Stax2FileResult
extends Stax2ReferentialResult
{
final File mFile;
public Stax2FileResult(File f) {
mFile = f;
}
/*
/////////////////////////////////////////
// Implementation of the Public API
/////////////////////////////////////////
*/
public Writer constructWriter()
throws IOException
{
String enc = getEncoding();
if (enc != null && enc.length() > 0) {
return new OutputStreamWriter(constructOutputStream(), enc);
}
// Sub-optimal; really shouldn't use the platform default encoding
return new FileWriter(mFile);
}
public OutputStream constructOutputStream()
throws IOException
{
return new FileOutputStream(mFile);
}
/*
/////////////////////////////////////////
// Additional API for this Result
/////////////////////////////////////////
*/
public File getFile() {
return mFile;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2FileSource.java 100644 0 0 3746 11520453235 21305 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
import java.net.URL;
/**
* Simple implementation of {@link Stax2ReferentialSource}, which refers
* to the specific file.
*/
public class Stax2FileSource
extends Stax2ReferentialSource
{
final File mFile;
public Stax2FileSource(File f) {
mFile = f;
}
/*
/////////////////////////////////////////
// Implementation of the Public API
/////////////////////////////////////////
*/
/**
* @return URL that refers to the reference resource, for the purposes
* of resolving a relative reference from content read from the
* resource.
*/
public URL getReference()
{
/* !!! 13-May-2006, TSa: For Woodstox 4.0, consider converting
* first to URI, then to URL, to ensure that characters in the
* filename are properly quoted
*/
try {
return mFile.toURL();
} catch (java.net.MalformedURLException e) {
/* Hmmh. Signature doesn't allow IOException to be thrown. So,
* let's use something close enough; this should not occur
* often in practice.
*/
throw new IllegalArgumentException("(was "+e.getClass()+") Could not convert File '"+mFile.getPath()+"' to URL: "+e);
}
}
public Reader constructReader()
throws IOException
{
String enc = getEncoding();
if (enc != null && enc.length() > 0) {
return new InputStreamReader(constructInputStream(), enc);
}
// Sub-optimal; really shouldn't use the platform default encoding
return new FileReader(mFile);
}
public InputStream constructInputStream()
throws IOException
{
return new FileInputStream(mFile);
}
/*
/////////////////////////////////////////
// Additional API for this source
/////////////////////////////////////////
*/
public File getFile() {
return mFile;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2ReferentialResult.java 100644 0 0 1231 11520453235 22667 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* This is the mid-level abstract base class for {@link Stax2Result}s
* that refer to a resource in such a way, that an efficient
* {@link OutputStream} or {@link Writer} can be constructed.
*
* @see Stax2FileResult
*/
public abstract class Stax2ReferentialResult
extends Stax2Result
{
protected Stax2ReferentialResult() { }
/*
/////////////////////////////////////////
// Public API
/////////////////////////////////////////
*/
public abstract Writer constructWriter() throws IOException;
public abstract OutputStream constructOutputStream() throws IOException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2ReferentialSource.java 100644 0 0 2721 11520453235 22656 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
import java.net.URL;
/**
* This is the mid-level abstract base class for {@link Stax2Source}s
* that refer to a resource in such a way, that an efficient
* {@link InputStream} or {@link Reader} can be constructed.
* Additionally, referenced sources also provide the base URI that allows
* for resolving relative references from within content read from
* such resources. Typical examples of references are
* {@link java.net.URL} and {@link java.io.File}: both for which
* a default implementations exist in this package
*
* @see Stax2FileSource
* @see Stax2URLSource
*/
public abstract class Stax2ReferentialSource
extends Stax2Source
{
protected Stax2ReferentialSource() { }
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
public abstract URL getReference();
public abstract Reader constructReader() throws IOException;
public abstract InputStream constructInputStream() throws IOException;
/*
/////////////////////////////////////////
// Overrides
/////////////////////////////////////////
*/
/**
* Since we can determine a system id from the base URL
*/
public String getSystemId()
{
String sysId = super.getSystemId();
if (sysId == null) {
sysId = getReference().toExternalForm();
}
return sysId;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2Result.java 100644 0 0 5742 11520453235 20521 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.OutputStream;
import java.io.IOException;
import java.io.Writer;
import javax.xml.transform.Result;
/**
* This is the base class for additional output results (implementations
* of {@link javax.xml.transform.Result}) that Stax2
* {@link org.codehaus.stax2.XMLInputFactory2} implementations should support.
*
* Note about usage by the parser factory implementations: the expectation
* is that at least one of methods {@link #constructWriter} and
* {@link #constructOutputStream} will succeed, but not necessarily both.
* This generally depends on type of resource being represented: for example,
* if the source is a StringBuffer, it is most naturally
* represent via {@link Writer}. For File-backed results, on the other hand,
* an {@link OutputStream} is the most natural access method.
*
* Other things to note about using result {@link Writer}s and
* {@link OutputStream}s:
*
* Note about usage by the parser factory implementations: the expectation
* is that at least one of methods {@link #constructReader} and
* {@link #constructInputStream} will succeed, but not necessarily both.
* This generally depends on type of resource being represented: for example,
* if the source is a String or character array, it is most naturally
* represent via {@link Reader}. For a byte array, on the other hand,
* an {@link InputStream} is the most natural access method.
*
* Other things to note about using result {@link Reader}s and
* {@link InputStream}s:
*
* Note: implementations of provider should NOT use introspection
* via {@link javax.xml.stream.XMLInputFactory#newInstance} as it will
* not work with OSGi. Instead, providers should directly construct
* instances of concrete factory they represent. That is, there will
* be one provider implementation per concrete Stax/Stax2 implementation
*/
public interface Stax2InputFactoryProvider
{
/*
///////////////////////////////////////////////////////////////
// Service property names to use with the provider
///////////////////////////////////////////////////////////////
*/
/**
* Service property that defines name of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_NAME = XMLStreamProperties.XSP_IMPLEMENTATION_NAME;
/**
* Service property that defines version of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_VERSION = XMLStreamProperties.XSP_IMPLEMENTATION_VERSION;
/*
///////////////////////////////////////////////////////////////
// Public provider API
///////////////////////////////////////////////////////////////
*/
/**
* Method called to create a new {@link XMLInputFactory2} instance.
*
* @return Input factory configured to implementation-specific
* default settings (some of which are mandated by Stax and Stax2
* specifications)
*/
public XMLInputFactory2 createInputFactory();
}
stax2-3.1.1/src/java/org/codehaus/stax2/osgi/Stax2OutputFactoryProvider.java 100644 0 0 3756 11520453235 24143 0 ustar 0 0 package org.codehaus.stax2.osgi;
import org.codehaus.stax2.XMLOutputFactory2;
import org.codehaus.stax2.XMLStreamProperties;
/**
* Simple interface to be used for registering objects that
* can construct {@link XMLOutputFactory2} instances with OSGi framework.
* The added indirection (provider constructing factory) is needed because
* of impedance between OSGi service objects (which are essentially
* singletons) and Stax/Stax2 factories which are not.
*
* Note: implementations of provider should NOT use introspection
* via {@link javax.xml.stream.XMLOutputFactory#newInstance} as it will
* not work with OSGi. Instead, providers should directly construct
* instances of concrete factory they represent. That is, there will
* be one provider implementation per concrete Stax/Stax2 implementation
*/
public interface Stax2OutputFactoryProvider
{
/*
///////////////////////////////////////////////////////////////
// Service property names to use with the provider
///////////////////////////////////////////////////////////////
*/
/**
* Service property that defines name of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_NAME = XMLStreamProperties.XSP_IMPLEMENTATION_NAME;
/**
* Service property that defines version of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_VERSION = XMLStreamProperties.XSP_IMPLEMENTATION_VERSION;
/*
///////////////////////////////////////////////////////////////
// Public provider API
///////////////////////////////////////////////////////////////
*/
/**
* Method called to create a new {@link XMLOutputFactory2} instance.
*
* @return Output factory configured to implementation-specific
* default settings (some of which are mandated by Stax and Stax2
* specifications)
*/
public XMLOutputFactory2 createOutputFactory();
}
stax2-3.1.1/src/java/org/codehaus/stax2/osgi/Stax2ValidationSchemaFactoryProvider.java 100644 0 0 6226 11520453235 26051 0 ustar 0 0 package org.codehaus.stax2.osgi;
import org.codehaus.stax2.XMLStreamProperties;
import org.codehaus.stax2.validation.XMLValidationSchemaFactory;
/**
* Simple interface to be used for registering objects that
* can construct {@link XMLValidationSchemaFactory} instances with OSGi framework.
* The added indirection (provider constructing factory) is needed because
* of impedance between OSGi service objects (which are essentially
* singletons) and Stax/Stax2 factories which are not.
*
* Note: implementations of provider should NOT use introspection
* via {@link XMLValidationSchemaFactory#newInstance} as it will
* not work with OSGi. Instead, providers should directly construct
* instances of concrete factory they represent. That is, there will
* be one provider implementation per concrete Stax/Stax2 implementation
*/
public interface Stax2ValidationSchemaFactoryProvider
{
/*
///////////////////////////////////////////////////////////////
// Service property names to use with the provider
///////////////////////////////////////////////////////////////
*/
/**
* Service property that defines name of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_NAME = XMLStreamProperties.XSP_IMPLEMENTATION_NAME;
/**
* Service property that defines version of Stax2 implementation that
* this provider represents.
*/
public final static String OSGI_SVC_PROP_IMPL_VERSION = XMLStreamProperties.XSP_IMPLEMENTATION_VERSION;
/**
* Service property that defines type of Schemas (one of constants from
* {@link org.codehaus.stax2.validation.XMLValidationSchema},
* such as {@link org.codehaus.stax2.validation.XMLValidationSchema#SCHEMA_ID_DTD})
* that the schema factory this provider handles supports. Can be used
* to locate proper provider for the schema type.
*/
public final static String OSGI_SVC_PROP_SCHEMA_TYPE = "org.codehaus.stax2.validation.schemaType";
/*
///////////////////////////////////////////////////////////////
// Public provider API
///////////////////////////////////////////////////////////////
*/
/**
* Method that can be used to determine which schema type this
* provider (or, rather, factory instances of which provider
* constructs) supports.
*
* @return Id of schema type that the factory instantiated by this
* provider will support.
*/
public String getSchemaType();
/**
* Method called to create a new {@link XMLValidationSchemaFactory}
* instance. Each schema factory supports a single schema type;
* so caller has to ensure that the factory it is using supports
* schema it needs to instantiate. This can be done either by using
* service properties, or by inspecting provider instances for
* schema type they support (see {@link #getSchemaType}).
*
* @return ValidationSchema factory configured to implementation-specific
* default settings, if type is supported by this provider; null
* if not.
*/
public XMLValidationSchemaFactory createValidationSchemaFactory();
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/EmptyIterator.java 100644 0 0 1342 11520453235 21124 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.util.Iterator;
/**
* Simple implementation of "null iterator", iterator that has nothing to
* iterate over.
*/
public final class EmptyIterator
implements Iterator
{
final static EmptyIterator sInstance = new EmptyIterator();
private EmptyIterator() { }
public static EmptyIterator getInstance() { return sInstance; }
public boolean hasNext() { return false; }
public Object next() {
throw new java.util.NoSuchElementException();
}
public void remove()
{
/* The reason we do this is that we know for a fact that
* it can not have been moved
*/
throw new IllegalStateException();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/EmptyNamespaceContext.java 100644 0 0 5133 11520453235 22576 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.util.Iterator;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
/**
* Dummy {@link NamespaceContext} implementation that contains no
* namespace information, except bindings that are specified by
* the namespace specification itself (for prefixes "xml" and "xmlns")
*/
public class EmptyNamespaceContext
implements NamespaceContext
{
final static EmptyNamespaceContext sInstance = new EmptyNamespaceContext();
private EmptyNamespaceContext() { }
public static EmptyNamespaceContext getInstance() { return sInstance; }
/*
/////////////////////////////////////////////
// NamespaceContext API
/////////////////////////////////////////////
*/
public final String getNamespaceURI(String prefix)
{
/* First the known offenders; invalid args, 2 predefined xml namespace
* prefixes
*/
if (prefix == null) {
throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
}
if (prefix.length() > 0) {
if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {
return XMLConstants.XML_NS_URI;
}
if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
}
return null;
}
public final String getPrefix(String nsURI)
{
/* First the known offenders; invalid args, 2 predefined xml namespace
* prefixes
*/
if (nsURI == null || nsURI.length() == 0) {
throw new IllegalArgumentException("Illegal to pass null/empty URI as argument.");
}
if (nsURI.equals(XMLConstants.XML_NS_URI)) {
return XMLConstants.XML_NS_PREFIX;
}
if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
return XMLConstants.XMLNS_ATTRIBUTE;
}
return null;
}
public final Iterator getPrefixes(String nsURI)
{
/* First the known offenders; invalid args, 2 predefined xml namespace
* prefixes
*/
if (nsURI == null || nsURI.length() == 0) {
throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
}
if (nsURI.equals(XMLConstants.XML_NS_URI)) {
return new SingletonIterator(XMLConstants.XML_NS_PREFIX);
}
if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
return new SingletonIterator(XMLConstants.XMLNS_ATTRIBUTE);
}
return EmptyIterator.getInstance();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/SingletonIterator.java 100644 0 0 1371 11520453235 21772 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.util.Iterator;
/**
* Simple read-only iterator that iterators over one specific item, passed
* in as constructor argument.
*/
public class SingletonIterator
implements Iterator
{
private final Object mValue;
private boolean mDone = false;
public SingletonIterator(Object value) {
mValue = value;
}
public boolean hasNext() {
return !mDone;
}
public Object next() {
if (mDone) {
throw new java.util.NoSuchElementException();
}
mDone = true;
return mValue;
}
public void remove()
{
throw new UnsupportedOperationException("Can not remove item from SingletonIterator.");
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2EventFactoryImpl.java 100644 0 0 15231 11520453235 22513 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import org.codehaus.stax2.evt.XMLEventFactory2;
import org.codehaus.stax2.evt.DTD2;
import org.codehaus.stax2.ri.evt.*;
/**
* This is an abstract almost complete plain vanilla implementation of
* {@link XMLEventFactory2}.
* It can be used as a building block for concrete implementations:
* the minimal requirement is to implement
* Since there is not much to optimize at this
* level (API and underlying stream reader pretty much define functionality
* and optimizations that can be done), implementation is fairly straight
* forward, with not many surprises.
*
* Implementation notes: the trickiest things to implement are:
*
* Note: although the interface allows implementations to
* throw an {@link XMLStreamException}, the reference implementation
* doesn't currently need to.
* It's still declared, in case in future there is need to throw
* such an exception.
*/
public boolean hasNextEvent()
throws XMLStreamException
{
return (mState != STATE_END_OF_INPUT);
}
/*
///////////////////////////////////////////////
// Overridable factory methods
///////////////////////////////////////////////
*/
protected XMLEvent createNextEvent(boolean checkEOD, int type)
throws XMLStreamException
{
try {
XMLEvent evt = mAllocator.allocate(mReader);
if (checkEOD && type == END_DOCUMENT) {
mState = STATE_END_OF_INPUT;
}
return evt;
} catch (RuntimeException rex) {
/* 29-Mar-2008, TSa: Due to some problems with Stax API
* (lack of 'throws XMLStreamException' in signature of
* XMLStreamReader.getText(), for one) it is possible
* we will get a wrapped XMLStreamException. If so,
* we should be able to unwrap it.
*/
Throwable t = rex.getCause();
while (t != null) {
if (t instanceof XMLStreamException) {
throw (XMLStreamException) t;
}
t = t.getCause();
}
// Nope, need to re-throw as is
throw rex;
}
}
/**
* Method called to create the very first event (START_DOCUMENT).
*/
protected XMLEvent createStartDocumentEvent()
throws XMLStreamException
{
XMLEvent start = mAllocator.allocate(mReader);
return start;
}
/*
///////////////////////////////////////////////
// Overridable error reporting methods
///////////////////////////////////////////////
*/
private void throwEndOfInput()
{
throw new NoSuchElementException();
}
protected void throwUnchecked(XMLStreamException sex)
{
/* Wrapped root cause? Let's only unwrap one layer; one that
* must have been used to expose the problem (if any)
*/
Throwable t = (sex.getNestedException() == null) ? sex : sex.getNestedException();
// Unchecked? Can re-throw as is
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
if (t instanceof Error) {
throw (Error) t;
}
// Otherwise, let's just wrap it
throw new RuntimeException("[was "+t.getClass()+"] "+t.getMessage(), t);
}
protected void reportProblem(String msg)
throws XMLStreamException
{
reportProblem(msg, mReader.getLocation());
}
protected void reportProblem(String msg, Location loc)
throws XMLStreamException
{
if (loc == null) {
throw new XMLStreamException(msg);
}
throw new XMLStreamException(msg, loc);
}
/*
///////////////////////////////////////////////
// Package methods for sub-classes
///////////////////////////////////////////////
*/
protected XMLStreamReader getStreamReader()
{
return mReader;
}
/*
///////////////////////////////////////////////
// Other internal methods
///////////////////////////////////////////////
*/
/**
* Method used to locate error message description to use.
* Calls sub-classes
* Note: ALL events (except for custom ones ref. impl. itself doesn't
* produce, and thus may not always be able to deal with) are routed
* through stream writer. This because it may want to do
* different kinds of validation
*/
public void add(XMLEvent event)
throws XMLStreamException
{
switch (event.getEventType()) {
/* First events that we have to route via stream writer, to
* get and/or update namespace information:
*/
case ATTRIBUTE: // need to pass to stream writer, to get namespace info
{
Attribute attr = (Attribute) event;
QName name = attr.getName();
mWriter.writeAttribute(name.getPrefix(), name.getNamespaceURI(),
name.getLocalPart(), attr.getValue());
}
break;
case END_DOCUMENT:
mWriter.writeEndDocument();
break;
case END_ELEMENT:
mWriter.writeEndElement();
break;
case NAMESPACE:
{
Namespace ns = (Namespace) event;
mWriter.writeNamespace(ns.getPrefix(), ns.getNamespaceURI());
}
break;
case START_DOCUMENT:
{
StartDocument sd = (StartDocument) event;
if (!sd.encodingSet()) { // encoding defined?
mWriter.writeStartDocument(sd.getVersion());
} else {
mWriter.writeStartDocument(sd.getCharacterEncodingScheme(),
sd.getVersion());
}
}
break;
case START_ELEMENT:
{
StartElement se = event.asStartElement();
QName n = se.getName();
mWriter.writeStartElement(n.getPrefix(), n.getLocalPart(),
n.getNamespaceURI());
Iterator it = se.getNamespaces();
while (it.hasNext()) {
Namespace ns = (Namespace) it.next();
add(ns);
}
it = se.getAttributes();
while (it.hasNext()) {
Attribute attr = (Attribute) it.next();
add(attr);
}
}
break;
/* Then events we could output directly if necessary... but that
* make sense to route via stream writer, for validation
* purposes.
*/
case CHARACTERS: // better pass to stream writer, for prolog/epilog validation
{
Characters ch = event.asCharacters();
String text = ch.getData();
if (ch.isCData()) {
mWriter.writeCData(text);
} else {
mWriter.writeCharacters(text);
}
}
break;
case CDATA:
mWriter.writeCData(event.asCharacters().getData());
break;
case COMMENT:
mWriter.writeComment(((Comment) event).getText());
break;
case DTD:
mWriter.writeDTD(((DTD) event).getDocumentTypeDeclaration());
break;
case ENTITY_REFERENCE:
mWriter.writeEntityRef(((EntityReference) event).getName());
break;
case PROCESSING_INSTRUCTION: // let's just write directly
{
ProcessingInstruction pi = (ProcessingInstruction) event;
mWriter.writeProcessingInstruction(pi.getTarget(), pi.getData());
}
break;
case ENTITY_DECLARATION: // not yet produced by Wstx
case NOTATION_DECLARATION: // not yet produced by Wstx
case SPACE: // usually only CHARACTERS events exist...
default:
// Easy, if stax2 enabled
if (event instanceof XMLEvent2) {
((XMLEvent2) event).writeUsing(mWriter);
} else {
// Otherwise... well, no real way to do it in generic manner
throw new XMLStreamException("Don't know how to output event "+event);
}
}
}
public void add(XMLEventReader reader)
throws XMLStreamException
{
while (reader.hasNext()) {
add(reader.nextEvent());
}
}
public void close()
throws XMLStreamException
{
mWriter.close();
}
public void flush()
throws XMLStreamException
{
mWriter.flush();
}
public NamespaceContext getNamespaceContext() {
return mWriter.getNamespaceContext();
}
public String getPrefix(String uri)
throws XMLStreamException
{
return mWriter.getPrefix(uri);
}
public void setDefaultNamespace(String uri)
throws XMLStreamException
{
mWriter.setDefaultNamespace(uri);
}
public void setNamespaceContext(NamespaceContext ctxt)
throws XMLStreamException
{
mWriter.setNamespaceContext(ctxt);
}
public void setPrefix(String prefix, String uri)
throws XMLStreamException
{
mWriter.setPrefix(prefix, uri);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2FilteredStreamReader.java 100644 0 0 2547 11520453235 23303 0 ustar 0 0 package org.codehaus.stax2.ri;
import javax.xml.stream.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.util.StreamReader2Delegate;
/**
* Simple straight-forward implementation of a filtering stream reader,
* which can fully adapt Stax2 stream reader
* ({@link XMLStreamReader2}).
*/
public class Stax2FilteredStreamReader
extends StreamReader2Delegate
implements XMLStreamConstants
{
final StreamFilter mFilter;
public Stax2FilteredStreamReader(XMLStreamReader r, StreamFilter f)
{
super(Stax2ReaderAdapter.wrapIfNecessary(r));
mFilter = f;
}
/*
//////////////////////////////////////////////////////
// XMLStreamReader method overrides that we need
//////////////////////////////////////////////////////
*/
public int next()
throws XMLStreamException
{
int type;
do {
type = mDelegate2.next();
if (mFilter.accept(this)) {
break;
}
} while (type != END_DOCUMENT);
return type;
}
public int nextTag()
throws XMLStreamException
{
int type;
// Can be implemented very much like next()
while (true) {
type = mDelegate2.nextTag();
if (mFilter.accept(this)) {
break;
}
}
return type;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2LocationAdapter.java 100644 0 0 3011 11520453235 22302 0 ustar 0 0 package org.codehaus.stax2.ri;
import javax.xml.stream.Location;
import org.codehaus.stax2.XMLStreamLocation2;
/**
* Simple implementation of {@link XMLStreamLocation2}, which just
* wraps Stax 1.0 {@link Location} and adds no-operation implementation
* of the additions.
*/
public class Stax2LocationAdapter
implements XMLStreamLocation2
{
protected final Location mWrappedLocation;
protected final Location mParentLocation;
public Stax2LocationAdapter(Location loc)
{
this(loc, null);
}
public Stax2LocationAdapter(Location loc, Location parent)
{
mWrappedLocation = loc;
mParentLocation = parent;
}
// // // Basic Stax 1.0 implementation
public int getCharacterOffset()
{
return mWrappedLocation.getCharacterOffset();
}
public int getColumnNumber()
{
return mWrappedLocation.getColumnNumber();
}
public int getLineNumber()
{
return mWrappedLocation.getLineNumber();
}
public String getPublicId()
{
return mWrappedLocation.getPublicId();
}
public String getSystemId()
{
return mWrappedLocation.getSystemId();
}
// // // And stax2 additions
public XMLStreamLocation2 getContext()
{
if (mParentLocation == null) {
return null;
}
if (mParentLocation instanceof XMLStreamLocation2) {
return (XMLStreamLocation2) mParentLocation;
}
return new Stax2LocationAdapter(mParentLocation);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2ReaderAdapter.java 100644 0 0 103402 11520453235 22001 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.util.StreamReaderDelegate;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import org.codehaus.stax2.typed.TypedArrayDecoder;
import org.codehaus.stax2.typed.TypedValueDecoder;
import org.codehaus.stax2.typed.TypedXMLStreamException;
import org.codehaus.stax2.ri.Stax2Util;
import org.codehaus.stax2.ri.typed.StringBase64Decoder;
import org.codehaus.stax2.ri.typed.ValueDecoderFactory;
import org.codehaus.stax2.*;
import org.codehaus.stax2.validation.*;
/**
* This adapter implements parts of {@link XMLStreamReader2}, the
* extended stream reader defined by Stax2 extension, by wrapping
* a vanilla Stax 1.0 {@link XMLStreamReader} implementation.
*
* Note: the implementation is incomplete as-is, since not all
* features needed are accessible via basic Stax 1.0 interface.
* As such, two main use cases for this wrapper are:
*
* !!! TODO: should be possible to implement completely
*/
public abstract int readElementAsArray(TypedArrayDecoder dec)
throws XMLStreamException;
/*
////////////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, binary data
////////////////////////////////////////////////////////
*/
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException
{
return readElementAsBinary(Base64Variants.getDefaultVariant(), resultBuffer, offset, maxLength);
}
public abstract int readElementAsBinary(Base64Variant b64variant, byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, scalar attributes
///////////////////////////////////////////////////////////
*/
public abstract int getAttributeIndex(String namespaceURI, String localName);
public boolean getAttributeAsBoolean(int index) throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public int getAttributeAsInt(int index) throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public long getAttributeAsLong(int index) throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public float getAttributeAsFloat(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public double getAttributeAsDouble(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigInteger getAttributeAsInteger(int index) throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public QName getAttributeAsQName(int index) throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getAttributeAs(index, dec);
// !!! Should we try to verify validity of name chars?
return dec.getValue();
}
public void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException
{
String value = getAttributeValue(index);
try {
tvd.decode(value);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
public int[] getAttributeAsIntArray(int index) throws XMLStreamException
{
ValueDecoderFactory.IntArrayDecoder dec = _decoderFactory().getIntArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
public long[] getAttributeAsLongArray(int index) throws XMLStreamException
{
ValueDecoderFactory.LongArrayDecoder dec = _decoderFactory().getLongArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
public float[] getAttributeAsFloatArray(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatArrayDecoder dec = _decoderFactory().getFloatArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleArrayDecoder dec = _decoderFactory().getDoubleArrayDecoder();
getAttributeAsArray(index, dec);
return dec.getValues();
}
/**
* Actual implementation needs to implement tokenization.
*
* !!! TODO: should be possible to implement completely
*/
public abstract int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException;
public byte[] getAttributeAsBinary(int index) throws XMLStreamException
{
return getAttributeAsBinary(Base64Variants.getDefaultVariant(), index);
}
public abstract byte[] getAttributeAsBinary(Base64Variant v, int index) throws XMLStreamException;
/*
////////////////////////////////////////////////////
// Package methods
////////////////////////////////////////////////////
*/
protected ValueDecoderFactory _decoderFactory()
{
if (_decoderFactory == null) {
_decoderFactory = new ValueDecoderFactory();
}
return _decoderFactory;
}
protected TypedXMLStreamException _constructTypeException(IllegalArgumentException iae, String lexicalValue)
{
return new TypedXMLStreamException(lexicalValue, iae.getMessage(), getStartLocation(), iae);
}
/*
////////////////////////////////////////////////////
// Internal methods
////////////////////////////////////////////////////
*/
protected void throwUnsupported()
throws XMLStreamException
{
throw new XMLStreamException("Unsupported method");
}
protected void throwNotStartElem()
{
throw new IllegalStateException("Current state not START_ELEMENT");
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2Util.java 100644 0 0 20732 11520453235 20177 0 ustar 0 0 /* Stax2 API extension for Streaming Api for Xml processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri;
import javax.xml.stream.XMLStreamConstants;
public final class Stax2Util
implements XMLStreamConstants
{
private Stax2Util() { } // no instantiation
/**
* Method that converts given standard Stax event type into
* textual representation.
*/
public static String eventTypeDesc(int type)
{
switch (type) {
case START_ELEMENT:
return "START_ELEMENT";
case END_ELEMENT:
return "END_ELEMENT";
case START_DOCUMENT:
return "START_DOCUMENT";
case END_DOCUMENT:
return "END_DOCUMENT";
case CHARACTERS:
return "CHARACTERS";
case CDATA:
return "CDATA";
case SPACE:
return "SPACE";
case COMMENT:
return "COMMENT";
case PROCESSING_INSTRUCTION:
return "PROCESSING_INSTRUCTION";
case DTD:
return "DTD";
case ENTITY_REFERENCE:
return "ENTITY_REFERENCE";
}
return "["+type+"]";
}
/**
* Method called to trim leading and/or trailing space that given
* lexical value has.
*
* @return Trimmed value if
* Note that it is assumed that any "weird" white space
* (xml 1.1 LSEP and NEL) have been replaced by canonical
* alternatives (linefeed for element content, regular space
* for attributes)
*/
private final static boolean _isSpace(char c)
{
return ((int) c) <= 0x0020;
}
/**
* Helper class used to simplify text gathering while keeping
* at as efficient as possible.
*/
public final static class TextBuffer
{
private String mText = null;
/* !!! JDK 1.5: when we can upgrade to Java 5, can convert
* to using
* Note: the implementation is incomplete as-is, since not all
* features needed are accessible via basic Stax 1.0 interface.
* As such, two main use cases for this wrapper are:
*
* Note that the implementation is only to be used for use with
*
* Some notes regarding missing/incomplete functionality:
*
*/
protected List _attrList = null;
/**
* Lazily instantiated String pairs of all namespace declarations for the
* current (start/end) element. String pair means that for each
* declarations there are two Strings in the list: first one is prefix
* (empty String for the default namespace declaration), and second
* URI it is bound to.
*/
protected List _nsDeclList = null;
/**
* Factory used for constructing decoders we need for typed access
*/
protected ValueDecoderFactory _decoderFactory;
/**
* Lazily-constructed decoder object for decoding base64 encoded
* binary content.
*/
protected StringBase64Decoder _base64Decoder = null;
/*
////////////////////////////////////////////////////
// Construction, configuration
////////////////////////////////////////////////////
*/
/**
* @param src Node that is the tree of the DOM document, or fragment.
* @param nsAware Whether resulting reader should operate in namespace
* aware mode or not. Note that this should be compatible with
* settings for the DOM builder that produced DOM tree or fragment
* being operated on, otherwise results are not defined.
* @param coalescing Whether resulting reader should coalesce adjacent
* text events or not
*/
protected DOMWrappingReader(DOMSource src, boolean nsAware, boolean coalescing)
throws XMLStreamException
{
Node treeRoot = src.getNode();
if (treeRoot == null) {
throw new IllegalArgumentException("Can not pass null Node for constructing a DOM-based XMLStreamReader");
}
_cfgNsAware = nsAware;
_coalescing = coalescing;
_systemId = src.getSystemId();
/* Ok; we need a document node; or an element node; or a document
* fragment node.
*/
switch (treeRoot.getNodeType()) {
case Node.DOCUMENT_NODE: // fine
/* Should try to find encoding, version and stand-alone
* settings... but is there a standard way of doing that?
*/
case Node.ELEMENT_NODE: // can make sub-tree... ok
// But should we skip START/END_DOCUMENT? For now, let's not
case Node.DOCUMENT_FRAGMENT_NODE: // as with element...
// Above types are fine
break;
default: // other Nodes not usable
throw new XMLStreamException("Can not create an XMLStreamReader for a DOM node of type "+treeRoot.getClass());
}
_rootNode = _currNode = treeRoot;
}
protected void setInternNames(boolean state) { _cfgInternNames = state; }
protected void setInternNsURIs(boolean state) { _cfgInternNsURIs = state; }
/*
////////////////////////////////////////////////////
// Abstract methods for sub-classes to implement
////////////////////////////////////////////////////
*/
protected abstract void throwStreamException(String msg, Location loc)
throws XMLStreamException;
/*
////////////////////////////////////////////////////
// XMLStreamReader, document info
////////////////////////////////////////////////////
*/
/**
* As per Stax (1.0) specs, needs to return whatever xml declaration
* claimed encoding is, if any; or null if no xml declaration found.
*/
public String getCharacterEncodingScheme() {
/* No standard way to figure it out from a DOM Document node;
* have to return null
*/
return null;
}
/**
* As per Stax (1.0) specs, needs to return whatever parser determined
* the encoding was, if it was able to figure it out. If not (there are
* cases where this can not be found; specifically when being passed a
* {@link java.io.Reader}), it should return null.
*/
public String getEncoding() {
/* We have no information regarding underlying stream/Reader, so
* best we can do is to see if we know xml declaration encoding.
*/
return getCharacterEncodingScheme();
}
public String getVersion()
{
/* No standard way to figure it out from a DOM Document node;
* have to return null
*/
return null;
}
public boolean isStandalone() {
/* No standard way to figure it out from a DOM Document node;
* have to return false
*/
return false;
}
public boolean standaloneSet() {
/* No standard way to figure it out from a DOM Document node;
* have to return false
*/
return false;
}
/*
////////////////////////////////////////////////////
// Public API, configuration
////////////////////////////////////////////////////
*/
public abstract Object getProperty(String name);
// NOTE: getProperty() defined in Stax 1.0 interface
public abstract boolean isPropertySupported(String name);
/**
* @param name Name of the property to set
* @param value Value to set property to.
*
* @return True, if the specified property was succesfully
* set to specified value; false if its value was not changed
*/
public abstract boolean setProperty(String name, Object value);
/*
////////////////////////////////////////////////////
// XMLStreamReader, current state
////////////////////////////////////////////////////
*/
// // // Attribute access:
public int getAttributeCount()
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
return _attrList.size();
}
public String getAttributeLocalName(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
Attr attr = (Attr) _attrList.get(index);
return _internName(_safeGetLocalName(attr));
}
public QName getAttributeName(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
Attr attr = (Attr) _attrList.get(index);
return _constructQName(attr.getNamespaceURI(), _safeGetLocalName(attr), attr.getPrefix());
}
public String getAttributeNamespace(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
Attr attr = (Attr) _attrList.get(index);
return _internNsURI(attr.getNamespaceURI());
}
public String getAttributePrefix(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
Attr attr = (Attr) _attrList.get(index);
return _internName(attr.getPrefix());
}
public String getAttributeType(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
//Attr attr = (Attr) _attrList.get(index);
// First, a special case, ID... since it's potentially most useful
/* 26-Apr-2006, TSa: Turns out that following methods are
* DOM Level3, and as such not available in JDK 1.4 and prior.
* Thus, let's not yet use them (could use dynamic discovery
* for graceful downgrade)
*/
/*
if (attr.isId()) {
return "ID";
}
TypeInfo schemaType = attr.getSchemaTypeInfo();
return (schemaType == null) ? "CDATA" : schemaType.getTypeName();
*/
return "CDATA";
}
public String getAttributeValue(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
if (_attrList == null) {
_calcNsAndAttrLists(true);
}
if (index >= _attrList.size() || index < 0) {
handleIllegalAttrIndex(index);
return null;
}
Attr attr = (Attr) _attrList.get(index);
return attr.getValue();
}
public String getAttributeValue(String nsURI, String localName)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
Element elem = (Element) _currNode;
NamedNodeMap attrs = elem.getAttributes();
/* Hmmh. DOM javadocs claim "Per [XML Namespaces], applications
* must use the value null as the namespaceURI parameter for methods
* if they wish to have no namespace.".
* Not sure how true that is, but:
*/
if (nsURI != null && nsURI.length() == 0) {
nsURI = null;
}
Attr attr = (Attr) attrs.getNamedItemNS(nsURI, localName);
return (attr == null) ? null : attr.getValue();
}
/**
* From StAX specs:
*
* Note: as per StAX 1.0 specs, this method does NOT close the underlying
* input reader. That is, unless the new StAX2 property
* {@link org.codehaus.stax2.XMLInputFactory2#P_AUTO_CLOSE_INPUT} is
* set to true.
*/
public void close()
throws XMLStreamException
{
// Since DOM tree has no real input source, nothing to do
}
/*
////////////////////////////////////////////////////
// NamespaceContext
////////////////////////////////////////////////////
*/
public String getNamespaceURI(String prefix)
{
/* !!! 26-Apr-2006, TSa: Alas, these methods are DOM Level 3,
* i.e. require JDK 1.5 or higher
*/
/*
if (prefix.length() == 0) { // def NS
return _currNode.lookupNamespaceURI(null);
}
return _currNode.lookupNamespaceURI(prefix);
*/
return null;
}
public String getPrefix(String namespaceURI)
{
/* !!! 26-Apr-2006, TSa: Alas, these methods are DOM Level 3,
* i.e. require JDK 1.5 or higher
*/
/*
String prefix = _currNode.lookupPrefix(namespaceURI);
if (prefix == null) { // maybe default NS?
String defURI = _currNode.lookupNamespaceURI(null);
if (defURI != null && defURI.equals(namespaceURI)) {
return "";
}
}
return prefix;
*/
return null;
}
public Iterator getPrefixes(String namespaceURI)
{
String prefix = getPrefix(namespaceURI);
if (prefix == null) {
return EmptyIterator.getInstance();
}
return new SingletonIterator(prefix);
}
/*
/////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, element
/////////////////////////////////////////////////
*/
public boolean getElementAsBoolean() throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getElementAs(dec);
return dec.getValue();
}
public int getElementAsInt() throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getElementAs(dec);
return dec.getValue();
}
public long getElementAsLong() throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getElementAs(dec);
return dec.getValue();
}
public float getElementAsFloat() throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getElementAs(dec);
return dec.getValue();
}
public double getElementAsDouble() throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigInteger getElementAsInteger() throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigDecimal getElementAsDecimal() throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getElementAs(dec);
return dec.getValue();
}
public QName getElementAsQName() throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getElementAs(dec);
return dec.getValue();
}
public byte[] getElementAsBinary() throws XMLStreamException
{
return getElementAsBinary(Base64Variants.getDefaultVariant());
}
public byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException
{
// note: code here is similar to Base64DecoderBase.aggregateAll(), see comments there
Stax2Util.ByteAggregator aggr = _base64Decoder().getByteAggregator();
byte[] buffer = aggr.startAggregation();
while (true) {
int offset = 0;
int len = buffer.length;
do {
int readCount = readElementAsBinary(buffer, offset, len, v);
if (readCount < 1) { // all done!
return aggr.aggregateAll(buffer, offset);
}
offset += readCount;
len -= readCount;
} while (len > 0);
buffer = aggr.addFullBlock(buffer);
}
}
public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException
{
String value = getElementText();
value = Stax2Util.trimSpaces(value);
try {
if (value == null) {
tvd.handleEmptyValue();
} else {
tvd.decode(value);
}
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
public int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getIntArrayDecoder(value, from, length));
}
public int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getLongArrayDecoder(value, from, length));
}
public int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getFloatArrayDecoder(value, from, length));
}
public int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getDoubleArrayDecoder(value, from, length));
}
public int readElementAsArray(TypedArrayDecoder tad) throws XMLStreamException
{
/* Otherwise either we are just starting (START_ELEMENT), or
* have collected all the stuff into _textBuffer.
*/
if (_currEvent == START_ELEMENT) {
// One special case, no children:
Node fc = _currNode.getFirstChild();
if (fc == null) {
_currEvent = END_ELEMENT;
return -1;
}
_coalescedText = coalesceTypedText(fc);
_currEvent = CHARACTERS;
_currNode = _currNode.getLastChild();
} else {
if (_currEvent != CHARACTERS && _currEvent != CDATA) {
// Maybe we are already done?
if (_currEvent == END_ELEMENT) {
return -1;
}
reportWrongState(ERR_STATE_NOT_TEXTUAL_OR_ELEM);
}
/* One more thing: do we have the data? It is possible
* that caller has advanced to this text node by itself.
* We could handle this mostly ok; but that is not a supported
* use case as per Typed Access API definition (as it can not
* be reliably supported by all implementations), so:
*/
if (_coalescedText == null) {
throw new IllegalStateException("First call to readElementAsArray() must be for a START_ELEMENT, not directly for a textual event");
}
}
/* Otherwise, need to move pointer to point to the last
* child node, and fake that it was a textual node
*/
// Ok, so what do we have left?
String input = _coalescedText;
final int end = input.length();
int ptr = 0;
int count = 0;
String value = null;
try {
decode_loop:
while (ptr < end) {
// First, any space to skip?
while (input.charAt(ptr) <= INT_SPACE) {
if (++ptr >= end) {
break decode_loop;
}
}
// Then let's figure out non-space char (token)
int start = ptr;
++ptr;
while (ptr < end && input.charAt(ptr) > INT_SPACE) {
++ptr;
}
++count;
// And there we have it
value = input.substring(start, ptr);
// Plus, can skip trailing space (or at end, just beyond it)
++ptr;
if (tad.decodeValue(value)) {
break;
}
}
} catch (IllegalArgumentException iae) {
// Need to convert to a checked stream exception
/* Hmmh. This is not an accurate location... but it's
* about the best we can do
*/
Location loc = getLocation();
throw new TypedXMLStreamException(value, iae.getMessage(), loc, iae);
} finally {
int len = end-ptr;
_coalescedText = (len < 1) ? "" : input.substring(ptr);
}
if (count < 1) { // end
_currEvent = END_ELEMENT;
_currNode = _currNode.getParentNode();
return -1;
}
return count;
}
private String coalesceTypedText(Node firstNode)
throws XMLStreamException
{
/* This is a bit tricky as we have to collect all the
* text up end tag, but can not advance to END_ELEMENT
* event itself (except if there is no content)
*/
_textBuffer.reset();
_attrList = null; // so it will not get reused accidentally
for (Node n = firstNode; n != null; n = n.getNextSibling()) {
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
// Illegal to have child elements...
throwStreamException("Element content can not contain child START_ELEMENT when using Typed Access methods");
case Node.CDATA_SECTION_NODE:
case Node.TEXT_NODE:
_textBuffer.append(n.getNodeValue());
break;
case Node.COMMENT_NODE:
case Node.PROCESSING_INSTRUCTION_NODE:
break;
default:
// Otherwise... do we care? For now, let's do
throwStreamException("Unexpected DOM node type ("+n.getNodeType()+") when trying to decode Typed content");
}
}
return _textBuffer.get();
}
/*
////////////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, binary data
////////////////////////////////////////////////////////
*/
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException
{
return readElementAsBinary(resultBuffer, offset, maxLength, Base64Variants.getDefaultVariant());
}
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength,
Base64Variant v)
throws XMLStreamException
{
if (resultBuffer == null) {
throw new IllegalArgumentException("resultBuffer is null");
}
if (offset < 0) {
throw new IllegalArgumentException("Illegal offset ("+offset+"), must be [0, "+resultBuffer.length+"[");
}
if (maxLength < 1 || (offset + maxLength) > resultBuffer.length) {
if (maxLength == 0) { // special case, allowed, but won't do anything
return 0;
}
throw new IllegalArgumentException("Illegal maxLength ("+maxLength+"), has to be positive number, and offset+maxLength can not exceed"+resultBuffer.length);
}
final StringBase64Decoder dec = _base64Decoder();
int type = _currEvent;
// First things first: must be acceptable start state:
if (((1 << type) & MASK_TYPED_ACCESS_BINARY) == 0) {
if (type == END_ELEMENT) {
// Minor complication: may have unflushed stuff (non-padded versions)
if (!dec.hasData()) {
return -1;
}
} else {
reportWrongState(ERR_STATE_NOT_TEXTUAL_OR_ELEM);
}
}
// Are we just starting (START_ELEMENT)?
if (type == START_ELEMENT) {
// Just need to locate the first text segment (or reach END_ELEMENT)
while (true) {
type = next();
if (type == END_ELEMENT) {
// Simple... no textual content
return -1;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
reportParseProblem(ERR_STATE_NOT_TEXTUAL);
}
dec.init(v, true, getText());
break;
}
}
int totalCount = 0;
main_loop:
while (true) {
// Ok, decode:
int count;
try {
count = dec.decode(resultBuffer, offset, maxLength);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, "");
}
offset += count;
totalCount += count;
maxLength -= count;
/* And if we filled the buffer we are done. Or, an edge
* case: reached END_ELEMENT (for non-padded variant)
*/
if (maxLength < 1 || _currEvent == END_ELEMENT) {
break;
}
// Otherwise need to advance to the next event
while (true) {
type = next();
if (type == COMMENT || type == PROCESSING_INSTRUCTION
|| type == SPACE) { // space is ignorable too
continue;
}
if (type == END_ELEMENT) {
/* Just need to verify we don't have partial stuff
* (missing one to three characters of a full quartet
* that encodes 1 - 3 bytes). Also: non-padding
* variants can be in incomplete state, from which
* data may need to be flushed...
*/
int left = dec.endOfContent();
if (left < 0) { // incomplete, error
throw _constructTypeException("Incomplete base64 triplet at the end of decoded content", "");
} else if (left > 0) { // 1 or 2 more bytes of data, loop some more
continue main_loop;
}
// Otherwise, no more data, we are done
break main_loop;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
reportParseProblem(ERR_STATE_NOT_TEXTUAL);
}
dec.init(v, false, getText());
break;
}
}
// If nothing was found, needs to be indicated via -1, not 0
return (totalCount > 0) ? totalCount : -1;
}
/*
/////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, attribute
/////////////////////////////////////////////////
*/
public int getAttributeIndex(String namespaceURI, String localName)
{
return findAttributeIndex(namespaceURI, localName);
}
public boolean getAttributeAsBoolean(int index) throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public int getAttributeAsInt(int index) throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public long getAttributeAsLong(int index) throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public float getAttributeAsFloat(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public double getAttributeAsDouble(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigInteger getAttributeAsInteger(int index) throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public QName getAttributeAsQName(int index) throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getAttributeAs(index, dec);
return dec.getValue();
}
public final void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException
{
String value = getAttributeValue(index);
value = Stax2Util.trimSpaces(value);
try {
if (value == null) {
tvd.handleEmptyValue();
} else {
tvd.decode(value);
}
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
public int[] getAttributeAsIntArray(int index) throws XMLStreamException
{
ValueDecoderFactory.IntArrayDecoder dec = _decoderFactory().getIntArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public long[] getAttributeAsLongArray(int index) throws XMLStreamException
{
ValueDecoderFactory.LongArrayDecoder dec = _decoderFactory().getLongArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public float[] getAttributeAsFloatArray(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatArrayDecoder dec = _decoderFactory().getFloatArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleArrayDecoder dec = _decoderFactory().getDoubleArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException
{
return _getAttributeAsArray(tad, getAttributeValue(index));
}
protected int _getAttributeAsArray(TypedArrayDecoder tad, String attrValue) throws XMLStreamException
{
int ptr = 0;
int start = 0;
final int end = attrValue.length();
String lexical = null;
int count = 0;
try {
decode_loop:
while (ptr < end) {
// First, any space to skip?
while (attrValue.charAt(ptr) <= INT_SPACE) {
if (++ptr >= end) {
break decode_loop;
}
}
// Then let's figure out non-space char (token)
start = ptr;
++ptr;
while (ptr < end && attrValue.charAt(ptr) > INT_SPACE) {
++ptr;
}
int tokenEnd = ptr;
++ptr; // to skip trailing space (or, beyond end)
// And there we have it
lexical = attrValue.substring(start, tokenEnd);
++count;
if (tad.decodeValue(lexical)) {
if (!checkExpand(tad)) {
break;
}
}
}
} catch (IllegalArgumentException iae) {
// Need to convert to a checked stream exception
Location loc = getLocation();
throw new TypedXMLStreamException(lexical, iae.getMessage(), loc, iae);
}
return count;
}
/**
* Internal method used to see if we can expand the buffer that
* the array decoder has. Bit messy, but simpler than having
* separately typed instances; and called rarely so that performance
* downside of instanceof is irrelevant.
*/
private final boolean checkExpand(TypedArrayDecoder tad)
{
if (tad instanceof ValueDecoderFactory.BaseArrayDecoder) {
((ValueDecoderFactory.BaseArrayDecoder) tad).expand();
return true;
}
return false;
}
public byte[] getAttributeAsBinary(int index) throws XMLStreamException
{
return getAttributeAsBinary(index, Base64Variants.getDefaultVariant());
}
public byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException
{
String lexical = getAttributeValue(index);
final StringBase64Decoder dec = _base64Decoder();
dec.init(v, true, lexical);
try {
return dec.decodeCompletely();
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, lexical);
}
}
/*
////////////////////////////////////////////////////
// XMLStreamReader2 (StAX2) implementation
////////////////////////////////////////////////////
*/
// // // StAX2, per-reader configuration
public Object getFeature(String name)
{
// No readable features supported yet
throw new IllegalArgumentException("Unrecognized feature \""+name+"\"");
}
public void setFeature(String name, Object value)
{
throw new IllegalArgumentException("Unrecognized feature \""+name+"\"");
}
// // // StAX2, additional traversal methods
public void skipElement() throws XMLStreamException
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
int nesting = 1; // need one more end elements than start elements
while (true) {
int type = next();
if (type == START_ELEMENT) {
++nesting;
} else if (type == END_ELEMENT) {
if (--nesting == 0) {
break;
}
}
}
}
// // // StAX2, additional attribute access
public AttributeInfo getAttributeInfo() throws XMLStreamException
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
return this;
}
// AttributeInfo impl:
//public int getAttributeCount()
public int findAttributeIndex(String nsURI, String localName)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
Element elem = (Element) _currNode;
NamedNodeMap attrs = elem.getAttributes();
if (nsURI != null && nsURI.length() == 0) {
nsURI = null;
}
// Ugh. Horrible clumsy code. But has to do...
for (int i = 0, len = attrs.getLength(); i < len; ++i) {
Node attr = attrs.item(i);
String ln = _safeGetLocalName(attr);
if (localName.equals(ln)) {
String thisUri = attr.getNamespaceURI();
boolean isEmpty = (thisUri == null) || thisUri.length() == 0;
if (nsURI == null) {
if (isEmpty) {
return i;
}
} else {
if (!isEmpty && nsURI.equals(thisUri)) {
return i;
}
}
}
}
return -1;
}
public int getIdAttributeIndex()
{
// !!! TBI
// Note: will need Dom3 level support (JDK 1.5)
return -1;
}
public int getNotationAttributeIndex()
{
// !!! TBI
// Note: will need Dom3 level support (JDK 1.5)
return -1;
}
// // // StAX2, Additional DTD access
/**
* Since this class implements {@link DTDInfo}, method can just
* return
* TODO: try to optimize to allow completely streaming pass-through:
* currently will still read all data in memory buffers before
* outputting
*
* @param w Writer to use for writing textual contents
* @param preserveContents If true, reader has to preserve contents
* so that further calls to
* Note that the implementation is only to be used with
*
* Note: the implementation may be incomplete as-is, since not all
* features needed are necessarily accessible via basic Stax 1.0 interface.
* As such, two main use cases for this wrapper are:
*
* Some notes about implemention:
*
* General contract for encoding is that caller must call things
* in following sequence:
*
* Main restrictions for use are that value serializations must
* produce only 7-bit ascii characters, and that the value can
* be produced incrementally using limited size buffers. This
* is true for all current value types of the Typed Access API.
*
* Finally, details of how encoders are created and/or reused
* is outside scope of this public interface. Stax2 reference
* implementation handles this using an encoder factory
* that knows construction details.
*
* @since 3.0
*/
public abstract class AsciiValueEncoder
{
/**
* Constant used to determine when caller should flush buffer
* before calling encode methods. Strict minimum would be
* something like 22 (for floating point numbers), but let's
* pad it a bit.
*/
protected final static int MIN_CHARS_WITHOUT_FLUSH = 64;
protected AsciiValueEncoder() { }
/**
* Method called by writer to check if it should flush its
* output buffer (which has specified amount of free space)
* before encoder can encode more data. Flushing is only
* needed if (a) encoder has more data to output, and
* (b) free space is not enough to contain smallest
* segment of encoded value (individual array element
* or encoded primitive value).
*
* @param freeChars Amount of free space (in characters) in
* the output buffer
*
* @return True if encoder still has data to output and
* specified amount of free space is insufficient for
* encoding any more data
*/
public final boolean bufferNeedsFlush(int freeChars)
{
/* 25-Jun-2008, tatu: Although minimum ok sizes differ,
* let's simplify this a bit and use uniform threshold:
* it just needs to ensure that it's higher than any
* individual minimum would be. It may lead to more
* flushes, but overall shouldn't matter a whole lot.
* But removes need for sub-classes to implement it
*/
return (freeChars < MIN_CHARS_WITHOUT_FLUSH);
}
/**
* Method that can alternatively be called to determine whether encoder
* has encoded all data it has. Generally called right after
* a call to {@link #encodeMore}, to figure out whether buffer flush
* is needed (there is more data), or encoding is complete.
*/
public abstract boolean isCompleted();
/**
* @return Value of pointer after all remaining data (which
* may be "none") that can be encoded (as constrained by
* buffer length) has been encoded. Has to exceed 'ptr'
* value sent in; will be equal to it if nothing was
* encoded (which should only occur when everything has
* been encoded, as long as {@link #bufferNeedsFlush}
* is appropriately called once before calling this
* method)
*/
public abstract int encodeMore(char[] buffer, int ptr, int end);
/**
* @return Value of pointer after all remaining data (which
* may be "none") that can be encoded (as constrained by
* buffer length) has been encoded. Has to exceed 'ptr'
* value sent in; will be equal to it if nothing was
* encoded (which should only occur when everything has
* been encoded, as long as {@link #bufferNeedsFlush}
* is appropriately called once before calling this
* method)
*/
public abstract int encodeMore(byte[] buffer, int ptr, int end);
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/Base64DecoderBase.java 100644 0 0 23124 11520453235 22570 0 ustar 0 0 /* StAX2 extension for StAX API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.ri.Stax2Util;
/**
* Abstract base class used to share functionality between concrete
* base64 decoders.
*
* Mostly what follows is just shared definitions of the state machine
* states to use, but there is also shared convenience functionality
* for convenience decoding into simple byte arrays.
*/
abstract class Base64DecoderBase
{
// // // Constants for the simple state machine used for decoding
/**
* Initial state is where we start, and where white space
* is accepted.
*/
final static int STATE_INITIAL = 0;
/**
* State in which we have gotten one valid non-padding base64 encoded
* character
*/
final static int STATE_VALID_1 = 1;
/**
* State in which we have gotten two valid non-padding base64 encoded
* characters.
*/
final static int STATE_VALID_2 = 2;
/**
* State in which we have gotten three valid non-padding base64 encoded
* characters.
*/
final static int STATE_VALID_3 = 3;
/**
* State in which we have succesfully decoded a full triplet, but not
* yet output any characters
*/
final static int STATE_OUTPUT_3 = 4;
/**
* State in which we have 2 decoded bytes to output (either due to
* partial triplet, or having output one byte from full triplet).
*/
final static int STATE_OUTPUT_2 = 5;
/**
* State in which we have 1 decoded byte to output (either due to
* partial triplet, or having output some of decoded bytes earlier)
*/
final static int STATE_OUTPUT_1 = 6;
/**
* State in which we have gotten two valid non-padding base64 encoded
* characters, followed by a single padding character. This means
* that we must get one more padding character to be able to decode
* the single encoded byte
*/
final static int STATE_VALID_2_AND_PADDING = 7;
// // // Character constants
final static int INT_SPACE = 0x0020;
// // // Base64 variant info
/**
* Details of base64 variant (alphabet in use, padding, line length)
* are contained in and accessed via this object. It is passed
* through init methods.
*/
Base64Variant _variant;
// // // Decoding State
/**
* State of the state machine
*/
int _state = STATE_INITIAL;
/**
* Data decoded and/or ready to be output. Alignment and storage format
* depend on state: during decoding things are appended from lowest
* significant bits, and during output, flushed from more significant
* bytes.
*/
int _decodedData;
// // // Reused state for convenience byte[] accessors
Stax2Util.ByteAggregator _byteAggr = null;
/*
//////////////////////////////////////////////////////////////
// Life-cycle
//////////////////////////////////////////////////////////////
*/
protected Base64DecoderBase() { }
/*
//////////////////////////////////////////////////////////////
// Shared base API
//////////////////////////////////////////////////////////////
*/
/**
* Method that does actual decoding
*/
public abstract int decode(byte[] resultBuffer, int resultOffset, int maxLength)
throws IllegalArgumentException;
/**
* Method that can be called to check if this decoder is in has unflushed
* data ready to be returned.
*/
public final boolean hasData()
{
return (_state >= STATE_OUTPUT_3) && (_state <= STATE_OUTPUT_1);
}
/**
* Method called to indicate that we have no more encoded content to
* process, and decoding is to finish. Depending base64 variant in
* use, this means one of three things:
*
* Note: we'll increase value since Integer.MIN_VALUE can not
* actually be output using simple int-serialization mechanism
* (since its negation does not fit in 32-bit signed int range)
*/
private static long MIN_INT_AS_LONG = (long) (Integer.MIN_VALUE+1);
private static long MAX_INT_AS_LONG = (long) Integer.MAX_VALUE;
final static char[] LEADING_TRIPLETS = new char[4000];
final static char[] FULL_TRIPLETS = new char[4000];
static {
/* Let's fill it with NULLs for ignorable leading digits,
* and digit chars for others
*/
int ix = 0;
for (int i1 = 0; i1 < 10; ++i1) {
char f1 = (char) ('0' + i1);
char l1 = (i1 == 0) ? NULL_CHAR : f1;
for (int i2 = 0; i2 < 10; ++i2) {
char f2 = (char) ('0' + i2);
char l2 = (i1 == 0 && i2 == 0) ? NULL_CHAR : f2;
for (int i3 = 0; i3 < 10; ++i3) {
// Last is never to be empty
char f3 = (char) ('0' + i3);
LEADING_TRIPLETS[ix] = l1;
LEADING_TRIPLETS[ix+1] = l2;
LEADING_TRIPLETS[ix+2] = f3;
FULL_TRIPLETS[ix] = f1;
FULL_TRIPLETS[ix+1] = f2;
FULL_TRIPLETS[ix+2] = f3;
ix += 4;
}
}
}
}
/*
///////////////////////////////////////////////////////////////
// Public API
///////////////////////////////////////////////////////////////
*/
/**
*
* Note: caller must ensure that there is room for least 11 characters
* (leading sign, and up to 10 digits) in buffer passed.
*
* @return Offset within buffer after outputting int
*/
public static int writeInt(int value, char[] buffer, int offset)
{
if (value < 0) {
// In general, can just output sign, negate, handle as positives
if (value == Integer.MIN_VALUE) {
/* But one special case: no matching positive value within
* range; let's just output as long
*/
return writeLong((long) value, buffer, offset);
}
buffer[offset++] = '-';
value = -value;
}
if (value < MILLION) { // at most 2 triplets...
if (value < 1000) {
if (value < 10) {
buffer[offset++] = (char) ('0' + value);
} else {
offset = writeLeadingTriplet(value, buffer, offset);
}
} else {
int thousands = value / 1000;
value -= (thousands * 1000); // == value % 1000
offset = writeLeadingTriplet(thousands, buffer, offset);
offset = writeFullTriplet(value, buffer, offset);
}
return offset;
}
// ok, all 3 triplets included
/* Let's first hand possible billions separately before
* handling 3 triplets. This is possible since we know we
* can have at most '2' as billion count.
*/
boolean hasBillions = (value >= BILLION);
if (hasBillions) {
value -= BILLION;
if (value >= BILLION) {
value -= BILLION;
buffer[offset++] = '2';
} else {
buffer[offset++] = '1';
}
}
int newValue = value / 1000;
int ones = (value - (newValue * 1000)); // == value % 1000
value = newValue;
newValue /= 1000;
int thousands = (value - (newValue * 1000));
// value now has millions, which have 1, 2 or 3 digits
if (hasBillions) {
offset = writeFullTriplet(newValue, buffer, offset);
} else {
offset = writeLeadingTriplet(newValue, buffer, offset);
}
offset = writeFullTriplet(thousands, buffer, offset);
offset = writeFullTriplet(ones, buffer, offset);
return offset;
}
// Cut'n pasted from above
public static int writeInt(int value, byte[] buffer, int offset)
{
if (value < 0) {
if (value == Integer.MIN_VALUE) {
return writeLong((long) value, buffer, offset);
}
buffer[offset++] = BYTE_HYPHEN;
value = -value;
}
if (value < MILLION) {
if (value < 1000) {
if (value < 10) {
buffer[offset++] = (byte) ('0' + value);
} else {
offset = writeLeadingTriplet(value, buffer, offset);
}
} else {
int thousands = value / 1000;
value -= (thousands * 1000); // == value % 1000
offset = writeLeadingTriplet(thousands, buffer, offset);
offset = writeFullTriplet(value, buffer, offset);
}
return offset;
}
boolean hasBillions = (value >= BILLION);
if (hasBillions) {
value -= BILLION;
if (value >= BILLION) {
value -= BILLION;
buffer[offset++] = BYTE_2;
} else {
buffer[offset++] = BYTE_1;
}
}
int newValue = value / 1000;
int ones = (value - (newValue * 1000)); // == value % 1000
value = newValue;
newValue /= 1000;
int thousands = (value - (newValue * 1000));
// value now has millions, which have 1, 2 or 3 digits
if (hasBillions) {
offset = writeFullTriplet(newValue, buffer, offset);
} else {
offset = writeLeadingTriplet(newValue, buffer, offset);
}
offset = writeFullTriplet(thousands, buffer, offset);
offset = writeFullTriplet(ones, buffer, offset);
return offset;
}
/**
*
* Note: caller must ensure that there is room for least 21 characters
* (leading sign, and up to 20 digits ) in buffer passed.
*
* @return Offset within buffer after outputting int
*/
public static int writeLong(long value, char[] buffer, int offset)
{
// First: does it actually fit in an int?
if (value < 0L) {
if (value >= MIN_INT_AS_LONG) {
return writeInt((int) value, buffer, offset);
}
if (value == Long.MIN_VALUE) {
// Special case: no matching positive value within range
return getChars(String.valueOf(value), buffer, offset);
}
buffer[offset++] = '-';
value = -value;
} else {
if (value <= MAX_INT_AS_LONG) {
return writeInt((int) value, buffer, offset);
}
}
/* Ok: real long print. Need to first figure out length
* in characters, and then print in from end to beginning
*/
int origOffset = offset;
offset += calcLongStrLength(value);
int ptr = offset;
// First, with long arithmetics:
while (value > MAX_INT_AS_LONG) { // full triplet
ptr -= 3;
long newValue = value / THOUSAND_L;
int triplet = (int) (value - newValue * THOUSAND_L);
writeFullTriplet(triplet, buffer, ptr);
value = newValue;
}
// Then with int arithmetics:
int ivalue = (int) value;
while (ivalue >= 1000) { // still full triplet
ptr -= 3;
int newValue = ivalue / 1000;
int triplet = ivalue - (newValue * 1000);
writeFullTriplet(triplet, buffer, ptr);
ivalue = newValue;
}
// And finally, if anything remains, partial triplet
writeLeadingTriplet(ivalue, buffer, origOffset);
return offset;
}
// Cut'n pasted from above
public static int writeLong(long value, byte[] buffer, int offset)
{
if (value < 0L) {
if (value >= MIN_INT_AS_LONG) {
return writeInt((int) value, buffer, offset);
}
if (value == Long.MIN_VALUE) { // shouldn't be common...
return getAsciiBytes(String.valueOf(value), buffer, offset);
}
buffer[offset++] = BYTE_HYPHEN;
value = -value;
} else {
if (value <= MAX_INT_AS_LONG) {
return writeInt((int) value, buffer, offset);
}
}
int origOffset = offset;
offset += calcLongStrLength(value);
int ptr = offset;
while (value > MAX_INT_AS_LONG) { // full triplet
ptr -= 3;
long newValue = value / THOUSAND_L;
int triplet = (int) (value - newValue * THOUSAND_L);
writeFullTriplet(triplet, buffer, ptr);
value = newValue;
}
int ivalue = (int) value;
while (ivalue >= 1000) { // still full triplet
ptr -= 3;
int newValue = ivalue / 1000;
int triplet = ivalue - (newValue * 1000);
writeFullTriplet(triplet, buffer, ptr);
ivalue = newValue;
}
writeLeadingTriplet(ivalue, buffer, origOffset);
return offset;
}
public static int writeFloat(float value, char[] buffer, int offset)
{
// No real efficient method exposed by JDK, so let's keep it simple
return getChars(String.valueOf(value), buffer, offset);
}
public static int writeFloat(float value, byte[] buffer, int offset)
{
// No real efficient method exposed by JDK, so let's keep it simple
return getAsciiBytes(String.valueOf(value), buffer, offset);
}
public static int writeDouble(double value, char[] buffer, int offset)
{
// No real efficient method exposed by JDK, so let's keep it simple
return getChars(String.valueOf(value), buffer, offset);
}
public static int writeDouble(double value, byte[] buffer, int offset)
{
return getAsciiBytes(String.valueOf(value), buffer, offset);
}
/*
////////////////////////////////////////
// Internal methods
////////////////////////////////////////
*/
private static int writeLeadingTriplet(int triplet, char[] buffer, int offset)
{
int digitOffset = (triplet << 2);
char c = LEADING_TRIPLETS[digitOffset++];
if (c != NULL_CHAR) {
buffer[offset++] = c;
}
c = LEADING_TRIPLETS[digitOffset++];
if (c != NULL_CHAR) {
buffer[offset++] = c;
}
// Last is required to be non-empty
buffer[offset++] = LEADING_TRIPLETS[digitOffset];
return offset;
}
private static int writeLeadingTriplet(int triplet, byte[] buffer, int offset)
{
int digitOffset = (triplet << 2);
char c = LEADING_TRIPLETS[digitOffset++];
if (c != NULL_CHAR) {
buffer[offset++] = (byte) c;
}
c = LEADING_TRIPLETS[digitOffset++];
if (c != NULL_CHAR) {
buffer[offset++] = (byte) c;
}
// Last is required to be non-empty
buffer[offset++] = (byte) LEADING_TRIPLETS[digitOffset];
return offset;
}
private static int writeFullTriplet(int triplet, char[] buffer, int offset)
{
int digitOffset = (triplet << 2);
buffer[offset++] = FULL_TRIPLETS[digitOffset++];
buffer[offset++] = FULL_TRIPLETS[digitOffset++];
buffer[offset++] = FULL_TRIPLETS[digitOffset];
return offset;
}
private static int writeFullTriplet(int triplet, byte[] buffer, int offset)
{
int digitOffset = (triplet << 2);
buffer[offset++] = (byte)FULL_TRIPLETS[digitOffset++];
buffer[offset++] = (byte)FULL_TRIPLETS[digitOffset++];
buffer[offset++] = (byte)FULL_TRIPLETS[digitOffset];
return offset;
}
/**
*
* Pre-conditions: posValue is positive, and larger than
* Integer.MAX_VALUE (about 2 billions).
*/
private static int calcLongStrLength(long posValue)
{
int len = 10;
long comp = TEN_BILLION_L;
// 19 is longest, need to worry about overflow
while (posValue >= comp) {
if (len == 19) {
break;
}
++len;
comp = (comp << 3) + (comp << 1); // 10x
}
return len;
}
private static int getChars(String str, char[] buffer, int ptr)
{
int len = str.length();
str.getChars(0, len, buffer, ptr);
return ptr+len;
}
private static int getAsciiBytes(String str, byte[] buffer, int ptr)
{
for (int i = 0, len = str.length(); i < len; ++i) {
buffer[ptr++] = (byte) str.charAt(i);
}
return ptr;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/SimpleValueEncoder.java 100644 0 0 4257 11520453235 23177 0 ustar 0 0 package org.codehaus.stax2.ri.typed;
import org.codehaus.stax2.typed.Base64Variant;
/**
* Helper class used for serializing typed values to String. Mostly
* used for "non-native" stream writers; things like DOM-backed
* stream writer, or stax (v1) adapter.
*
* @author Tatu Saloranta
*/
public class SimpleValueEncoder
{
/**
* For efficient encoding, need a working buffer
*/
protected final char[] mBuffer = new char[500];
protected final ValueEncoderFactory mEncoderFactory;
public SimpleValueEncoder()
{
mEncoderFactory = new ValueEncoderFactory();
}
public String encodeAsString(int[] value, int from, int length)
{
return encode(mEncoderFactory.getEncoder(value, from, length));
}
public String encodeAsString(long[] value, int from, int length)
{
return encode(mEncoderFactory.getEncoder(value, from, length));
}
public String encodeAsString(float[] value, int from, int length)
{
return encode(mEncoderFactory.getEncoder(value, from, length));
}
public String encodeAsString(double[] value, int from, int length)
{
return encode(mEncoderFactory.getEncoder(value, from, length));
}
public String encodeAsString(Base64Variant v, byte[] value, int from, int length)
{
return encode(mEncoderFactory.getEncoder(v, value, from, length));
}
/*
///////////////////////////////////////////////////
// Internal methods
///////////////////////////////////////////////////
*/
protected String encode(AsciiValueEncoder enc)
{
// note: nothing in buffer, can't flush (thus no need to call to check)
int last = enc.encodeMore(mBuffer, 0, mBuffer.length);
if (enc.isCompleted()) { // fitted in completely?
return new String(mBuffer, 0, last);
}
// !!! TODO: with Java 5, use StringBuilder instead
StringBuffer sb = new StringBuffer(mBuffer.length << 1);
sb.append(mBuffer, 0, last);
do {
last = enc.encodeMore(mBuffer, 0, mBuffer.length);
sb.append(mBuffer, 0, last);
} while (!enc.isCompleted());
return sb.toString();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/StringBase64Decoder.java 100644 0 0 17014 11520453235 23165 0 ustar 0 0 /* StAX2 extension for StAX API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
import org.codehaus.stax2.typed.Base64Variant;
/**
* Base64 decoder that can be used to decode base64 encoded content that
* is passed as a Single string.
*/
public final class StringBase64Decoder
extends Base64DecoderBase
{
// // // Input buffer information
/**
* Base64 content String being currently processed.
*/
String _currSegment;
int _currSegmentPtr;
int _currSegmentEnd;
public StringBase64Decoder() { super(); }
public void init(Base64Variant variant, boolean firstChunk, String segment)
{
_variant = variant;
if (firstChunk) {
_state = STATE_INITIAL;
}
_currSegment = segment;
_currSegmentPtr = 0;
_currSegmentEnd = segment.length();
}
/**
* @param resultBuffer Buffer in which decoded bytes are returned
* @param resultOffset Offset that points to position to put the
* first decoded byte in maxLength Maximum number of bytes that can be returned
* in given buffer
*
* @return Number of bytes decoded and returned in the result buffer
*/
public int decode(byte[] resultBuffer, int resultOffset, int maxLength)
throws IllegalArgumentException
{
final int origResultOffset = resultOffset;
final int resultBufferEnd = resultOffset + maxLength;
main_loop:
while (true) {
switch (_state) {
case STATE_INITIAL:
// first, we'll skip preceding white space, if any
{
char ch;
do {
if (_currSegmentPtr >= _currSegmentEnd) {
break main_loop;
}
ch = _currSegment.charAt(_currSegmentPtr++);
} while (ch <= INT_SPACE);
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
throw reportInvalidChar(ch, 0);
}
_decodedData = bits;
}
// fall through, "fast" path
case STATE_VALID_1:
// then second base64 char; can't get padding yet, nor ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
_state = STATE_VALID_1; // to cover fall-through case
break main_loop;
}
char ch = _currSegment.charAt(_currSegmentPtr++);
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
throw reportInvalidChar(ch, 1);
}
_decodedData = (_decodedData << 6) | bits;
}
// fall through, "fast path"
case STATE_VALID_2:
// third base64 char; can be padding, but not ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
_state = STATE_VALID_2; // to cover fall-through case
break main_loop;
}
char ch = _currSegment.charAt(_currSegmentPtr++);
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
throw reportInvalidChar(ch, 2);
}
// Padding is off the "fast path", so:
_state = STATE_VALID_2_AND_PADDING;
continue main_loop;
}
_decodedData = (_decodedData << 6) | bits;
}
// fall through, "fast path"
case STATE_VALID_3:
// fourth and last base64 char; can be padding, but not ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
_state = STATE_VALID_3; // to cover fall-through case
break main_loop;
}
char ch = _currSegment.charAt(_currSegmentPtr++);
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
throw reportInvalidChar(ch, 3);
}
/* With padding we only get 2 bytes; but we have
* to shift it a bit so it is identical to triplet
* case with partial output.
* 3 chars gives 3x6 == 18 bits, of which 2 are
* dummies, need to discard:
*/
_decodedData >>= 2;
_state = STATE_OUTPUT_2;
continue main_loop;
}
// otherwise, our triple is now complete
_decodedData = (_decodedData << 6) | bits;
}
// still along fast path
case STATE_OUTPUT_3:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_3;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) (_decodedData >> 16);
// fall through
case STATE_OUTPUT_2:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_2;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) (_decodedData >> 8);
// fall through
case STATE_OUTPUT_1:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_1;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) _decodedData;
_state = STATE_INITIAL;
continue main_loop;
case STATE_VALID_2_AND_PADDING:
{
if (_currSegmentPtr >= _currSegmentEnd) {
// must have valid state already (can't get in via fall-through)
break main_loop;
}
char ch = _currSegment.charAt(_currSegmentPtr++);
if (!_variant.usesPaddingChar(ch)) {
throw reportInvalidChar(ch, 3, "expected padding character '='");
}
// Got 12 bits, only need 8, need to shift
_state = STATE_OUTPUT_1;
_decodedData >>= 4;
}
continue main_loop;
default:
// sanity check: should never happen
throw new IllegalStateException("Illegal internal state "+_state);
}
}
return resultOffset - origResultOffset;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/ValueDecoderFactory.java 100644 0 0 136413 11520453235 23403 0 ustar 0 0 /* Reference Implementation of
* Stax2 extension API (for basic Stax API, JSR-173)
*
* Copyright (c) 2008- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import org.codehaus.stax2.typed.TypedArrayDecoder;
import org.codehaus.stax2.typed.TypedValueDecoder;
/**
* Factory class used to construct all
* {@link org.codehaus.stax2.typed.TypedValueDecoder}
* (and {@link org.codehaus.stax2.typed.TypedArrayDecoder})
* instances needed by a
* single stream reader instance. Some decoders are also recycled
* (for the lifetime of an encoder, which is same as its owners,
* i.e. stream reader or writer's) to minimize overhead.
*
* Since encoders may be recycled, instances are not thread-safe.
*
* @since 3.0
*/
public final class ValueDecoderFactory
{
// // // Lazily-constructed, recycled decoder instances
// // // (only for simple commonly needed types)
protected BooleanDecoder mBooleanDecoder = null;
protected IntDecoder mIntDecoder = null;
protected LongDecoder mLongDecoder = null;
protected FloatDecoder mFloatDecoder = null;
protected DoubleDecoder mDoubleDecoder = null;
public ValueDecoderFactory() { }
/*
/////////////////////////////////////////////////////
// Factory methods, scalar decoders
/////////////////////////////////////////////////////
*/
public BooleanDecoder getBooleanDecoder()
{
if (mBooleanDecoder == null) {
mBooleanDecoder = new BooleanDecoder();
}
return mBooleanDecoder;
}
public IntDecoder getIntDecoder()
{
if (mIntDecoder == null) {
mIntDecoder = new IntDecoder();
}
return mIntDecoder;
}
public LongDecoder getLongDecoder()
{
if (mLongDecoder == null) {
mLongDecoder = new LongDecoder();
}
return mLongDecoder;
}
public FloatDecoder getFloatDecoder()
{
if (mFloatDecoder == null) {
mFloatDecoder = new FloatDecoder();
}
return mFloatDecoder;
}
public DoubleDecoder getDoubleDecoder()
{
if (mDoubleDecoder == null) {
mDoubleDecoder = new DoubleDecoder();
}
return mDoubleDecoder;
}
// // // Other scalar decoders: not recycled
public IntegerDecoder getIntegerDecoder() { return new IntegerDecoder(); }
public DecimalDecoder getDecimalDecoder() { return new DecimalDecoder(); }
public QNameDecoder getQNameDecoder(NamespaceContext nsc) {
return new QNameDecoder(nsc);
}
/*
/////////////////////////////////////////////////////
// Factory methods, array decoders
/////////////////////////////////////////////////////
*/
/**
* Method for constructing
* integer array value decoder
* that uses provided fixed array for storing results.
*/
public IntArrayDecoder getIntArrayDecoder(int[] result, int offset, int len)
{
return new IntArrayDecoder(result, offset, len, getIntDecoder());
}
/**
* Method for constructing
* integer array value decoder
* that automatically allocates and resizes result array as necessary.
*/
public IntArrayDecoder getIntArrayDecoder()
{
return new IntArrayDecoder(getIntDecoder());
}
public LongArrayDecoder getLongArrayDecoder(long[] result, int offset, int len)
{
return new LongArrayDecoder(result, offset, len, getLongDecoder());
}
public LongArrayDecoder getLongArrayDecoder()
{
return new LongArrayDecoder(getLongDecoder());
}
public FloatArrayDecoder getFloatArrayDecoder(float[] result, int offset, int len)
{
return new FloatArrayDecoder(result, offset, len, getFloatDecoder());
}
public FloatArrayDecoder getFloatArrayDecoder()
{
return new FloatArrayDecoder(getFloatDecoder());
}
public DoubleArrayDecoder getDoubleArrayDecoder(double[] result, int offset, int len)
{
return new DoubleArrayDecoder(result, offset, len, getDoubleDecoder());
}
public DoubleArrayDecoder getDoubleArrayDecoder()
{
return new DoubleArrayDecoder(getDoubleDecoder());
}
/*
/////////////////////////////////////////////////////
// Shared decoder base class
/////////////////////////////////////////////////////
*/
/**
* There are some things common to all textual decoders (like
* white space trimming).
*/
public abstract static class DecoderBase
extends TypedValueDecoder
{
final static long L_BILLION = 1000000000;
final static long L_MAX_INT = (long) Integer.MAX_VALUE;
final static long L_MIN_INT = (long) Integer.MIN_VALUE;
final static BigInteger BD_MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE);
final static BigInteger BD_MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE);
/**
* Pointer to the next character to check, within lexical value
*/
protected int mNextPtr;
protected DecoderBase() { }
public abstract String getType();
/**
* Method called if the value to decode does not contain
* any non-white space characters (including the case where
* typed accessor is called for an empty element).
*/
public void handleEmptyValue()
{
/* Defalt behavior for all types implemented within
* this class is to just throw an exception
*/
throw new IllegalArgumentException("Empty value (all white space) not a valid lexical representation of "+getType());
}
/*
//////////////////////////////////////////////////
// Shared methods, trimming
//////////////////////////////////////////////////
*/
/**
* Method called to check that remaining String consists of zero or
* more digits
*/
protected void verifyDigits(String lexical, int start, int end)
{
for (; start < end; ++start) {
char ch = lexical.charAt(start);
if (ch > '9' || ch < '0') {
throw constructInvalidValue(lexical);
}
}
}
protected void verifyDigits(char[] lexical, int start, int end, int ptr)
{
for (; ptr < end; ++ptr) {
char ch = lexical[ptr];
if (ch > '9' || ch < '0') {
throw constructInvalidValue(lexical, start, end);
}
}
}
/**
* @return Numeric value of the first non-zero character (or, in
* case of a zero value, zero)
*/
protected int skipSignAndZeroes(String lexical, char ch, boolean hasSign, final int end)
{
int ptr;
// Then optional sign
if (hasSign) {
ptr = 1;
if (ptr >= end) {
throw constructInvalidValue(lexical);
}
ch = lexical.charAt(ptr++);
} else {
ptr = 1;
}
// Has to start with a digit
int value = ch - '0';
if (value < 0 || value > 9) {
throw constructInvalidValue(lexical);
}
// Then, leading zero(es) to skip? (or just value zero itself)
while (value == 0 && ptr < end) {
int v2 = lexical.charAt(ptr) - '0';
if (v2 < 0 || v2 > 9) {
break;
}
++ptr;
value = v2;
}
mNextPtr = ptr;
return value;
}
protected int skipSignAndZeroes(char[] lexical, char ch, boolean hasSign, final int start, final int end)
{
int ptr = start+1;
if (hasSign) {
if (ptr >= end) {
throw constructInvalidValue(lexical, start, end);
}
ch = lexical[ptr++];
}
// Has to start with a digit
int value = ch - '0';
if (value < 0 || value > 9) {
throw constructInvalidValue(lexical, start, end);
}
// Then leading zero(es) to skip? (or just value zero itself)
while (value == 0 && ptr < end) {
int v2 = lexical[ptr] - '0';
if (v2 < 0 || v2 > 9) {
break;
}
++ptr;
value = v2;
}
mNextPtr = ptr;
return value;
}
/*
///////////////////////////////////////////////
// Shared methods, int conversions
///////////////////////////////////////////////
*/
/**
* Fast method for parsing integers that are known to fit into
* regular 32-bit signed int type. This means that length is
* between 1 and 9 digits (inclusive)
*
* @return Parsed integer value
*/
protected final static int parseInt(char[] digitChars, int start, int end)
{
/* This looks ugly, but appears to be the fastest way
* (based on perf testing, profiling)
*/
int num = digitChars[start] - '0';
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
}
}
}
}
}
}
}
}
return num;
}
protected final static int parseInt(int num, char[] digitChars, int start, int end)
{
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
if (++start < end) {
num = (num * 10) + (digitChars[start] - '0');
}
}
}
}
}
}
}
return num;
}
protected final static int parseInt(String digitChars, int start, int end)
{
int num = digitChars.charAt(start) - '0';
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
}
}
}
}
}
}
}
}
return num;
}
protected final static int parseInt(int num, String digitChars, int start, int end)
{
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
if (++start < end) {
num = (num * 10) + (digitChars.charAt(start) - '0');
}
}
}
}
}
}
}
return num;
}
protected final static long parseLong(char[] digitChars, int start, int end)
{
// Note: caller must ensure length is [10, 18]
int start2 = end-9;
long val = parseInt(digitChars, start, start2) * L_BILLION;
return val + (long) parseInt(digitChars, start2, end);
}
protected final static long parseLong(String digitChars, int start, int end)
{
// Note: caller must ensure length is [10, 18]
int start2 = end-9;
long val = parseInt(digitChars, start, start2) * L_BILLION;
return val + (long) parseInt(digitChars, start2, end);
}
/*
///////////////////////////////////////////////
// Shared methods, error reporting
///////////////////////////////////////////////
*/
protected IllegalArgumentException constructInvalidValue(String lexical)
{
// !!! Should we escape ctrl+chars etc?
return new IllegalArgumentException("Value \""+lexical+"\" not a valid lexical representation of "+getType());
}
protected IllegalArgumentException constructInvalidValue(char[] lexical, int startOffset, int end)
{
return new IllegalArgumentException("Value \""+lexicalDesc(lexical, startOffset, end)+"\" not a valid lexical representation of "+getType());
}
protected String lexicalDesc(char[] lexical, int startOffset, int end)
{
return _clean(new String(lexical, startOffset, end-startOffset));
}
protected String lexicalDesc(String lexical)
{
return _clean(lexical);
}
protected String _clean(String str)
{
// !!! Should we escape ctrl+chars etc?
return str.trim();
}
}
/*
/////////////////////////////////////////////////////
// Decoders, scalar primitives
/////////////////////////////////////////////////////
*/
public final static class BooleanDecoder
extends DecoderBase
{
protected boolean mValue;
public BooleanDecoder() { }
public String getType() { return "boolean"; }
public boolean getValue() { return mValue; }
public void decode(String lexical)
throws IllegalArgumentException
{
int len = lexical.length();
char c = lexical.charAt(0);
if (c == 't') {
if (len == 4
&& lexical.charAt(1) == 'r'
&& lexical.charAt(2) == 'u'
&& lexical.charAt(3) == 'e') {
mValue = true;
return;
}
} else if (c == 'f') {
if (len == 5
&& lexical.charAt(1) == 'a'
&& lexical.charAt(2) == 'l'
&& lexical.charAt(3) == 's'
&& lexical.charAt(4) == 'e') {
mValue = false;
return;
}
} else if (c == '0') {
if (len == 1) {
mValue = false;
return;
}
} else if (c == '1') {
if (len == 1) {
mValue = true;
return;
}
}
throw constructInvalidValue(lexical);
}
public void decode(char[] lexical, int start, int end)
throws IllegalArgumentException
{
// First, skip leading ws if any
int len = end-start;
char c = lexical[start];
if (c == 't') {
if (len == 4
&& lexical[start+1] == 'r'
&& lexical[start+2] == 'u'
&& lexical[start+3] == 'e') {
mValue = true;
return;
}
} else if (c == 'f') {
if (len == 5
&& lexical[start+1] == 'a'
&& lexical[start+2] == 'l'
&& lexical[start+3] == 's'
&& lexical[start+4] == 'e') {
mValue = false;
return;
}
} else if (c == '0') {
if (len == 1) {
mValue = false;
return;
}
} else if (c == '1') {
if (len == 1) {
mValue = true;
return;
}
}
throw constructInvalidValue(lexical, start, end);
}
}
public final static class IntDecoder
extends DecoderBase
{
protected int mValue;
public IntDecoder() { }
public String getType() { return "int"; }
public int getValue() { return mValue; }
public void decode(String lexical)
throws IllegalArgumentException
{
final int end = lexical.length();
char ch = lexical.charAt(0);
boolean neg = (ch == '-');
int nr;
if (neg || (ch == '+')) {
nr = skipSignAndZeroes(lexical, ch, true, end);
} else {
nr = skipSignAndZeroes(lexical, ch, false, end);
}
int ptr = mNextPtr;
// Otherwise, need to verify that is [digit*][ws*]
int charsLeft = end-ptr;
if (charsLeft == 0) {
mValue = neg ? -nr : nr;
return;
}
verifyDigits(lexical, ptr, end);
// Note: charsLeft one less than total length (skipped first digit)
if (charsLeft <= 8) { // no overflow
int i = parseInt(nr, lexical, ptr, ptr+charsLeft);
mValue = neg ? -i : i;
return;
}
// Otherwise, may have overflow
// Max 10 digits for a legal int
if (charsLeft == 9 && nr < 3) { // min/max is ~2 billion (+/-)
long base = L_BILLION;
if (nr == 2) {
base += L_BILLION;
}
int i = parseInt(lexical, ptr, ptr+charsLeft);
long l = base + (long) i;
if (neg) {
l = -l;
if (l >= L_MIN_INT) {
mValue = (int) l;
return;
}
} else {
if (l <= L_MAX_INT) {
mValue = (int) l;
return;
}
}
}
throw new IllegalArgumentException("value \""+lexicalDesc(lexical)+"\" not a valid 32-bit integer: overflow.");
}
public void decode(char[] lexical, final int start, final int end)
throws IllegalArgumentException
{
char ch = lexical[start];
boolean neg = (ch == '-');
int nr;
if (neg || (ch == '+')) {
nr = skipSignAndZeroes(lexical, ch, true, start, end);
} else {
nr = skipSignAndZeroes(lexical, ch, false, start, end);
}
int ptr = mNextPtr;
// Quick check for short (single-digit) values:
int charsLeft = end-ptr;
if (charsLeft == 0) {
mValue = neg ? -nr : nr;
return;
}
verifyDigits(lexical, start, end, ptr);
// Note: charsLeft one less than total length (skipped first digit)
// Can parse more cheaply, if it's really just an int...
if (charsLeft <= 8) { // no overflow
int i = parseInt(nr, lexical, ptr, ptr+charsLeft);
mValue = neg ? -i : i;
return;
}
// Otherwise, may have overflow
// Max 10 digits for a legal int
if (charsLeft == 9 && nr < 3) { // min/max is ~2 billion (+/-)
long base = L_BILLION;
if (nr == 2) {
base += L_BILLION;
}
int i = parseInt(lexical, ptr, ptr+charsLeft);
long l = base + (long) i;
if (neg) {
l = -l;
if (l >= L_MIN_INT) {
mValue = (int) l;
return;
}
} else {
if (l <= L_MAX_INT) {
mValue = (int) l;
return;
}
}
}
throw new IllegalArgumentException("value \""+lexicalDesc(lexical, start, end)+"\" not a valid 32-bit integer: overflow.");
}
}
public final static class LongDecoder
extends DecoderBase
{
protected long mValue;
public LongDecoder() { }
public String getType() { return "long"; }
public long getValue() { return mValue; }
public void decode(String lexical)
throws IllegalArgumentException
{
final int end = lexical.length();
char ch = lexical.charAt(0);
boolean neg = (ch == '-');
int nr;
if (neg || (ch == '+')) {
nr = skipSignAndZeroes(lexical, ch, true, end);
} else {
nr = skipSignAndZeroes(lexical, ch, false, end);
}
int ptr = mNextPtr;
// Quick check for short (single-digit) values:
int charsLeft = end-ptr;
if (charsLeft == 0) {
mValue = (long) (neg ? -nr : nr);
return;
}
verifyDigits(lexical, ptr, end);
// Note: charsLeft one less than total length (skipped first digit)
// Can parse more cheaply, if it's really just an int...
if (charsLeft <= 8) { // no overflow
int i = parseInt(nr, lexical, ptr, ptr+charsLeft);
mValue = (long) (neg ? -i : i);
return;
}
// At this point, let's just push back the first digit... simpler
--ptr;
++charsLeft;
// Still simple long?
if (charsLeft <= 18) {
long l = parseLong(lexical, ptr, ptr+charsLeft);
mValue = neg ? -l : l;
return;
}
/* Otherwise, let's just fallback to an expensive option,
* BigInteger. While relatively inefficient, it's simple
* to use, reliable etc.
*/
mValue = parseUsingBD(lexical.substring(ptr, ptr+charsLeft), neg);
}
public void decode(char[] lexical, final int start, final int end)
throws IllegalArgumentException
{
char ch = lexical[start];
boolean neg = (ch == '-');
int nr;
if (neg || (ch == '+')) {
nr = skipSignAndZeroes(lexical, ch, true, start, end);
} else {
nr = skipSignAndZeroes(lexical, ch, false, start, end);
}
int ptr = mNextPtr;
// Quick check for short (single-digit) values:
int charsLeft = end-ptr;
if (charsLeft == 0) {
mValue = (long) (neg ? -nr : nr);
return;
}
verifyDigits(lexical, start, end, ptr);
// Note: charsLeft one less than total length (skipped first digit)
// Can parse more cheaply, if it's really just an int...
if (charsLeft <= 8) { // no overflow
int i = parseInt(nr, lexical, ptr, ptr+charsLeft);
mValue = neg ? -i : i;
return;
}
// At this point, let's just push back the first digit... simpler
--ptr;
++charsLeft;
// Still simple long?
if (charsLeft <= 18) {
long l = parseLong(lexical, ptr, ptr+charsLeft);
mValue = neg ? -l : l;
return;
}
// Otherwise, let's just fallback to an expensive option
mValue = parseUsingBD(new String(lexical, ptr, charsLeft), neg);
}
private long parseUsingBD(String lexical, boolean neg)
{
BigInteger bi = new BigInteger(lexical);
// But we may over/underflow, let's check:
if (neg) {
bi = bi.negate();
if (bi.compareTo(BD_MIN_LONG) >= 0) {
return bi.longValue();
}
} else {
if (bi.compareTo(BD_MAX_LONG) <= 0) {
return bi.longValue();
}
}
throw new IllegalArgumentException("value \""+lexicalDesc(lexical)+"\" not a valid long: overflow.");
}
}
public final static class FloatDecoder
extends DecoderBase
{
protected float mValue;
public FloatDecoder() { }
public String getType() { return "float"; }
public float getValue() { return mValue; }
public void decode(String lexical)
throws IllegalArgumentException
{
/* Then, leading digit; or one of 3 well-known constants
* (INF, -INF, NaN)
*/
int len = lexical.length();
if (len == 3) {
char c = lexical.charAt(0);
if (c == 'I') {
if (lexical.charAt(1) == 'N' && lexical.charAt(2) == 'F') {
mValue = Float.POSITIVE_INFINITY;
return;
}
} else if (c == 'N') {
if (lexical.charAt(1) == 'a' && lexical.charAt(2) == 'N') {
mValue = Float.NaN;
return;
}
}
} else if (len == 4) {
char c = lexical.charAt(0);
if (c == '-') {
if (lexical.charAt(1) == 'I'
&& lexical.charAt(2) == 'N'
&& lexical.charAt(3) == 'F') {
mValue = Float.NEGATIVE_INFINITY;
return;
}
}
}
try {
mValue = Float.parseFloat(lexical);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexical);
}
}
public void decode(char[] lexical, int start, int end)
throws IllegalArgumentException
{
int len = end-start;
if (len == 3) {
char c = lexical[start];
if (c == 'I') {
if (lexical[start+1] == 'N' && lexical[start+2] == 'F') {
mValue = Float.POSITIVE_INFINITY;
return;
}
} else if (c == 'N') {
if (lexical[start+1] == 'a' && lexical[start+2] == 'N') {
mValue = Float.NaN;
return;
}
}
} else if (len == 4) {
char c = lexical[start];
if (c == '-') {
if (lexical[start+1] == 'I'
&& lexical[start+2] == 'N'
&& lexical[start+3] == 'F') {
mValue = Float.NEGATIVE_INFINITY;
return;
}
}
}
String lexicalStr = new String(lexical, start, len);
try {
mValue = Float.parseFloat(lexicalStr);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexicalStr);
}
}
}
public final static class DoubleDecoder
extends DecoderBase
{
protected double mValue;
public DoubleDecoder() { }
public String getType() { return "double"; }
public double getValue() { return mValue; }
public void decode(String lexical)
throws IllegalArgumentException
{
/* Then, leading digit; or one of 3 well-known constants
* (INF, -INF, NaN)
*/
int len = lexical.length();
if (len == 3) {
char c = lexical.charAt(0);
if (c == 'I') {
if (lexical.charAt(1) == 'N' && lexical.charAt(2) == 'F') {
mValue = Double.POSITIVE_INFINITY;
return;
}
} else if (c == 'N') {
if (lexical.charAt(1) == 'a' && lexical.charAt(2) == 'N') {
mValue = Double.NaN;
return;
}
}
} else if (len == 4) {
char c = lexical.charAt(0);
if (c == '-') {
if (lexical.charAt(1) == 'I'
&& lexical.charAt(2) == 'N'
&& lexical.charAt(3) == 'F') {
mValue = Double.NEGATIVE_INFINITY;
return;
}
}
}
try {
mValue = Double.parseDouble(lexical);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexical);
}
}
public void decode(char[] lexical, int start, int end)
throws IllegalArgumentException
{
int len = end-start;
if (len == 3) {
char c = lexical[start];
if (c == 'I') {
if (lexical[start+1] == 'N' && lexical[start+2] == 'F') {
mValue = Double.POSITIVE_INFINITY;
return;
}
} else if (c == 'N') {
if (lexical[start+1] == 'a' && lexical[start+2] == 'N') {
mValue = Double.NaN;
return;
}
}
} else if (len == 4) {
char c = lexical[start];
if (c == '-') {
if (lexical[start+1] == 'I'
&& lexical[start+2] == 'N'
&& lexical[start+3] == 'F') {
mValue = Double.NEGATIVE_INFINITY;
return;
}
}
}
String lexicalStr = new String(lexical, start, len);
try {
mValue = Double.parseDouble(lexicalStr);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexicalStr);
}
}
}
/*
/////////////////////////////////////////////////////
// Decoders, other scalars
/////////////////////////////////////////////////////
*/
public final static class IntegerDecoder
extends DecoderBase
{
protected BigInteger mValue;
public IntegerDecoder() { }
public String getType() { return "integer"; }
public BigInteger getValue() { return mValue; }
public void decode(String lexical) throws IllegalArgumentException
{
try {
mValue = new BigInteger(lexical);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexical);
}
}
public void decode(char[] lexical, int start, int end) throws IllegalArgumentException
{
String lexicalStr = new String(lexical, start, (end-start));
try {
mValue = new BigInteger(lexicalStr);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexicalStr);
}
}
}
public final static class DecimalDecoder
extends DecoderBase
{
protected BigDecimal mValue;
public DecimalDecoder() { }
public String getType() { return "decimal"; }
public BigDecimal getValue() { return mValue; }
public void decode(String lexical) throws IllegalArgumentException
{
try {
mValue = new BigDecimal(lexical);
} catch (NumberFormatException nex) {
throw constructInvalidValue(lexical);
}
}
public void decode(char[] lexical, int start, int end) throws IllegalArgumentException
{
int len = end-start;
try {
/* !!! 21-Nov-2008, TSa: This constructor was added in JDK1.5
* so can't yet be used (As of Woodstox 4.x).
* Need to use the older constructor for now
*/
//mValue = new BigDecimal(lexical, start, len);
mValue = new BigDecimal(new String(lexical, start, len));
} catch (NumberFormatException nex) {
throw constructInvalidValue(new String(lexical, start, len));
}
}
}
public final static class QNameDecoder
extends DecoderBase
{
final NamespaceContext mNsCtxt;
protected QName mValue;
public QNameDecoder(NamespaceContext nsc) {
mNsCtxt = nsc;
}
public String getType() { return "QName"; }
public QName getValue() { return mValue; }
public void decode(String lexical) throws IllegalArgumentException
{
int ix = lexical.indexOf(':');
if (ix >= 0) { // qualified name
mValue = resolveQName(lexical.substring(0, ix),
lexical.substring(ix+1));
} else {
mValue = resolveQName(lexical);
}
}
public void decode(char[] lexical, int start, int end) throws IllegalArgumentException
{
int i = start;
for (; i < end; ++i) {
if (lexical[i] == ':') {
mValue = resolveQName(new String(lexical, start, i-start),
new String(lexical, i+1, end-i-1));
return;
}
}
mValue = resolveQName(new String(lexical, start, end-start));
}
protected QName resolveQName(String localName) throws IllegalArgumentException
{
// No prefix -> default namespace ("element rules")
String uri = mNsCtxt.getNamespaceURI("");
if (uri == null) { // some impls may return null
uri = "";
}
return new QName(uri, localName);
}
protected QName resolveQName(String prefix, String localName)
throws IllegalArgumentException
{
if (prefix.length() == 0 || localName.length() == 0) {
// either prefix or local name is empty String, illegal
throw constructInvalidValue(prefix+":"+localName);
}
/* Explicit prefix, must map to a bound namespace; and that
* namespace can not be empty (only "no prefix", i.e. 'default
* namespace' has empty URI)
*/
String uri = mNsCtxt.getNamespaceURI(prefix);
if (uri == null || uri.length() == 0) {
throw new IllegalArgumentException("Value \""+lexicalDesc(prefix+":"+localName)+"\" not a valid QName: prefix '"+prefix+"' not bound to a namespace");
}
return new QName(uri, localName, prefix);
}
}
/*
/////////////////////////////////////////////////////
// Decoders, array
/////////////////////////////////////////////////////
*/
/**
* Intermediate shared base class for token array decoders.
* The most important additional part is the abstract method
* that can be used to expand storage space; this is needed
* when decoding attribute values when all values must fit
* in the result array.
*/
public abstract static class BaseArrayDecoder
extends TypedArrayDecoder
{
/**
* Let's use some modest array size for allocating initial
* result buffer
*/
protected final static int INITIAL_RESULT_BUFFER_SIZE = 40;
/**
* When expanding 'small' result buffers, we will expand
* size by bigger factor than for larger ones.
*/
protected final static int SMALL_RESULT_BUFFER_SIZE = 4000;
protected int mStart;
protected int mEnd;
protected int mCount = 0;
protected BaseArrayDecoder(int start, int maxCount)
{
mStart = start;
// First, sanity check
if (maxCount < 1) {
throw new IllegalArgumentException("Number of elements to read can not be less than 1");
}
mEnd = maxCount;
}
public final int getCount() { return mCount; }
public final boolean hasRoom() { return mCount < mEnd; }
/**
* Method that can be called if the internal result buffer
* fills up (when {@link #hasRoom} returns false) and
* will expand result buffer to hold at least one more value.
*/
public abstract void expand();
protected int calcNewSize(int currSize)
{
if (currSize < SMALL_RESULT_BUFFER_SIZE) {
return currSize << 2; // 4 x current for small bufs
}
return currSize+currSize; // 2x for bigger
}
}
public final static class IntArrayDecoder
extends BaseArrayDecoder
{
int[] mResult;
final IntDecoder mDecoder;
/**
* Constructor used for constructing decoders with fixed pre-allocated
* result buffer.
*/
public IntArrayDecoder(int[] result, int start, int maxCount,
IntDecoder intDecoder)
{
super(start, maxCount);
mResult = result;
mDecoder = intDecoder;
}
/**
* Constructor used for constructing decoders with automatically
* adjusting result buffer
*/
public IntArrayDecoder(IntDecoder intDecoder)
{
super(0, INITIAL_RESULT_BUFFER_SIZE);
mResult = new int[INITIAL_RESULT_BUFFER_SIZE];
mDecoder = intDecoder;
}
public void expand()
{
int[] old = mResult;
int oldLen = old.length;
int newSize = calcNewSize(oldLen);
mResult = new int[newSize];
System.arraycopy(old, mStart, mResult, 0, oldLen);
mStart = 0;
mEnd = newSize;
}
public int[] getValues()
{
int[] result = new int[mCount];
// !!! TBI: with JDK 6, use Arrays.copyOf:
System.arraycopy(mResult, mStart, result, 0, mCount);
return result;
}
public boolean decodeValue(String input) throws IllegalArgumentException
{
mDecoder.decode(input);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
public boolean decodeValue(char[] buffer, int start, int end) throws IllegalArgumentException
{
mDecoder.decode(buffer, start, end);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
}
public final static class LongArrayDecoder
extends BaseArrayDecoder
{
long[] mResult;
final LongDecoder mDecoder;
public LongArrayDecoder(long[] result, int start, int maxCount,
LongDecoder longDecoder)
{
super(start, maxCount);
mResult = result;
mDecoder = longDecoder;
}
public LongArrayDecoder(LongDecoder longDecoder)
{
super(0, INITIAL_RESULT_BUFFER_SIZE);
mResult = new long[INITIAL_RESULT_BUFFER_SIZE];
mDecoder = longDecoder;
}
public void expand()
{
long[] old = mResult;
int oldLen = old.length;
int newSize = calcNewSize(oldLen);
mResult = new long[newSize];
System.arraycopy(old, mStart, mResult, 0, oldLen);
mStart = 0;
mEnd = newSize;
}
public long[] getValues()
{
long[] result = new long[mCount];
System.arraycopy(mResult, mStart, result, 0, mCount);
return result;
}
public boolean decodeValue(String input) throws IllegalArgumentException
{
mDecoder.decode(input);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
public boolean decodeValue(char[] buffer, int start, int end) throws IllegalArgumentException
{
mDecoder.decode(buffer, start, end);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
}
public final static class FloatArrayDecoder
extends BaseArrayDecoder
{
float[] mResult;
final FloatDecoder mDecoder;
public FloatArrayDecoder(float[] result, int start, int maxCount,
FloatDecoder floatDecoder)
{
super(start, maxCount);
mResult = result;
mDecoder = floatDecoder;
}
public FloatArrayDecoder(FloatDecoder floatDecoder)
{
super(0, INITIAL_RESULT_BUFFER_SIZE);
mResult = new float[INITIAL_RESULT_BUFFER_SIZE];
mDecoder = floatDecoder;
}
public void expand()
{
float[] old = mResult;
int oldLen = old.length;
int newSize = calcNewSize(oldLen);
mResult = new float[newSize];
System.arraycopy(old, mStart, mResult, 0, oldLen);
mStart = 0;
mEnd = newSize;
}
public float[] getValues()
{
float[] result = new float[mCount];
System.arraycopy(mResult, mStart, result, 0, mCount);
return result;
}
public boolean decodeValue(String input) throws IllegalArgumentException
{
mDecoder.decode(input);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
public boolean decodeValue(char[] buffer, int start, int end) throws IllegalArgumentException
{
mDecoder.decode(buffer, start, end);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
}
public final static class DoubleArrayDecoder
extends BaseArrayDecoder
{
double[] mResult;
final DoubleDecoder mDecoder;
public DoubleArrayDecoder(double[] result, int start, int maxCount,
DoubleDecoder doubleDecoder)
{
super(start, maxCount);
mResult = result;
mDecoder = doubleDecoder;
}
public DoubleArrayDecoder(DoubleDecoder doubleDecoder)
{
super(0, INITIAL_RESULT_BUFFER_SIZE);
mResult = new double[INITIAL_RESULT_BUFFER_SIZE];
mDecoder = doubleDecoder;
}
public void expand()
{
double[] old = mResult;
int oldLen = old.length;
int newSize = calcNewSize(oldLen);
mResult = new double[newSize];
System.arraycopy(old, mStart, mResult, 0, oldLen);
mStart = 0;
mEnd = newSize;
}
public double[] getValues()
{
double[] result = new double[mCount];
System.arraycopy(mResult, mStart, result, 0, mCount);
return result;
}
public boolean decodeValue(String input) throws IllegalArgumentException
{
mDecoder.decode(input);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
public boolean decodeValue(char[] buffer, int start, int end) throws IllegalArgumentException
{
mDecoder.decode(buffer, start, end);
mResult[mStart+mCount] = mDecoder.getValue();
return (++mCount >= mEnd);
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/ValueEncoderFactory.java 100644 0 0 45224 11520453235 23374 0 ustar 0 0 /* Reference Implementation of
* Stax2 extension API (for basic Stax API, JSR-173)
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
import org.codehaus.stax2.typed.Base64Variant;
/**
* Factory class used to construct all
* {@link AsciiValueEncoder} instances needed by a single
* stream writer instance. Simple encoders are also recycled
* (for the lifetime of an encoder, which is same as its owners,
* i.e. stream reader or writer's) to minimize overhead.
* More complex ones (array based, long string) are not recycled.
*
* Since encoders are recycled, instances are not thread-safe.
*
* @since 3.0
*/
public final class ValueEncoderFactory
{
final static byte BYTE_SPACE = (byte) ' ';
// // // Lazily-constructed, recycled encoder instances
protected TokenEncoder _tokenEncoder = null;
protected IntEncoder _intEncoder = null;
protected LongEncoder _longEncoder = null;
protected FloatEncoder _floatEncoder = null;
protected DoubleEncoder _doubleEncoder = null;
public ValueEncoderFactory() { }
// // // Scalar encoder access
public ScalarEncoder getScalarEncoder(String value)
{
// Short or long?
if (value.length() > AsciiValueEncoder.MIN_CHARS_WITHOUT_FLUSH) { // short
if (_tokenEncoder == null) {
_tokenEncoder = new TokenEncoder();
}
_tokenEncoder.reset(value);
return _tokenEncoder;
}
// Nope, long: need segmented
return new StringEncoder(value);
}
public ScalarEncoder getEncoder(boolean value)
{
// !!! TBI: optimize
return getScalarEncoder(value ? "true" : "false");
}
public IntEncoder getEncoder(int value)
{
if (_intEncoder == null) {
_intEncoder = new IntEncoder();
}
_intEncoder.reset(value);
return _intEncoder;
}
public LongEncoder getEncoder(long value)
{
if (_longEncoder == null) {
_longEncoder = new LongEncoder();
}
_longEncoder.reset(value);
return _longEncoder;
}
public FloatEncoder getEncoder(float value)
{
if (_floatEncoder == null) {
_floatEncoder = new FloatEncoder();
}
_floatEncoder.reset(value);
return _floatEncoder;
}
public DoubleEncoder getEncoder(double value)
{
if (_doubleEncoder == null) {
_doubleEncoder = new DoubleEncoder();
}
_doubleEncoder.reset(value);
return _doubleEncoder;
}
// // // Array encoder access
public IntArrayEncoder getEncoder(int[] values, int from, int length)
{
return new IntArrayEncoder(values, from, from+length);
}
public LongArrayEncoder getEncoder(long[] values, int from, int length)
{
return new LongArrayEncoder(values, from, from+length);
}
public FloatArrayEncoder getEncoder(float[] values, int from, int length)
{
return new FloatArrayEncoder(values, from, from+length);
}
public DoubleArrayEncoder getEncoder(double[] values, int from, int length)
{
return new DoubleArrayEncoder(values, from, from+length);
}
// // // And special one for Base64
public Base64Encoder getEncoder(Base64Variant v, byte[] data, int from, int length)
{
return new Base64Encoder(v, data, from, from+length);
}
/*
////////////////////////////////////////////////////////////////
// Implementation classes; first, scalar (single-value) encoders
////////////////////////////////////////////////////////////////
*/
/**
* Intermediate base class for encoders that deal with single
* primitive values.
*
* No default implementations, because textual and typed
* (non-textual) sub-classes differ significantly.
* In a way, this is just a tag class
*/
abstract static class ScalarEncoder
extends AsciiValueEncoder
{
protected ScalarEncoder() { }
}
/**
* Implementation of textual encoder that operates on short
* textual values ("tokens"). As such, it can count on being able
* to output the whole output in one pass, without tracking
* location
*/
final static class TokenEncoder
extends ScalarEncoder
{
String _value;
protected TokenEncoder() { super(); }
protected void reset(String value) {
_value = value;
}
public boolean isCompleted() { return (_value == null); }
public int encodeMore(char[] buffer, int ptr, int end)
{
String str = _value;
_value = null;
int len = str.length();
str.getChars(0, len, buffer, ptr);
ptr += len;
return ptr;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
String str = _value;
_value = null;
int len = str.length();
for (int i = 0; i < len; ++i) {
buffer[ptr++] = (byte) str.charAt(i);
}
return ptr;
}
}
/**
* Implementation of textual encoder that operates on longer
* textual values. Because of length, it is possible that output
* has to be done in multiple pieces. As a result, there is need
* to track current position withing text.
*
* In addition, instances of this class are not recycled, as
* it seems less beneficial (less likely to need to be reused,
* or offer performance improvements if they would be)
*/
final static class StringEncoder
extends ScalarEncoder
{
String _value;
int _offset;
protected StringEncoder(String value) {
super();
_value = value;
}
public boolean isCompleted() { return (_value == null); }
public int encodeMore(char[] buffer, int ptr, int end)
{
int left = _value.length() - _offset;
int free = end-ptr;
if (free >= left) { // completed, simple
_value.getChars(_offset, left, buffer, ptr);
_value = null;
return (ptr+left);
}
_value.getChars(_offset, free, buffer, ptr);
_offset += free;
return end;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
int left = _value.length() - _offset;
int free = end-ptr;
if (free >= left) { // completed, simple
String str = _value;
_value = null;
for (int last = str.length(), offset = _offset; offset < last; ++offset) {
buffer[ptr++] = (byte) str.charAt(offset);
}
return ptr;
}
for (; ptr < end; ++ptr) {
buffer[ptr] = (byte) _value.charAt(_offset++);
}
return ptr;
}
}
/**
* Intermediate base class for typed (non-textual) scalar values
*/
abstract static class TypedScalarEncoder
extends ScalarEncoder
{
protected TypedScalarEncoder() { }
/**
* Since scalar typed values are guaranteed to always be
* written in one go, they will always be completed by
* time method is called./
*/
public final boolean isCompleted() { return true; }
}
final static class IntEncoder
extends TypedScalarEncoder
{
int _value;
protected IntEncoder() { super(); }
protected void reset(int value) {
_value = value;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
return NumberUtil.writeInt(_value, buffer, ptr);
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
return NumberUtil.writeInt(_value, buffer, ptr);
}
}
final static class LongEncoder
extends TypedScalarEncoder
{
long _value;
protected LongEncoder() { super(); }
protected void reset(long value) {
_value = value;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
return NumberUtil.writeLong(_value, buffer, ptr);
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
return NumberUtil.writeLong(_value, buffer, ptr);
}
}
final static class FloatEncoder
extends TypedScalarEncoder
{
float _value;
protected FloatEncoder() { super(); }
protected void reset(float value) {
_value = value;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
return NumberUtil.writeFloat(_value, buffer, ptr);
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
return NumberUtil.writeFloat(_value, buffer, ptr);
}
}
final static class DoubleEncoder
extends TypedScalarEncoder
{
double _value;
protected DoubleEncoder() { super(); }
protected void reset(double value) {
_value = value;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
return NumberUtil.writeDouble(_value, buffer, ptr);
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
return NumberUtil.writeDouble(_value, buffer, ptr);
}
}
/*
////////////////////////////////////////////////////////////////
// Implementation classes; array encoders
////////////////////////////////////////////////////////////////
*/
/**
* Intermediate base class for encoders that deal with arrays
* of values.
*/
abstract static class ArrayEncoder
extends AsciiValueEncoder
{
int _ptr;
final int _end;
protected ArrayEncoder(int ptr, int end)
{
_ptr = ptr;
_end = end;
}
public final boolean isCompleted() { return (_ptr >= _end); }
public abstract int encodeMore(char[] buffer, int ptr, int end);
}
/**
* Concrete implementation used for encoding int[] content.
*/
final static class IntArrayEncoder
extends ArrayEncoder
{
final int[] _values;
protected IntArrayEncoder(int[] values, int from, int length)
{
super(from, length);
_values = values;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_INT_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = ' ';
ptr = NumberUtil.writeInt(_values[_ptr++], buffer, ptr);
}
return ptr;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_INT_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = BYTE_SPACE;
ptr = NumberUtil.writeInt(_values[_ptr++], buffer, ptr);
}
return ptr;
}
}
final static class LongArrayEncoder
extends ArrayEncoder
{
final long[] _values;
protected LongArrayEncoder(long[] values, int from, int length)
{
super(from, length);
_values = values;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_LONG_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = ' ';
ptr = NumberUtil.writeLong(_values[_ptr++], buffer, ptr);
}
return ptr;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_LONG_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = BYTE_SPACE;
ptr = NumberUtil.writeLong(_values[_ptr++], buffer, ptr);
}
return ptr;
}
}
final static class FloatArrayEncoder
extends ArrayEncoder
{
final float[] _values;
protected FloatArrayEncoder(float[] values, int from, int length)
{
super(from, length);
_values = values;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_FLOAT_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = ' ';
ptr = NumberUtil.writeFloat(_values[_ptr++], buffer, ptr);
}
return ptr;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_FLOAT_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = BYTE_SPACE;
ptr = NumberUtil.writeFloat(_values[_ptr++], buffer, ptr);
}
return ptr;
}
}
final static class DoubleArrayEncoder
extends ArrayEncoder
{
final double[] _values;
protected DoubleArrayEncoder(double[] values, int from, int length)
{
super(from, length);
_values = values;
}
public int encodeMore(char[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_DOUBLE_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = ' ';
ptr = NumberUtil.writeDouble(_values[_ptr++], buffer, ptr);
}
return ptr;
}
public int encodeMore(byte[] buffer, int ptr, int end)
{
int lastOk = end - (1+NumberUtil.MAX_DOUBLE_CLEN);
while (ptr <= lastOk && _ptr < _end) {
buffer[ptr++] = BYTE_SPACE;
ptr = NumberUtil.writeDouble(_values[_ptr++], buffer, ptr);
}
return ptr;
}
}
/*
////////////////////////////////////////////////////////////////
// Implementation classes: binary (base64) encoder
////////////////////////////////////////////////////////////////
*/
final static class Base64Encoder
extends AsciiValueEncoder
{
final static char PAD_CHAR = '=';
final static byte PAD_BYTE = (byte) PAD_CHAR;
/* Hmmh. Base64 specs suggest \r\n... but for xml, \n is the
* canonical one. Let's take xml's choice here, more compact too.
*/
final static byte LF_CHAR = '\n';
final static byte LF_BYTE = (byte) LF_CHAR;
final Base64Variant _variant;
final byte[] _input;
int _inputPtr;
final int _inputEnd;
/**
* We need a counter to know when to add mandatory
* linefeed.
*/
int _chunksBeforeLf;
protected Base64Encoder(Base64Variant v, byte[] values, int from, int end)
{
_variant = v;
_input = values;
_inputPtr = from;
_inputEnd = end;
_chunksBeforeLf = _variant.getMaxLineLength() >> 2;
}
public boolean isCompleted() { return (_inputPtr >= _inputEnd); }
public int encodeMore(char[] buffer, int outPtr, int outEnd)
{
// Encoding is by chunks of 3 input, 4 output chars, so:
int inEnd = _inputEnd-3;
// But let's also reserve room for lf char
outEnd -= 5;
while (_inputPtr <= inEnd) {
if (outPtr > outEnd) { // no more room: need to return for flush
return outPtr;
}
// First, mash 3 bytes into lsb of 32-bit int
int b24 = ((int) _input[_inputPtr++]) << 8;
b24 |= ((int) _input[_inputPtr++]) & 0xFF;
b24 = (b24 << 8) | (((int) _input[_inputPtr++]) & 0xFF);
outPtr = _variant.encodeBase64Chunk(b24, buffer, outPtr);
if (--_chunksBeforeLf <= 0) {
buffer[outPtr++] = LF_CHAR;
_chunksBeforeLf = _variant.getMaxLineLength() >> 2;
}
}
// main stuff done, any partial data to output?
int inputLeft = (_inputEnd-_inputPtr); // 0, 1 or 2
if (inputLeft > 0) { // yes, but do we have room for output?
if (outPtr <= outEnd) { // yup (and we do have room for it all)
int b24 = ((int) _input[_inputPtr++]) << 16;
if (inputLeft == 2) {
b24 |= (((int) _input[_inputPtr++]) & 0xFF) << 8;
}
outPtr = _variant.encodeBase64Partial(b24, inputLeft, buffer, outPtr);
}
}
return outPtr;
}
public int encodeMore(byte[] buffer, int outPtr, int outEnd)
{
int inEnd = _inputEnd-3;
outEnd -= 5;
while (_inputPtr <= inEnd) {
if (outPtr > outEnd) { // no more room: need to return for flush
return outPtr;
}
// First, mash 3 bytes into lsb of 32-bit int
int b24 = ((int) _input[_inputPtr++]) << 8;
b24 |= ((int) _input[_inputPtr++]) & 0xFF;
b24 = (b24 << 8) | (((int) _input[_inputPtr++]) & 0xFF);
outPtr = _variant.encodeBase64Chunk(b24, buffer, outPtr);
if (--_chunksBeforeLf <= 0) {
buffer[outPtr++] = LF_BYTE;
_chunksBeforeLf = _variant.getMaxLineLength() >> 2;
}
}
// main stuff done, any leftovers?
int inputLeft = (_inputEnd-_inputPtr);
if (inputLeft > 0) { // yes, but do we have room for output?
if (outPtr <= outEnd) { // yup
int b24 = ((int) _input[_inputPtr++]) << 16;
if (inputLeft == 2) {
b24 |= (((int) _input[_inputPtr++]) & 0xFF) << 8;
}
outPtr = _variant.encodeBase64Partial(b24, inputLeft, buffer, outPtr);
}
}
return outPtr;
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/Base64Variant.java 100644 0 0 24645 11520453235 21433 0 ustar 0 0 /* Stax2 extension for basic Stax API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.typed;
import java.util.Arrays;
/**
* This abstract base class is used to define specific details of which
* variant of Base64 encoding/decoding is to be used. Although there is
* somewhat standard basic version (so-called "MIME Base64"), other variants
* exists, see Base64 Wikipedia entry for details.
*
* Implementation notes:
*
* Note: for some output modes (when writing attributes) linefeeds may
* need to be avoided, and this value ignored.
*/
final int _maxLineLength;
/*
////////////////////////////////////////////////////
// Life-cycle
////////////////////////////////////////////////////
*/
public Base64Variant(String name, String base64Alphabet, boolean usesPadding, char paddingChar, int maxLineLength)
{
_name = name;
_usesPadding = usesPadding;
_paddingChar = paddingChar;
_maxLineLength = maxLineLength;
// Ok and then we need to create codec tables.
// First the main encoding table:
int alphaLen = base64Alphabet.length();
if (alphaLen != 64) {
throw new IllegalArgumentException("Base64Alphabet length must be exactly 64 (was "+alphaLen+")");
}
// And then secondary encoding table and decoding table:
base64Alphabet.getChars(0, alphaLen, _base64ToAsciiC, 0);
Arrays.fill(_asciiToBase64, BASE64_VALUE_INVALID);
for (int i = 0; i < alphaLen; ++i) {
char alpha = _base64ToAsciiC[i];
_base64ToAsciiB[i] = (byte) alpha;
_asciiToBase64[alpha] = i;
}
// Plus if we use padding, add that in too
if (usesPadding) {
_asciiToBase64[(int) paddingChar] = BASE64_VALUE_PADDING;
}
}
/**
* "Copy constructor" that can be used when the base alphabet is identical
* to one used by another variant except for the maximum line length
* (and obviously, name).
*/
public Base64Variant(Base64Variant base, String name, int maxLineLength)
{
this(base, name, base._usesPadding, base._paddingChar, maxLineLength);
}
/**
* "Copy constructor" that can be used when the base alphabet is identical
* to one used by another variant, but other details (padding, maximum
* line length) differ
*/
public Base64Variant(Base64Variant base, String name, boolean usesPadding, char paddingChar, int maxLineLength)
{
_name = name;
byte[] srcB = base._base64ToAsciiB;
System.arraycopy(srcB, 0, this._base64ToAsciiB, 0, srcB.length);
char[] srcC = base._base64ToAsciiC;
System.arraycopy(srcC, 0, this._base64ToAsciiC, 0, srcC.length);
int[] srcV = base._asciiToBase64;
System.arraycopy(srcV, 0, this._asciiToBase64, 0, srcV.length);
_usesPadding = usesPadding;
_paddingChar = paddingChar;
_maxLineLength = maxLineLength;
}
/*
////////////////////////////////////////////////////
// Public accessors
////////////////////////////////////////////////////
*/
public String getName() { return _name; }
public boolean usesPadding() { return _usesPadding; }
public boolean usesPaddingChar(char c) { return c == _paddingChar; }
public char getPaddingChar() { return _paddingChar; }
public byte getPaddingByte() { return (byte)_paddingChar; }
public int getMaxLineLength() { return _maxLineLength; }
/*
////////////////////////////////////////////////////
// Decoding support
////////////////////////////////////////////////////
*/
/**
* @return 6-bit decoded value, if valid character;
*/
public int decodeBase64Char(char c)
{
int ch = (int) c;
return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID;
}
public int decodeBase64Byte(byte b)
{
int ch = (int) b;
return (ch <= 127) ? _asciiToBase64[ch] : BASE64_VALUE_INVALID;
}
/*
////////////////////////////////////////////////////
// Encoding support
////////////////////////////////////////////////////
*/
public char encodeBase64BitsAsChar(int value)
{
/* Let's assume caller has done necessary checks; this
* method must be fast and inlinable
*/
return _base64ToAsciiC[value];
}
/**
* Method that encodes given right-aligned (LSB) 24-bit value
* into 4 base64 characters, stored in given result buffer.
*/
public int encodeBase64Chunk(int b24, char[] buffer, int ptr)
{
buffer[ptr++] = _base64ToAsciiC[(b24 >> 18) & 0x3F];
buffer[ptr++] = _base64ToAsciiC[(b24 >> 12) & 0x3F];
buffer[ptr++] = _base64ToAsciiC[(b24 >> 6) & 0x3F];
buffer[ptr++] = _base64ToAsciiC[b24 & 0x3F];
return ptr;
}
/**
* Method that outputs partial chunk (which only encodes one
* or two bytes of data). Data given is still aligned same as if
* it as full data; that is, missing data is at the "right end"
* (LSB) of int.
*
* @param outputBytes Number of encoded bytes included (either 1 or 2)
*/
public int encodeBase64Partial(int bits, int outputBytes, char[] buffer, int outPtr)
{
buffer[outPtr++] = _base64ToAsciiC[(bits >> 18) & 0x3F];
buffer[outPtr++] = _base64ToAsciiC[(bits >> 12) & 0x3F];
if (_usesPadding) {
buffer[outPtr++] = (outputBytes == 2) ?
_base64ToAsciiC[(bits >> 6) & 0x3F] : _paddingChar;
buffer[outPtr++] = _paddingChar;
} else {
if (outputBytes == 2) {
buffer[outPtr++] = _base64ToAsciiC[(bits >> 6) & 0x3F];
}
}
return outPtr;
}
public byte encodeBase64BitsAsByte(int value)
{
// As with above, assuming it is 6-bit value
return _base64ToAsciiB[value];
}
/**
* Method that encodes given right-aligned (LSB) 24-bit value
* into 4 base64 bytes (ascii), stored in given result buffer.
*/
public int encodeBase64Chunk(int b24, byte[] buffer, int ptr)
{
buffer[ptr++] = _base64ToAsciiB[(b24 >> 18) & 0x3F];
buffer[ptr++] = _base64ToAsciiB[(b24 >> 12) & 0x3F];
buffer[ptr++] = _base64ToAsciiB[(b24 >> 6) & 0x3F];
buffer[ptr++] = _base64ToAsciiB[b24 & 0x3F];
return ptr;
}
/**
* Method that outputs partial chunk (which only encodes one
* or two bytes of data). Data given is still aligned same as if
* it as full data; that is, missing data is at the "right end"
* (LSB) of int.
*
* @param outputBytes Number of encoded bytes included (either 1 or 2)
*/
public int encodeBase64Partial(int bits, int outputBytes, byte[] buffer, int outPtr)
{
buffer[outPtr++] = _base64ToAsciiB[(bits >> 18) & 0x3F];
buffer[outPtr++] = _base64ToAsciiB[(bits >> 12) & 0x3F];
if (_usesPadding) {
byte pb = (byte) _paddingChar;
buffer[outPtr++] = (outputBytes == 2) ?
_base64ToAsciiB[(bits >> 6) & 0x3F] : pb;
buffer[outPtr++] = pb;
} else {
if (outputBytes == 2) {
buffer[outPtr++] = _base64ToAsciiB[(bits >> 6) & 0x3F];
}
}
return outPtr;
}
/*
////////////////////////////////////////////////////
// other methods
////////////////////////////////////////////////////
*/
// @Override
public String toString() { return _name; }
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/Base64Variants.java 100644 0 0 6520 11520453235 21566 0 ustar 0 0 /* Stax2 extension for basic Stax API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.typed;
/**
* This class is used as a container for commonly used Base64 variants.
*
* @author Tatu Saloranta
*
* @since 3.0.0
*/
public final class Base64Variants
{
final static String STD_BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
* This variant is what most people would think of "the standard"
* Base64 encoding.
*
* See wikipedia Base64 entry for details.
*/
public final static Base64Variant MIME;
static {
MIME = new Base64Variant("MIME", STD_BASE64_ALPHABET, true, '=', 76);
}
/**
* Slightly non-standard modification of {@link #MIME} which does not
* use linefeeds (max line length set to infinite). Useful when linefeeds
* wouldn't work well (possibly in attributes), or for minor space savings
* (save 1 linefeed per 76 data chars, ie. ~1.4% savings).
*/
public final static Base64Variant MIME_NO_LINEFEEDS;
static {
MIME_NO_LINEFEEDS = new Base64Variant(MIME, "MIME-NO-LINEFEEDS", Integer.MAX_VALUE);
}
/**
* This variant is the one that predates {@link #MIME}: it is otherwise
* identical, except that it mandates shorter line length.
*/
public final static Base64Variant PEM = new Base64Variant(MIME, "PEM", true, '=', 64);
/**
* This non-standard variant is usually used when encoded data needs to be
* passed via URLs (such as part of GET request). It differs from the
* base {@link #MIME} variant in multiple ways.
* First, no padding is used: this also means that it generally can not
* be written in multiple separate but adjacent chunks (which would not
* be the usual use case in any case). Also, no linefeeds are used (max
* line length set to infinite). And finally, two characters (plus and
* slash) that would need quoting in URLs are replaced with more
* optimal alternatives (hyphen and underscore, respectively).
*/
public final static Base64Variant MODIFIED_FOR_URL;
static {
StringBuffer sb = new StringBuffer(STD_BASE64_ALPHABET);
// Replace plus with hyphen, slash with underscore (and no padding)
sb.setCharAt(sb.indexOf("+"), '-');
sb.setCharAt(sb.indexOf("/"), '_');
/* And finally, let's not split lines either, wouldn't work too
* well with URLs
*/
MODIFIED_FOR_URL = new Base64Variant("MODIFIED-FOR-URL", sb.toString(), false, Base64Variant.PADDING_CHAR_NONE, Integer.MAX_VALUE);
}
/**
* Method used to get the default variant ("MIME") for cases
* where caller does not explicitly specify the variant
*/
public static Base64Variant getDefaultVariant() {
return MIME;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/TypedArrayDecoder.java 100644 0 0 2046 11520453235 22403 0 ustar 0 0 package org.codehaus.stax2.typed;
/**
* Base class that defines decoder used for decoding multiple
* elements of an array type. Implementations typically use
* an embedded instance of {@link TypedValueDecoder} for
* decoding individual values.
*
* Set of concrete implementations is included in the reference
* implementation of the Typed Access API.
*
* @author Tatu Saloranta
*
* @since 3.0
*/
public abstract class TypedArrayDecoder
{
/**
* Method called to decode single (element) value that given textual
* input contains and store it in result array.
*
* @return True if decoding is complete, that is, no more
* elements can be added to contained array
*/
public abstract boolean decodeValue(String input) throws IllegalArgumentException;
public abstract boolean decodeValue(char[] buffer, int start, int end) throws IllegalArgumentException;
/**
* @return Number of elements decoded and contained
*/
public abstract int getCount();
public abstract boolean hasRoom();
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/TypedValueDecoder.java 100644 0 0 5240 11520453235 22400 0 ustar 0 0 package org.codehaus.stax2.typed;
/**
* Base class that defines generic typed value decoder API used
* by {@link TypedXMLStreamReader} to allow for efficient customized
* decoding of textual xml content into actual typed values.
* Set of concrete decoders is also included in the reference
* implementation of the Typed Access API.
*
* Details of how value decoded is to be accessed is NOT defined
* as part of this interface: since decoders are explicitly passed
* by callers, they can (and need to) use more specific sub-classes
* with value access method or methods.
*
* Note: to allow for optimal efficiency, there are multiple
* decode methods, one of which gets called during decoding process.
* This is necessary since the stream reader implementations may
* use different internal representations, either in general (an
* implementation might stored everyting as Strings; another
* as character arrays).
*
* @author Tatu Saloranta
*
* @since 3.0
*/
public abstract class TypedValueDecoder
{
/**
* Method used to invoke decoding functionality, for decoding
* the value encoded in given substring.
* It is to try decoding value, and either store decoded value
* for later access (using method(s) caller knows about), or
* throw an exception to indicate problem encountered.
*
* Note: method will get called with "trimmed" input, i.e. input
* will never have any leading or trailing white space.
* It will also never be called with empty content
* ({@link #handleEmptyValue} is called instead for such cases)
*/
public abstract void decode(String input) throws IllegalArgumentException;
/**
* Method used to invoke decoding functionality, for decoding
* the value encoded in given portion of character array
* It is to try decoding value, and either store decoded value
* for later access (using method(s) caller knows about), or
* throw an exception to indicate problem encountered.
*
* Note: method will get called with "trimmed" input, i.e. input
* will never have any leading or trailing white space.
* It will also never be called with empty content
* ({@link #handleEmptyValue} is called instead for such cases)
*/
public abstract void decode(char[] buffer, int start, int end) throws IllegalArgumentException;
/**
* Method called in cases where value to decode would be empty, after
* trimming leading and trailing white space. Decoder can
* then either change its state (to contain value to return)
* or throw appropriate exception
*/
public abstract void handleEmptyValue() throws IllegalArgumentException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/TypedXMLStreamException.java 100644 0 0 7302 11520453235 23532 0 ustar 0 0 package org.codehaus.stax2.typed;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
/**
* This class represents an exception throw by an
* {@link TypedXMLStreamReader} or an {@link TypedXMLStreamWriter}. It is
* used to indicate a problems occuring when trying convert
* data for access using typed read or write methods.
*
* Note that the lexical value is a mandatory thing to pass -- since
* this exception subtype need not be used solely for wrapping
* purposes ({@link XMLStreamException}s are to be passed as is,
* other underlying root cause types should be unchecked), we
* can mandate a lexical value (which may be null, however) to
* be passed.
* Similarly, aside from generic stream exception, it is mandated
* that root causes to wrap need to be of type
* {@link IllegalArgumentException}, since that is the supertype
* of regular parsing/conversion types for primitive types.
*
* @since 3.0
*
* @author Santiago.PericasGeertsen@sun.com
* @author Tatu Saloranta
*/
public class TypedXMLStreamException
extends XMLStreamException
{
private static final long serialVersionUID = 1L;
/**
* Lexical representation of the content that could not be
* converted to the requested type. May be Read an element content as a boolean. The lexical
* representation of a boolean is defined by the
* XML Schema boolean data type. Whitespace MUST be
* collapsed
* according to the whiteSpace facet for the XML Schema boolean
* data type.
* An exception is thrown if, after whitespace is
* collapsed, the resulting sequence of characters is not in
* the lexical space defined by the XML Schema boolean data type.
* (note: allowed lexical values are canonicals "true" and
* "false", as well as non-canonical "0" and "1")
*
* These are the pre- and post-conditions of calling this method:
* XSP_V_XMLID_TYPING
for implementations
* that do support Xml:id specification: those that do not, have to
* default to XSP_V_XMLID_NONE.
* For Xml:id-enabled implementations, typing support is the most
* logical default, since it
* provides the intuitive behavior of xml:id functionality, as well
* as reasonable performance (very little overhead in non-validating
* mode; usual id checking overhead for validating mode).
*/
public final static String XSP_SUPPORT_XMLID = "org.codehaus.stax2.supportXmlId";
/**
* Property value to use with property
* {@link #XSP_SUPPORT_XMLID}.
* Property value that indicates that no xml:id support should be
* enabled.
*/
public final static String XSP_V_XMLID_NONE = "disable";
/**
* Property value to use with property
* {@link #XSP_SUPPORT_XMLID}.
* Value indicates that the attribute type assignment
* portion of xml:id should be supported (all 'xml:id' attributes
* that are not explicitly declared should have attribute type of
* ID), but that no xml:id specific validation is to be done.
* Due to typing, value normalization should occur.
* It is still possible that schema (DTD, RNG, W3C Schema) based
* validation is done, including validation of values of xml:id
* attributes, but only based on Schema information.
*
Feature is write-only, since storing it after loading the DTD
* in question does not have much use.
*
*
*getText
will return
* proper conntets. If false, reader is allowed to skip creation
* of such copies: this can improve performance, but it also means
* that further calls to getText
is not guaranteed to
* return meaningful data.
*
* @return Number of characters written to the reader
*/
public int getText(Writer w, boolean preserveContents)
throws IOException, XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Other accessors
///////////////////////////////////////////////////////////
*/
/**
* Method that can be used to check whether current START_ELEMENT
* event was created for an empty element (xml short-hand notation
* where one tag implies start and end, ending with "/>"), or not.
*getLocalName
* and getPrefix
separately, but are not required to do
* so. Nonetheless it is usually at least as efficient (if not more)
* to call this method as to do it fully in calling code.
*
* @return Prefix-qualified name of the current element; essentially
* 'prefix:localName' if the element has a prefix, or 'localName'
* if it does not have one (belongs to the default namespace)
*/
public String getPrefixedName();
/*
///////////////////////////////////////////////////////////
// Input handling
///////////////////////////////////////////////////////////
*/
/**
* Method similar to
* {@link javax.xml.stream.XMLStreamReader#getNamespaceContext()},
* except that this method also does close the underlying input
* source if it has not yet been closed. It is generally preferable
* to call this method if the parsing ends in an exception;
* and for some input sources (when passing
* a {@link java.io.File} or {@link java.net.URL} for factory
* method) it has to be called as the application does not have
* access to the actually input source ({@link java.io.InputStream}
* opened from a {@link java.net.URL} and so on).
*/
public void closeCompletely()
throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/XMLStreamWriter2.java 100644 0 0 22617 11520453235 21025 0 ustar 0 0 package org.codehaus.stax2;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.codehaus.stax2.typed.TypedXMLStreamWriter;
import org.codehaus.stax2.validation.Validatable;
/**
* Extended interface that implements functionality that is necessary
* to properly build event API on top of {@link XMLStreamWriter},
* as well as to configure individual instances.
* It also adds limited number of methods that are important for
* efficient pass-through processing (such as one needed when routing
* SOAP-messages).
*
*
*/
public String getEncoding();
/*
///////////////////////////////////////////////////////////
// Write methods base interface is missing
///////////////////////////////////////////////////////////
*/
public void writeCData(char[] text, int start, int len)
throws XMLStreamException;
public void writeDTD(String rootName, String systemId, String publicId,
String internalSubset)
throws XMLStreamException;
/**
* Method similar to {@link #writeEndElement}, but that will always
* write the full end element, instead of empty element. This only
* matters for cases where the element itself has no content, and
* if writer is allowed to write empty elements when it encounters
* such start/end element write pairs.
*/
public void writeFullEndElement() throws XMLStreamException;
public void writeStartDocument(String version, String encoding,
boolean standAlone)
throws XMLStreamException;
/**
* Method that can be called to write whitespace-only content.
* If so, it is to be written as is (with no escaping), and does
* not contain non-whitespace characters (writer may validate this,
* and throw an exception if it does).
*writeStartDocument
method (explicitly
* or implicity; latter in cases where defaults are imposed
* by Stax specification)
* flush()
and close()
to the underlying
* Writer.
*/
public interface EscapingWriterFactory
{
/**
* Method called to create an instance of escaping writer that
* will output content using specified writer,
* and escaping necessary characters (depending on
* both type [attr, element text] and encoding).
*
* @param w Underlying writer that the encoding writer should
* output
* @param enc Encoding to use, as specified by the stream writer
* (based on information application has passed)
*/
public Writer createEscapingWriterFor(Writer w, String enc)
throws UnsupportedEncodingException;
/**
* Method called to create an instance of escaping writer that
* will output to the specified stream, using the specified
* encoding,
* and escaping necessary characters (depending on
* both type [attr, element text] and encoding).
*
* @param out Underlying stream that the encoding writer should
* output using
* @param enc Encoding to use, as specified by the stream writer
* (based on information application has passed)
*/
public Writer createEscapingWriterFor(OutputStream out, String enc)
throws UnsupportedEncodingException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2BlockResult.java 100644 0 0 1671 11520453235 21471 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* This is the mid-level abstract base class for {@link Stax2Result}s
* that an be used to write to in-memory (low-level) data structures,
* such as byte and char arrays, StringBuffers and so forth.
* The main reason for using such a result object (instead of constructing
* wrapper Readers or InputStreams) is that concrete implementations
* usually also allow more direct access to the underlying data, so
* that stream reader implementations may be able to do more optimal
* access.
*/
public abstract class Stax2BlockResult
extends Stax2Result
{
protected Stax2BlockResult() { }
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
public abstract Writer constructWriter() throws IOException;
public abstract OutputStream constructOutputStream() throws IOException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2BlockSource.java 100644 0 0 2330 11520453235 21444 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
import java.net.URL;
/**
* This is the mid-level abstract base class for {@link Stax2Source}s
* that an be used to access fixed-length in-memory data sources, such
* as byte and char arrays, Strings, StringBuffers and so forth.
* The main reason for using such a source object (instead of constructing
* wrapper Readers or InputStreams) is that concrete implementations
* usually also allow more direct access to the underlying data, so
* that stream reader implementations may be able to do more optimal
* access.
*/
public abstract class Stax2BlockSource
extends Stax2Source
{
protected Stax2BlockSource() { }
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
/**
* Usually there is no way to refer to the underlying data source,
* since they are in-memory data structures. Because of this, the
* base implementation just returns null.
*/
public URL getReference() {
return null;
}
public abstract Reader constructReader() throws IOException;
public abstract InputStream constructInputStream() throws IOException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2ByteArraySource.java 100644 0 0 4124 11520453235 22317 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* Simple implementation of {@link Stax2BlockSource} that encapsulates
* a byte array.
*
*
*/
public abstract class Stax2Result
implements Result
{
protected String mSystemId;
protected String mPublicId;
protected String mEncoding;
protected Stax2Result() { }
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
public String getSystemId() {
return mSystemId;
}
public void setSystemId(String id) {
mSystemId = id;
}
public String getPublicId() {
return mPublicId;
}
public void setPublicId(String id) {
mPublicId = id;
}
public String getEncoding() {
return mEncoding;
}
public void setEncoding(String enc) {
mEncoding = enc;
}
/*
///////////////////////////////////////////
// Public API, convenience factory methods
///////////////////////////////////////////
*/
/**
* This method creates a {@link Writer} via which underlying output
* target can be written to. Note that caller is responsible for
* closing that Writer when it is done reading it.
*/
public abstract Writer constructWriter()
throws IOException;
/**
* This method creates an {@link OutputStream} via which underlying output
* target can be written to. Note that caller is responsible for
* closing that OutputStream when it is done reading it
*/
public abstract OutputStream constructOutputStream()
throws IOException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2Source.java 100644 0 0 6373 11520453235 20504 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import javax.xml.transform.Source;
/**
* This is the base class for additional input sources (implementations
* of {@link javax.xml.transform.Source}) that Stax2
* {@link org.codehaus.stax2.XMLInputFactory2} implementations should support.
*
*
*/
public abstract class Stax2Source
implements Source
{
protected String mSystemId;
protected String mPublicId;
protected String mEncoding;
protected Stax2Source() { }
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
public String getSystemId() {
return mSystemId;
}
public void setSystemId(String id) {
mSystemId = id;
}
public String getPublicId() {
return mPublicId;
}
public void setPublicId(String id) {
mPublicId = id;
}
public String getEncoding() {
return mEncoding;
}
public void setEncoding(String enc) {
mEncoding = enc;
}
/**
* @return URL that can be used to resolve references
* originating from the content read via this source; may be
* null if not known (which is the case for most non-referential
* sources)
*/
public abstract URL getReference();
/*
///////////////////////////////////////////
// Public API, convenience factory methods
///////////////////////////////////////////
*/
/**
* This method creates a {@link Reader} via which underlying input
* source can be accessed. Note that caller is responsible for
* closing that Reader when it is done reading it.
*/
public abstract Reader constructReader()
throws IOException;
/**
* This method creates an {@link InputStream} via which underlying input
* source can be accessed. Note that caller is responsible for
* closing that InputSource when it is done reading it
*/
public abstract InputStream constructInputStream()
throws IOException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2StringSource.java 100644 0 0 2016 11520453235 21661 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
/**
* Simple implementation of {@link Stax2BlockSource} that encapsulates
* a simple {@link String}.
*/
public class Stax2StringSource
extends Stax2BlockSource
{
final String mText;
public Stax2StringSource(String text) {
mText = text;
}
/*
/////////////////////////////////////////
// Implementation of the Public API
/////////////////////////////////////////
*/
public Reader constructReader()
throws IOException
{
return new StringReader(mText);
}
public InputStream constructInputStream()
throws IOException
{
/* No obvious/easy way; if caller really wants an InputStream, it
* can get a Reader, add an encoders, and so on.
*/
return null;
}
/*
/////////////////////////////////////////
// Additional API for this source
/////////////////////////////////////////
*/
public String getText() {
return mText;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/io/Stax2URLSource.java 100644 0 0 2651 11520453235 21062 0 ustar 0 0 package org.codehaus.stax2.io;
import java.io.*;
import java.net.URL;
/**
* Simple implementation of {@link Stax2ReferentialSource}, which refers
* to the specific file.
*/
public class Stax2URLSource
extends Stax2ReferentialSource
{
final URL mURL;
public Stax2URLSource(URL url) {
mURL = url;
}
/*
/////////////////////////////////////////
// Public API, simple accessors/mutators
/////////////////////////////////////////
*/
/**
* @return URL that refers to the reference resource, for the purposes
* of resolving a relative reference from content read from the
* resource.
*/
public URL getReference()
{
return mURL;
}
public Reader constructReader()
throws IOException
{
String enc = getEncoding();
if (enc != null && enc.length() > 0) {
return new InputStreamReader(constructInputStream(), enc);
}
// Sub-optimal; really shouldn't use the platform default encoding
return new InputStreamReader(constructInputStream());
}
public InputStream constructInputStream()
throws IOException
{
/* A simple optimization: if it's a file reference, can use
* a more optimal one:
*/
if ("file".equals(mURL.getProtocol())) {
return new FileInputStream(mURL.getPath());
}
return mURL.openStream();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/osgi/Stax2InputFactoryProvider.java 100644 0 0 3746 11520453235 23741 0 ustar 0 0 package org.codehaus.stax2.osgi;
import org.codehaus.stax2.XMLInputFactory2;
import org.codehaus.stax2.XMLStreamProperties;
/**
* Simple interface to be used for registering objects that
* can construct {@link XMLInputFactory2} instances with OSGi framework.
* The added indirection (provider constructing factory) is needed because
* of impedance between OSGi service objects (which are essentially
* singletons) and Stax/Stax2 factories which are not.
*createQName
* methods.
*
* @author Tatu Saloranta
*
* @since 3.0
*/
public abstract class Stax2EventFactoryImpl
extends XMLEventFactory2
{
protected Location mLocation;
public Stax2EventFactoryImpl() { }
/*
/////////////////////////////////////////////////////////////
// XMLEventFactory API
/////////////////////////////////////////////////////////////
*/
public Attribute createAttribute(QName name, String value) {
return new AttributeEventImpl(mLocation, name, value, true);
}
public Attribute createAttribute(String localName, String value) {
return new AttributeEventImpl(mLocation, localName, null, null, value, true);
}
public Attribute createAttribute(String prefix, String nsURI,
String localName, String value)
{
return new AttributeEventImpl(mLocation, localName, nsURI, prefix, value, true);
}
public Characters createCData(String content) {
return new CharactersEventImpl(mLocation, content, true);
}
public Characters createCharacters(String content) {
return new CharactersEventImpl(mLocation, content, false);
}
public Comment createComment(String text) {
return new CommentEventImpl(mLocation, text);
}
/**
* Note: constructing DTD events this way means that there will be no
* internal presentation of actual DTD; no parsing is implied by
* construction.
*/
public DTD createDTD(String dtd) {
return new DTDEventImpl(mLocation, dtd);
}
public EndDocument createEndDocument() {
return new EndDocumentEventImpl(mLocation);
}
public EndElement createEndElement(QName name, Iterator namespaces) {
return new EndElementEventImpl(mLocation, name, namespaces);
}
public EndElement createEndElement(String prefix, String nsURI,
String localName)
{
return createEndElement(createQName(nsURI, localName), null);
}
public EndElement createEndElement(String prefix, String nsURI,
String localName, Iterator ns)
{
return createEndElement(createQName(nsURI, localName, prefix), ns);
}
public EntityReference createEntityReference(String name, EntityDeclaration decl)
{
return new EntityReferenceEventImpl(mLocation, decl);
}
public Characters createIgnorableSpace(String content) {
return CharactersEventImpl.createIgnorableWS(mLocation, content);
}
public Namespace createNamespace(String nsURI) {
return NamespaceEventImpl.constructDefaultNamespace(mLocation, nsURI);
}
public Namespace createNamespace(String prefix, String nsURI) {
return NamespaceEventImpl.constructNamespace(mLocation, prefix, nsURI);
}
public ProcessingInstruction createProcessingInstruction(String target, String data) {
return new ProcInstrEventImpl(mLocation, target, data);
}
public Characters createSpace(String content) {
return CharactersEventImpl.createNonIgnorableWS(mLocation, content);
}
public StartDocument createStartDocument() {
return new StartDocumentEventImpl(mLocation);
}
public StartDocument createStartDocument(String encoding) {
return new StartDocumentEventImpl(mLocation, encoding);
}
public StartDocument createStartDocument(String encoding, String version) {
return new StartDocumentEventImpl(mLocation, encoding, version);
}
public StartDocument createStartDocument(String encoding, String version, boolean standalone)
{
return new StartDocumentEventImpl(mLocation, encoding, version,
true, standalone);
}
public StartElement createStartElement(QName name, Iterator attr, Iterator ns)
{
return createStartElement(name, attr, ns, null);
}
public StartElement createStartElement(String prefix, String nsURI, String localName)
{
return createStartElement(createQName(nsURI, localName, prefix),
null, null, null);
}
public StartElement createStartElement(String prefix, String nsURI,
String localName, Iterator attr,
Iterator ns)
{
return createStartElement(createQName(nsURI, localName, prefix), attr, ns,
null);
}
public StartElement createStartElement(String prefix, String nsURI,
String localName, Iterator attr,
Iterator ns, NamespaceContext nsCtxt)
{
return createStartElement(createQName(nsURI, localName, prefix),
attr, ns, nsCtxt);
}
public void setLocation(Location loc)
{
mLocation = loc;
}
/*
/////////////////////////////////////////////////////////////
// XMLEventFactory2 methods
/////////////////////////////////////////////////////////////
*/
public DTD2 createDTD(String rootName, String sysId, String pubId,
String intSubset)
{
return new DTDEventImpl(mLocation, rootName, sysId, pubId, intSubset, null);
}
public DTD2 createDTD(String rootName, String sysId, String pubId,
String intSubset, Object processedDTD)
{
return new DTDEventImpl(mLocation, rootName, sysId, pubId, intSubset,
processedDTD);
}
/*
/////////////////////////////////////////////////////////////
// Helper methods, overridable
/////////////////////////////////////////////////////////////
*/
protected abstract QName createQName(String nsURI, String localName);
protected abstract QName createQName(String nsURI, String localName, String prefix);
protected StartElement createStartElement(QName name, Iterator attr,
Iterator ns, NamespaceContext ctxt)
{
return StartElementEventImpl.construct(mLocation, name, attr, ns, ctxt);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2EventReaderImpl.java 100644 0 0 41155 11520453235 22312 0 ustar 0 0 /* Woodstox XML processor
*
* Copyright (c) 2004- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri;
import java.util.NoSuchElementException;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.util.XMLEventAllocator;
import org.codehaus.stax2.XMLEventReader2;
import org.codehaus.stax2.XMLStreamReader2;
/**
* Almost complete implementation of {@link XMLEventReader2}, built on top of
* a generic {@link XMLStreamReader} implementation (using aggregation).
* Designed to be used by concrete Stax2 implementations to provide
* full Event API implementation with minimal effort.
*
*
*/
public abstract class Stax2EventReaderImpl
implements XMLEventReader2,
XMLStreamConstants
{
// // // Enumerated state ids
protected final static int STATE_INITIAL = 1;
protected final static int STATE_END_OF_INPUT = 2;
protected final static int STATE_CONTENT = 3;
// // // Enumerated error case ids
/**
* Current state when getElementText() called not START_ELEMENT
*/
protected final static int ERR_GETELEMTEXT_NOT_START_ELEM = 1;
/**
* Encountered non-textual event (other than closing END_ELEMENT)
* when collecting text for getElementText()
*/
protected final static int ERR_GETELEMTEXT_NON_TEXT_EVENT = 2;
/**
* Encountered CHARACTERS or CDATA that contains non-white space
* char(s), when trying to locate tag with nextTag()
*/
protected final static int ERR_NEXTTAG_NON_WS_TEXT = 3;
/**
* Encountered non-skippable non-text/element event with
* nextTag()
*/
protected final static int ERR_NEXTTAG_WRONG_TYPE = 4;
/*
///////////////////////////////////////////
// Configuration
///////////////////////////////////////////
*/
protected final XMLEventAllocator mAllocator;
protected final XMLStreamReader2 mReader;
/*
///////////////////////////////////////////
// State
///////////////////////////////////////////
*/
/**
* Event that has been peeked, ie. loaded without call to
* {@link #nextEvent}; will be returned and cleared by
* call to {@link #nextEvent} (or, returned again if peeked
* again)
*/
private XMLEvent mPeekedEvent = null;
/**
* High-level state indicator, with currently three values:
* whether we are initializing (need to synthetize START_DOCUMENT),
* at END_OF_INPUT (end-of-doc), or otherwise, normal operation.
* Useful in simplifying some methods, as well as to make sure
* that independent of how stream reader handles things, event reader
* can reliably detect End-Of-Document.
*/
protected int mState = STATE_INITIAL;
/**
* This variable keeps track of the type of the 'previous' event
* when peeking for the next Event. It is needed for some functionality,
* to remember state even when underlying parser has to move to peek
* the next event.
*/
protected int mPrePeekEvent = START_DOCUMENT;
/*
///////////////////////////////////////////
// Construction
///////////////////////////////////////////
*/
protected Stax2EventReaderImpl(XMLEventAllocator a, XMLStreamReader2 r)
{
mAllocator = a;
mReader = r;
}
/*
//////////////////////////////////////////////////////
// Abstract methods sub-classes have to implement
//////////////////////////////////////////////////////
*/
public abstract boolean isPropertySupported(String name);
public abstract boolean setProperty(String name, Object value);
/**
* Method called upon encountering a problem that should result
* in an exception being thrown. If non-null String is returned.
* that will be used as the message of exception thrown; if null,
* a standard message will be used instead.
*
* @param errorType Type of the problem, one of ERR_
* constants
* @param eventType Type of the event that triggered the problem,
* if any; -1 if not available.
*/
protected abstract String getErrorDesc(int errorType, int eventType);
/*
//////////////////////////////////////////////////////
// XMLEventReader API
//////////////////////////////////////////////////////
*/
public void close()
throws XMLStreamException
{
mReader.close();
}
public String getElementText()
throws XMLStreamException
{
/* Simple, if no peeking occured: can just forward this to the
* underlying parser
*/
if (mPeekedEvent == null) {
return mReader.getElementText();
}
XMLEvent evt = mPeekedEvent;
mPeekedEvent = null;
/* Otherwise need to verify that we are currently over START_ELEMENT.
* Problem is we have already went past it...
*/
if (mPrePeekEvent != START_ELEMENT) {
reportProblem(findErrorDesc(ERR_GETELEMTEXT_NOT_START_ELEM, mPrePeekEvent));
}
// ??? do we need to update mPrePeekEvent now
String str = null;
StringBuffer sb = null;
/* Ok, fine, then just need to loop through and get all the
* text...
*/
for (; true; evt = nextEvent()) {
if (evt.isEndElement()) {
break;
}
int type = evt.getEventType();
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
// can/should just ignore them
continue;
}
if (!evt.isCharacters()) {
reportProblem(findErrorDesc(ERR_GETELEMTEXT_NON_TEXT_EVENT, type));
}
String curr = evt.asCharacters().getData();
if (str == null) {
str = curr;
} else {
if (sb == null) {
sb = new StringBuffer(str.length() + curr.length());
sb.append(str);
}
sb.append(curr);
}
}
if (sb != null) {
return sb.toString();
}
return (str == null) ? "" : str;
}
public Object getProperty(String name) {
return mReader.getProperty(name);
}
public boolean hasNext() {
return (mState != STATE_END_OF_INPUT);
}
public XMLEvent nextEvent()
throws XMLStreamException
{
if (mState == STATE_END_OF_INPUT) {
throwEndOfInput();
} else if (mState == STATE_INITIAL) {
mState = STATE_CONTENT;
return createStartDocumentEvent();
}
if (mPeekedEvent != null) {
XMLEvent evt = mPeekedEvent;
mPeekedEvent = null;
if (evt.isEndDocument()) {
mState = STATE_END_OF_INPUT;
}
return evt;
}
return createNextEvent(true, mReader.next());
}
public Object next() {
try {
return nextEvent();
} catch (XMLStreamException sex) {
throwUnchecked(sex);
return null;
}
}
public XMLEvent nextTag()
throws XMLStreamException
{
// If we have peeked something, need to process it
if (mPeekedEvent != null) {
XMLEvent evt = mPeekedEvent;
mPeekedEvent = null;
int type = evt.getEventType();
switch (type) {
case END_DOCUMENT:
return null;
case START_DOCUMENT:
// Need to skip START_DOCUMENT to get the root elem
break;
case SPACE:
// Ignorable WS is just fine
break;
/* !!! 07-Dec-2004, TSa: Specs are mum about Comments and PIs.
* But why would they not be skipped just like what
* the stream reader does?
*/
case COMMENT:
case PROCESSING_INSTRUCTION:
break;
case CDATA:
case CHARACTERS:
if (((Characters) evt).isWhiteSpace()) {
break;
}
reportProblem(findErrorDesc(ERR_NEXTTAG_NON_WS_TEXT, type));
break; // never gets here, but some compilers whine without...
case START_ELEMENT:
case END_ELEMENT:
return evt;
default:
reportProblem(findErrorDesc(ERR_NEXTTAG_WRONG_TYPE, type));
}
} else {
/* 13-Sep-2005, TSa: As pointed out by Patrick, we may need to
* initialize the state here, too; otherwise peek() won't work
* correctly. The problem is that following loop's get method
* does not use event reader's method but underlying reader's.
* As such, it won't update state: most importantly, initial
* state may not be changed to non-initial.
*/
if (mState == STATE_INITIAL) {
mState = STATE_CONTENT;
}
}
while (true) {
int next = mReader.next();
switch (next) {
case END_DOCUMENT:
return null;
case SPACE:
/* !!! 07-Dec-2004, TSa: Specs are mum about Comments and PIs.
* But why would they not be skipped just like what
* the stream reader does?
*/
case COMMENT:
case PROCESSING_INSTRUCTION:
continue;
case CDATA:
case CHARACTERS:
if (mReader.isWhiteSpace()) {
continue;
}
reportProblem(findErrorDesc(ERR_NEXTTAG_NON_WS_TEXT, next));
break; // just to keep Jikes happy...
case START_ELEMENT:
case END_ELEMENT:
return createNextEvent(false, next);
default:
reportProblem(findErrorDesc(ERR_NEXTTAG_WRONG_TYPE, next));
}
}
}
public XMLEvent peek()
throws XMLStreamException
{
if (mPeekedEvent == null) {
if (mState == STATE_END_OF_INPUT) {
// 06-Mar-2006, TSa: Fixed as per Arjen's suggestion:
//throwEndOfInput();
return null;
}
if (mState == STATE_INITIAL) {
// Not sure what it should be... but this should do:
mPrePeekEvent = START_DOCUMENT;
mPeekedEvent = createStartDocumentEvent();
mState = STATE_CONTENT;
} else {
mPrePeekEvent = mReader.getEventType();
mPeekedEvent = createNextEvent(false, mReader.next());
}
}
return mPeekedEvent;
}
/**
* Note: only here because we implement Iterator interface. Will not
* work, don't bother calling it.
*/
public void remove() {
throw new UnsupportedOperationException("Can not remove events from XMLEventReader.");
}
/*
//////////////////////////////////////////////////////
// XMLEventReader2 API
//////////////////////////////////////////////////////
*/
/**
*getErrorDesc()
first, and only
* if no message found, uses default messages defined here.
*/
private final String findErrorDesc(int errorType, int currEvent)
{
String msg = getErrorDesc(errorType, currEvent);
if (msg != null) {
return msg;
}
switch (errorType) {
case ERR_GETELEMTEXT_NOT_START_ELEM:
return "Current state not START_ELEMENT when calling getElementText()";
case ERR_GETELEMTEXT_NON_TEXT_EVENT:
return "Expected a text token";
case ERR_NEXTTAG_NON_WS_TEXT:
return "Only all-whitespace CHARACTERS/CDATA (or SPACE) allowed for nextTag()";
case ERR_NEXTTAG_WRONG_TYPE:
return "Should only encounter START_ELEMENT/END_ELEMENT, SPACE, or all-white-space CHARACTERS";
}
// should never happen, but it'd be bad to throw another exception...
return "Internal error (unrecognized error type: "+errorType+")";
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2EventWriterImpl.java 100644 0 0 14426 11520453235 22365 0 ustar 0 0 package org.codehaus.stax2.ri;
import java.util.Iterator;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.evt.XMLEvent2;
/**
* Simple implementation of {@link XMLEventWriter}.
*/
public class Stax2EventWriterImpl
implements XMLEventWriter,
XMLStreamConstants
{
final XMLStreamWriter2 mWriter;
/*
////////////////////////////////////////////////////
// Construction, init
////////////////////////////////////////////////////
*/
public Stax2EventWriterImpl(XMLStreamWriter2 sw)
{
mWriter = sw;
}
/*
////////////////////////////////////////////////////
// XMLEventWriter API
////////////////////////////////////////////////////
*/
/**
* Basic implementation of the method which will use event implementations
* available as part of the reference implementation.
*
*
*
* @author Tatu Saloranta
*/
public class Stax2ReaderAdapter
extends StreamReaderDelegate /* from Stax 1.0 */
implements XMLStreamReader2 /* From Stax2 */
,AttributeInfo
,DTDInfo
,LocationInfo
{
final static int INT_SPACE = 0x0020;
final private static int MASK_GET_ELEMENT_TEXT =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << ENTITY_REFERENCE);
final protected static int MASK_TYPED_ACCESS_BINARY =
(1 << START_ELEMENT) // note: END_ELEMENT handled separately
| (1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
;
/**
* Factory used for constructing decoders we need for typed access
*/
protected ValueDecoderFactory _decoderFactory;
/**
* Lazily-constructed decoder object for decoding base64 encoded
* binary content.
*/
protected StringBase64Decoder _base64Decoder = null;
/**
* Number of open (start) elements currently.
*/
protected int _depth = 0;
/**
* Content temporarily cached to be used for decoding typed content
* that is in chunked mode (int/long/float/double arrays, base64
* encoded binary data)
*/
protected String _typedContent;
/*
///////////////////////////////////////////////////////////////////////
// Life-cycle methods
///////////////////////////////////////////////////////////////////////
*/
protected Stax2ReaderAdapter(XMLStreamReader sr)
{
super(sr);
}
/**
* Method that should be used to add dynamic support for
* {@link XMLStreamReader2}. Method will check whether the
* stream reader passed happens to be a {@link XMLStreamReader2};
* and if it is, return it properly cast. If not, it will create
* necessary wrapper.
*/
public static XMLStreamReader2 wrapIfNecessary(XMLStreamReader sr)
{
if (sr instanceof XMLStreamReader2) {
return (XMLStreamReader2) sr;
}
return new Stax2ReaderAdapter(sr);
}
/*
///////////////////////////////////////////////////////////////////////
// Stax 1.0 methods overridden
///////////////////////////////////////////////////////////////////////
*/
public int next()
throws XMLStreamException
{
/* First special check: are we in the middle of chunked
* decode operation? If so, we'll just end it...
*/
if (_typedContent != null) {
_typedContent = null;
return XMLStreamConstants.END_ELEMENT;
}
int type = super.next();
if (type == XMLStreamConstants.START_ELEMENT) {
++_depth;
} else if (type == XMLStreamConstants.END_ELEMENT) {
--_depth;
}
return type;
}
/**
* As per [WSTX-254], must override and add handling for depth calculation here.
*/
public String getElementText() throws XMLStreamException
{
/* Should not succeed (as per specs) if not pointing to START_ELEMENT, but just in
* case some impls are more lenient, let's verify...
*/
boolean hadStart = (getEventType() == XMLStreamConstants.START_ELEMENT);
String text = super.getElementText();
if (hadStart) {
--_depth;
}
return text;
}
/*
///////////////////////////////////////////////////////////////////////
// TypedXMLStreamReader, element access
///////////////////////////////////////////////////////////////////////
*/
public boolean getElementAsBoolean() throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getElementAs(dec);
return dec.getValue();
}
public int getElementAsInt() throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getElementAs(dec);
return dec.getValue();
}
public long getElementAsLong() throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getElementAs(dec);
return dec.getValue();
}
public float getElementAsFloat() throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getElementAs(dec);
return dec.getValue();
}
public double getElementAsDouble() throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigInteger getElementAsInteger() throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigDecimal getElementAsDecimal() throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getElementAs(dec);
return dec.getValue();
}
public QName getElementAsQName() throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getElementAs(dec);
return dec.getValue();
}
public byte[] getElementAsBinary() throws XMLStreamException
{
return getElementAsBinary(Base64Variants.getDefaultVariant());
}
public byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException
{
// note: code here is similar to Base64DecoderBase.aggregateAll(), see comments there
Stax2Util.ByteAggregator aggr = _base64Decoder().getByteAggregator();
byte[] buffer = aggr.startAggregation();
while (true) {
int offset = 0;
int len = buffer.length;
do {
int readCount = readElementAsBinary(buffer, offset, len, v);
if (readCount < 1) { // all done!
return aggr.aggregateAll(buffer, offset);
}
offset += readCount;
len -= readCount;
} while (len > 0);
buffer = aggr.addFullBlock(buffer);
}
}
public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException
{
String value = getElementText();
value = Stax2Util.trimSpaces(value);
try {
if (value == null) {
tvd.handleEmptyValue();
} else {
tvd.decode(value);
}
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
public int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getIntArrayDecoder(value, from, length));
}
public int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getLongArrayDecoder(value, from, length));
}
public int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getFloatArrayDecoder(value, from, length));
}
public int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getDoubleArrayDecoder(value, from, length));
}
public int readElementAsArray(TypedArrayDecoder tad) throws XMLStreamException
{
// Are we started?
if (_typedContent == null) { // nope, not yet (or not any more?)
int type = getEventType();
if (type == END_ELEMENT) { // already done
return -1;
}
if (type != START_ELEMENT) {
throw new IllegalStateException("First call to readElementAsArray() must be for a START_ELEMENT");
}
_typedContent = getElementText();
/* This will move current event to END_ELEMENT, too...
* But should we mask it (and claim it's, say, CHARACTERS)
* or expose as is? For now, let's do latter, simplest
*/
}
// Ok, so what do we have left?
String input = _typedContent;
final int end = input.length();
int ptr = 0;
int count = 0;
String value = null;
try {
decode_loop:
while (ptr < end) {
// First, any space to skip?
while (input.charAt(ptr) <= INT_SPACE) {
if (++ptr >= end) {
break decode_loop;
}
}
// Then let's figure out non-space char (token)
int start = ptr;
++ptr;
while (ptr < end && input.charAt(ptr) > INT_SPACE) {
++ptr;
}
++count;
// And there we have it
value = input.substring(start, ptr);
// Plus, can skip trailing space (or at end, just beyond it)
++ptr;
if (tad.decodeValue(value)) {
break;
}
}
} catch (IllegalArgumentException iae) {
// Need to convert to a checked stream exception
/* Hmmh. This is not an accurate location... but it's
* about the best we can do
*/
Location loc = getLocation();
throw new TypedXMLStreamException(value, iae.getMessage(), loc, iae);
} finally {
int len = end-ptr;
// null works well as the marker for complete processing
_typedContent = (len < 1) ? null : input.substring(ptr);
}
return (count < 1) ? -1 : count;
}
/*
///////////////////////////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, binary data
///////////////////////////////////////////////////////////////////////
*/
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException
{
return readElementAsBinary(resultBuffer, offset, maxLength, Base64Variants.getDefaultVariant());
}
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength, Base64Variant v)
throws XMLStreamException
{
if (resultBuffer == null) {
throw new IllegalArgumentException("resultBuffer is null");
}
if (offset < 0) {
throw new IllegalArgumentException("Illegal offset ("+offset+"), must be [0, "+resultBuffer.length+"[");
}
if (maxLength < 1 || (offset + maxLength) > resultBuffer.length) {
if (maxLength == 0) { // special case, allowed, but won't do anything
return 0;
}
throw new IllegalArgumentException("Illegal maxLength ("+maxLength+"), has to be positive number, and offset+maxLength can not exceed"+resultBuffer.length);
}
final StringBase64Decoder dec = _base64Decoder();
int type = getEventType();
// First things first: must be acceptable start state:
if (((1 << type) & MASK_TYPED_ACCESS_BINARY) == 0) {
if (type == END_ELEMENT) {
// Minor complication: may have unflushed stuff (non-padded versions)
if (!dec.hasData()) {
return -1;
}
} else {
throwNotStartElemOrTextual(type);
}
}
// Are we just starting (START_ELEMENT)?
if (type == START_ELEMENT) {
// Just need to locate the first text segment (or reach END_ELEMENT)
while (true) {
type = next();
if (type == END_ELEMENT) {
// Simple... no textual content
return -1;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
throwNotStartElemOrTextual(type);
}
dec.init(v, true, getText());
break;
}
}
int totalCount = 0;
main_loop:
while (true) {
// Ok, decode:
int count;
try {
count = dec.decode(resultBuffer, offset, maxLength);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, "");
}
offset += count;
totalCount += count;
maxLength -= count;
/* And if we filled the buffer we are done. Or, an edge
* case: reached END_ELEMENT (for non-padded variant)
*/
if (maxLength < 1 || getEventType() == END_ELEMENT) {
break;
}
// Otherwise need to advance to the next event
while (true) {
type = next();
if (type == COMMENT || type == PROCESSING_INSTRUCTION
|| type == SPACE) { // space is ignorable too
continue;
}
if (type == END_ELEMENT) {
/* Just need to verify we don't have partial stuff
* (missing one to three characters of a full quartet
* that encodes 1 - 3 bytes). Also: non-padding
* variants can be in incomplete state, from which
* data may need to be flushed...
*/
int left = dec.endOfContent();
if (left < 0) { // incomplete, error
throw _constructTypeException("Incomplete base64 triplet at the end of decoded content", "");
} else if (left > 0) { // 1 or 2 more bytes of data, loop some more
continue main_loop;
}
// Otherwise, no more data, we are done
break main_loop;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
throwNotStartElemOrTextual(type);
}
dec.init(v, false, getText());
break;
}
}
// If nothing was found, needs to be indicated via -1, not 0
return (totalCount > 0) ? totalCount : -1;
}
/*
///////////////////////////////////////////////////////////////////////
// TypedXMLStreamReader, attribute access
///////////////////////////////////////////////////////////////////////
*/
public int getAttributeIndex(String namespaceURI, String localName)
{
return findAttributeIndex(namespaceURI, localName);
}
public boolean getAttributeAsBoolean(int index) throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public int getAttributeAsInt(int index) throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public long getAttributeAsLong(int index) throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public float getAttributeAsFloat(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public double getAttributeAsDouble(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigInteger getAttributeAsInteger(int index) throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getAttributeAs(index, dec);
return dec.getValue();
}
public QName getAttributeAsQName(int index) throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getAttributeAs(index, dec);
return dec.getValue();
}
public void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException
{
String value = getAttributeValue(index);
value = Stax2Util.trimSpaces(value);
try {
if (value == null) {
tvd.handleEmptyValue();
} else {
tvd.decode(value);
}
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
public int[] getAttributeAsIntArray(int index) throws XMLStreamException
{
ValueDecoderFactory.IntArrayDecoder dec = _decoderFactory().getIntArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public long[] getAttributeAsLongArray(int index) throws XMLStreamException
{
ValueDecoderFactory.LongArrayDecoder dec = _decoderFactory().getLongArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public float[] getAttributeAsFloatArray(int index) throws XMLStreamException
{
ValueDecoderFactory.FloatArrayDecoder dec = _decoderFactory().getFloatArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException
{
ValueDecoderFactory.DoubleArrayDecoder dec = _decoderFactory().getDoubleArrayDecoder();
_getAttributeAsArray(dec, getAttributeValue(index));
return dec.getValues();
}
public int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException
{
return _getAttributeAsArray(tad, getAttributeValue(index));
}
protected int _getAttributeAsArray(TypedArrayDecoder tad, String attrValue) throws XMLStreamException
{
int ptr = 0;
int start = 0;
final int end = attrValue.length();
String lexical = null;
int count = 0;
try {
decode_loop:
while (ptr < end) {
// First, any space to skip?
while (attrValue.charAt(ptr) <= INT_SPACE) {
if (++ptr >= end) {
break decode_loop;
}
}
// Then let's figure out non-space char (token)
start = ptr;
++ptr;
while (ptr < end && attrValue.charAt(ptr) > INT_SPACE) {
++ptr;
}
int tokenEnd = ptr;
++ptr; // to skip trailing space (or, beyond end)
// And there we have it
lexical = attrValue.substring(start, tokenEnd);
++count;
if (tad.decodeValue(lexical)) {
if (!checkExpand(tad)) {
break;
}
}
}
} catch (IllegalArgumentException iae) {
// Need to convert to a checked stream exception
Location loc = getLocation();
throw new TypedXMLStreamException(lexical, iae.getMessage(), loc, iae);
}
return count;
}
/**
* Internal method used to see if we can expand the buffer that
* the array decoder has. Bit messy, but simpler than having
* separately typed instances; and called rarely so that performance
* downside of instanceof is irrelevant.
*/
private final boolean checkExpand(TypedArrayDecoder tad)
{
if (tad instanceof ValueDecoderFactory.BaseArrayDecoder) {
((ValueDecoderFactory.BaseArrayDecoder) tad).expand();
return true;
}
return false;
}
public byte[] getAttributeAsBinary(int index) throws XMLStreamException
{
return getAttributeAsBinary(index, Base64Variants.getDefaultVariant());
}
public byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException
{
String lexical = getAttributeValue(index);
final StringBase64Decoder dec = _base64Decoder();
dec.init(v, true, lexical);
try {
return dec.decodeCompletely();
} catch (IllegalArgumentException iae) {
throw new TypedXMLStreamException(lexical, iae.getMessage(), getLocation(), iae);
}
}
/*
///////////////////////////////////////////////////////////////////////
// XMLStreamReader2 (StAX2) implementation
///////////////////////////////////////////////////////////////////////
*/
// // // StAX2, per-reader configuration
public Object getFeature(String name)
{
// No features defined
return null;
}
public void setFeature(String name, Object value)
{
// No features defined
}
// NOTE: getProperty() defined in Stax 1.0 interface
public boolean isPropertySupported(String name) {
/* No way to cleanly implement this using just Stax 1.0
* interface, so let's be conservative and decline any knowledge
* of properties...
*/
return false;
}
public boolean setProperty(String name, Object value)
{
return false; // could throw an exception too
}
// // // StAX2, additional traversal methods
public void skipElement() throws XMLStreamException
{
if (getEventType() != START_ELEMENT) {
throwNotStartElem(getEventType());
}
int nesting = 1; // need one more end elements than start elements
while (true) {
int type = next();
if (type == START_ELEMENT) {
++nesting;
} else if (type == END_ELEMENT) {
if (--nesting == 0) {
break;
}
}
}
}
// // // StAX2, additional attribute access
public AttributeInfo getAttributeInfo() throws XMLStreamException
{
if (getEventType() != START_ELEMENT) {
throwNotStartElem(getEventType());
}
return this;
}
// // // StAX2, Additional DTD access
public DTDInfo getDTDInfo() throws XMLStreamException
{
if (getEventType() != DTD) {
return null;
}
return this;
}
// // // StAX2, Additional location information
/**
* Location information is always accessible, for this reader.
*/
public final LocationInfo getLocationInfo() {
return this;
}
// // // StAX2, Pass-through text accessors
public int getText(Writer w, boolean preserveContents)
throws IOException, XMLStreamException
{
char[] cbuf = getTextCharacters();
int start = getTextStart();
int len = getTextLength();
if (len > 0) {
w.write(cbuf, start, len);
}
return len;
}
// // // StAX 2, Other accessors
/**
* @return Number of open elements in the stack; 0 when parser is in
* prolog/epilog, 1 inside root element and so on.
*/
public int getDepth()
{
/* 16-Jun-2008, tatus: Need to compensate for the fact
* that END_ELEMENT decrements "too early"
*/
if (getEventType() == END_ELEMENT) {
return _depth+1;
}
return _depth;
}
/**
* Alas, there is no way to find this out via Stax 1.0, so this
* implementation always returns false.
*/
public boolean isEmptyElement() throws XMLStreamException
{
return false;
}
public NamespaceContext getNonTransientNamespaceContext()
{
/* Too hard to construct without other info: let's bail
* and return null; this is better than return a transient
* one.
*/
return null;
}
public String getPrefixedName()
{
switch (getEventType()) {
case START_ELEMENT:
case END_ELEMENT:
{
String prefix = getPrefix();
String ln = getLocalName();
if (prefix == null || prefix.length() == 0) {
return ln;
}
StringBuffer sb = new StringBuffer(ln.length() + 1 + prefix.length());
sb.append(prefix);
sb.append(':');
sb.append(ln);
return sb.toString();
}
case ENTITY_REFERENCE:
return getLocalName();
case PROCESSING_INSTRUCTION:
return getPITarget();
case DTD:
return getDTDRootName();
}
throw new IllegalStateException("Current state not START_ELEMENT, END_ELEMENT, ENTITY_REFERENCE, PROCESSING_INSTRUCTION or DTD");
}
public void closeCompletely() throws XMLStreamException
{
/* As usual, Stax 1.0 offers no generic way of doing just this.
* But let's at least call the lame basic close()
*/
close();
}
/*
///////////////////////////////////////////////////////////////////////
// AttributeInfo implementation (StAX 2)
///////////////////////////////////////////////////////////////////////
*/
// Already part of XMLStreamReader
//public int getAttributeCount();
public int findAttributeIndex(String nsURI, String localName)
{
if ("".equals(nsURI)) {
nsURI = null;
}
for (int i = 0, len = getAttributeCount(); i < len; ++i) {
if (getAttributeLocalName(i).equals(localName)) {
String otherUri = getAttributeNamespace(i);
if (nsURI == null) {
if (otherUri == null || otherUri.length() == 0) {
return i;
}
} else {
if (nsURI.equals(otherUri)) {
return i;
}
}
}
}
return -1;
}
public int getIdAttributeIndex()
{
for (int i = 0, len = getAttributeCount(); i < len; ++i) {
if ("ID".equals(getAttributeType(i))) {
return i;
}
}
return -1;
}
public int getNotationAttributeIndex()
{
for (int i = 0, len = getAttributeCount(); i < len; ++i) {
if ("NOTATION".equals(getAttributeType(i))) {
return i;
}
}
return -1;
}
/*
///////////////////////////////////////////////////////////////////////
// DTDInfo implementation (StAX 2)
///////////////////////////////////////////////////////////////////////
*/
public Object getProcessedDTD() {
return null;
}
public String getDTDRootName() {
return null;
}
public String getDTDPublicId() {
return null;
}
public String getDTDSystemId() {
return null;
}
/**
* @return Internal subset portion of the DOCTYPE declaration, if any;
* empty String if none
*/
public String getDTDInternalSubset()
{
/* According to basic Stax API, getText() should return
* the internal subset. Not all implementations agree, so
* this may or may not work.
*/
if (getEventType() == XMLStreamConstants.DTD) {
return getText();
}
return null;
}
// // StAX2, v2.0
public DTDValidationSchema getProcessedDTDSchema() {
return null;
}
/*
///////////////////////////////////////////////////////////////////////
// LocationInfo implementation (StAX 2)
///////////////////////////////////////////////////////////////////////
*/
// // // First, the "raw" offset accessors:
public long getStartingByteOffset() {
return -1L;
}
public long getStartingCharOffset() {
return 0;
}
public long getEndingByteOffset() throws XMLStreamException
{
return -1;
}
public long getEndingCharOffset() throws XMLStreamException
{
return -1;
}
// // // and then the object-based access methods:
public XMLStreamLocation2 getStartLocation()
{
/* We don't really know whether location given is current,
* start or end, but it's the best approximation we have
* without knowing more about impl:
*/
return getCurrentLocation();
}
public XMLStreamLocation2 getCurrentLocation()
{
// Just need to adapt; no info on parent context, if any:
return new Stax2LocationAdapter(getLocation());
}
public final XMLStreamLocation2 getEndLocation()
throws XMLStreamException
{
/* We don't really know whether location given is current,
* start or end, but it's the best approximation we have
* without knowing more about impl:
*/
return getCurrentLocation();
}
/*
///////////////////////////////////////////////////////////////////////
// Stax2 validation
///////////////////////////////////////////////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
return null;
}
/*
///////////////////////////////////////////////////////////////////////
// Internal methods
///////////////////////////////////////////////////////////////////////
*/
protected ValueDecoderFactory _decoderFactory()
{
if (_decoderFactory == null) {
_decoderFactory = new ValueDecoderFactory();
}
return _decoderFactory;
}
protected StringBase64Decoder _base64Decoder()
{
if (_base64Decoder == null) {
_base64Decoder = new StringBase64Decoder();
}
return _base64Decoder;
}
protected void throwUnsupported()
throws XMLStreamException
{
throw new XMLStreamException("Unsupported method");
}
protected void throwNotStartElem(int type)
{
throw new IllegalStateException("Current event ("+Stax2Util.eventTypeDesc(type)+") not START_ELEMENT");
}
protected void throwNotStartElemOrTextual(int type)
{
throw new IllegalStateException("Current event ("+Stax2Util.eventTypeDesc(type)+") not START_ELEMENT, END_ELEMENT, CHARACTERS or CDATA");
}
/**
* Method called to wrap or convert given conversion-fail exception
* into a full {@link TypedXMLStreamException},
*
* @param iae Problem as reported by converter
* @param lexicalValue Lexical value (element content, attribute value)
* that could not be converted succesfully.
*/
protected TypedXMLStreamException _constructTypeException(IllegalArgumentException iae, String lexicalValue)
{
String msg = iae.getMessage();
if (msg == null) {
msg = "";
}
Location loc = getStartLocation();
if (loc == null) {
return new TypedXMLStreamException(lexicalValue, msg, iae);
}
return new TypedXMLStreamException(lexicalValue, msg, loc, iae);
}
protected TypedXMLStreamException _constructTypeException(String msg, String lexicalValue)
{
Location loc = getStartLocation();
if (loc == null) {
return new TypedXMLStreamException(lexicalValue, msg);
}
return new TypedXMLStreamException(lexicalValue, msg, loc);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2ReaderImpl.java 100644 0 0 43772 11520453235 21317 0 ustar 0 0 /* Stax2 API extension for Streaming Api for Xml processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import org.codehaus.stax2.typed.TypedArrayDecoder;
import org.codehaus.stax2.typed.TypedValueDecoder;
import org.codehaus.stax2.typed.TypedXMLStreamException;
import org.codehaus.stax2.validation.*;
import org.codehaus.stax2.ri.typed.ValueDecoderFactory;
/**
* This is a partial base implementation of {@link XMLStreamReader2},
* the extended stream reader that is part of Stax2.
*/
public abstract class Stax2ReaderImpl
implements XMLStreamReader2 /* From Stax2 */
,AttributeInfo
,DTDInfo
,LocationInfo
{
/**
* Factory used for constructing decoders we need for typed access
*/
protected ValueDecoderFactory _decoderFactory;
/*
////////////////////////////////////////////////////
// Life-cycle methods
////////////////////////////////////////////////////
*/
protected Stax2ReaderImpl()
{
}
/*
////////////////////////////////////////////////////
// XMLStreamReader2 (StAX2) implementation
////////////////////////////////////////////////////
*/
// // // StAX2, per-reader configuration
public Object getFeature(String name)
{
// No features defined
return null;
}
public void setFeature(String name, Object value)
{
// No features defined
}
// NOTE: getProperty() defined in Stax 1.0 interface
public boolean isPropertySupported(String name) {
/* No way to cleanly implement this using just Stax 1.0
* interface, so let's be conservative and decline any knowledge
* of properties...
*/
return false;
}
public boolean setProperty(String name, Object value)
{
return false; // could throw an exception too
}
// // // StAX2, additional traversal methods
public void skipElement() throws XMLStreamException
{
if (getEventType() != START_ELEMENT) {
throwNotStartElem();
}
int nesting = 1; // need one more end elements than start elements
while (true) {
int type = next();
if (type == START_ELEMENT) {
++nesting;
} else if (type == END_ELEMENT) {
if (--nesting == 0) {
break;
}
}
}
}
// // // StAX2, additional attribute access
public AttributeInfo getAttributeInfo() throws XMLStreamException
{
if (getEventType() != START_ELEMENT) {
throwNotStartElem();
}
return this;
}
// // // StAX2, Additional DTD access
public DTDInfo getDTDInfo() throws XMLStreamException
{
if (getEventType() != DTD) {
return null;
}
return this;
}
// // // StAX2, Additional location information
/**
* Location information is always accessible, for this reader.
*/
public final LocationInfo getLocationInfo() {
return this;
}
// // // StAX2, Pass-through text accessors
public int getText(Writer w, boolean preserveContents)
throws IOException, XMLStreamException
{
char[] cbuf = getTextCharacters();
int start = getTextStart();
int len = getTextLength();
if (len > 0) {
w.write(cbuf, start, len);
}
return len;
}
// // // StAX 2, Other accessors
/**
* @return Number of open elements in the stack; 0 when parser is in
* prolog/epilog, 1 inside root element and so on.
*/
public abstract int getDepth();
public abstract boolean isEmptyElement() throws XMLStreamException;
public abstract NamespaceContext getNonTransientNamespaceContext();
public String getPrefixedName()
{
switch (getEventType()) {
case START_ELEMENT:
case END_ELEMENT:
{
String prefix = getPrefix();
String ln = getLocalName();
if (prefix == null) {
return ln;
}
StringBuffer sb = new StringBuffer(ln.length() + 1 + prefix.length());
sb.append(prefix);
sb.append(':');
sb.append(ln);
return sb.toString();
}
case ENTITY_REFERENCE:
return getLocalName();
case PROCESSING_INSTRUCTION:
return getPITarget();
case DTD:
return getDTDRootName();
}
throw new IllegalStateException("Current state not START_ELEMENT, END_ELEMENT, ENTITY_REFERENCE, PROCESSING_INSTRUCTION or DTD");
}
public void closeCompletely() throws XMLStreamException
{
/* As usual, Stax 1.0 offers no generic way of doing just this.
* But let's at least call the lame basic close()
*/
close();
}
/*
////////////////////////////////////////////////////
// AttributeInfo implementation (StAX 2)
////////////////////////////////////////////////////
*/
// Already part of XMLStreamReader
//public int getAttributeCount();
public int findAttributeIndex(String nsURI, String localName)
{
// !!! TBI
return -1;
}
public int getIdAttributeIndex()
{
// !!! TBI
return -1;
}
public int getNotationAttributeIndex()
{
// !!! TBI
return -1;
}
/*
////////////////////////////////////////////////////
// DTDInfo implementation (StAX 2)
////////////////////////////////////////////////////
*/
public Object getProcessedDTD() {
return null;
}
public String getDTDRootName() {
return null;
}
public String getDTDPublicId() {
return null;
}
public String getDTDSystemId() {
return null;
}
/**
* @return Internal subset portion of the DOCTYPE declaration, if any;
* empty String if none
*/
public String getDTDInternalSubset() {
return null;
}
// // StAX2, v2.0
public DTDValidationSchema getProcessedDTDSchema() {
return null;
}
/*
////////////////////////////////////////////////////
// LocationInfo implementation (StAX 2)
////////////////////////////////////////////////////
*/
// // // First, the "raw" offset accessors:
public long getStartingByteOffset() {
return -1L;
}
public long getStartingCharOffset() {
return 0;
}
public long getEndingByteOffset() throws XMLStreamException
{
return -1;
}
public long getEndingCharOffset() throws XMLStreamException
{
return -1;
}
// // // and then the object-based access methods:
public abstract XMLStreamLocation2 getStartLocation();
public abstract XMLStreamLocation2 getCurrentLocation();
public abstract XMLStreamLocation2 getEndLocation()
throws XMLStreamException;
/*
////////////////////////////////////////////////////
// Stax2 validation
////////////////////////////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
throwUnsupported();
return null;
}
public abstract ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h);
/*
////////////////////////////////////////////////////////
// TypedXMLStreamReader, scalar elements
////////////////////////////////////////////////////////
*/
public boolean getElementAsBoolean() throws XMLStreamException
{
ValueDecoderFactory.BooleanDecoder dec = _decoderFactory().getBooleanDecoder();
getElementAs(dec);
return dec.getValue();
}
public int getElementAsInt() throws XMLStreamException
{
ValueDecoderFactory.IntDecoder dec = _decoderFactory().getIntDecoder();
getElementAs(dec);
return dec.getValue();
}
public long getElementAsLong() throws XMLStreamException
{
ValueDecoderFactory.LongDecoder dec = _decoderFactory().getLongDecoder();
getElementAs(dec);
return dec.getValue();
}
public float getElementAsFloat() throws XMLStreamException
{
ValueDecoderFactory.FloatDecoder dec = _decoderFactory().getFloatDecoder();
getElementAs(dec);
return dec.getValue();
}
public double getElementAsDouble() throws XMLStreamException
{
ValueDecoderFactory.DoubleDecoder dec = _decoderFactory().getDoubleDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigInteger getElementAsInteger() throws XMLStreamException
{
ValueDecoderFactory.IntegerDecoder dec = _decoderFactory().getIntegerDecoder();
getElementAs(dec);
return dec.getValue();
}
public BigDecimal getElementAsDecimal() throws XMLStreamException
{
ValueDecoderFactory.DecimalDecoder dec = _decoderFactory().getDecimalDecoder();
getElementAs(dec);
return dec.getValue();
}
public QName getElementAsQName() throws XMLStreamException
{
ValueDecoderFactory.QNameDecoder dec = _decoderFactory().getQNameDecoder(getNamespaceContext());
getElementAs(dec);
// !!! Should we try to verify validity of name chars?
return dec.getValue();
}
public byte[] getElementAsBinary() throws XMLStreamException
{
return getElementAsBinary(Base64Variants.getDefaultVariant());
}
// !!! TODO: copy code from Stax2ReaderAdapter?
public abstract byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException;
public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException
{
String value = getElementText();
try {
tvd.decode(value);
} catch (IllegalArgumentException iae) {
throw _constructTypeException(iae, value);
}
}
/*
////////////////////////////////////////////////////////
// TypedXMLStreamReader2 implementation, array elements
////////////////////////////////////////////////////////
*/
public int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getIntArrayDecoder(value, from, length));
}
public int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getLongArrayDecoder(value, from, length));
}
public int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getFloatArrayDecoder(value, from, length));
}
public int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException
{
return readElementAsArray(_decoderFactory().getDoubleArrayDecoder(value, from, length));
}
/**
* Actual implementation needs to implement tokenization and state
* keeping.
*lexical
had at least one
* non-space character; null otherwise
*/
public static String trimSpaces(String lexical)
{
int end = lexical.length();
int start = 0;
while (true) {
if (start >= end) {
return null;
}
if (!_isSpace(lexical.charAt(start))) {
break;
}
++start;
}
// No trailing space? Either original String as is, or just trim leading
--end;
if (!_isSpace(lexical.charAt(end))) {
return (start == 0) ? lexical : lexical.substring(start);
}
// Otherwise, at least some trailing ws...
while (--end > start && _isSpace(lexical.charAt(end))) { }
return lexical.substring(start, end+1);
}
/**
*StringBuilder
instead.
*/
private StringBuffer mBuilder = null;
public TextBuffer() { }
public void reset()
{
mText = null;
mBuilder = null;
}
public void append(String text)
{
int len = text.length();
if (len > 0) {
// Any prior text?
if (mText != null) {
mBuilder = new StringBuffer(mText.length() + len);
mBuilder.append(mText);
mText = null;
}
if (mBuilder != null) {
mBuilder.append(text);
} else {
mText = text;
}
}
}
public String get()
{
if (mText != null) {
return mText;
}
if (mBuilder != null) {
return mBuilder.toString();
}
return "";
}
public boolean isEmpty() { return (mText == null) && (mBuilder == null); }
}
/**
* Helper class for efficiently reading and aggregating variable length
* byte content.
*/
public final static class ByteAggregator
{
private final static byte[] NO_BYTES = new byte[0];
/**
* Size of the first block we will allocate.
*/
private final static int INITIAL_BLOCK_SIZE = 500;
/**
* Maximum block size we will use for individual non-aggregated
* blocks. Let's limit to using 256k chunks.
*/
//private final static int MAX_BLOCK_SIZE = (1 << 18);
final static int DEFAULT_BLOCK_ARRAY_SIZE = 100;
private byte[][] mBlocks;
private int mBlockCount;
private int mTotalLen;
/**
* Reusable byte buffer block; we retain biggest one from
* {@link #mBlocks} after aggregation.
*/
private byte[] mSpareBlock;
public ByteAggregator() { }
/**
* Method called to initialize aggregation process.
*
* @return Block that can be used to read in content
*/
public byte[] startAggregation()
{
mTotalLen = 0;
mBlockCount = 0;
byte[] result = mSpareBlock;
if (result == null) {
result = new byte[INITIAL_BLOCK_SIZE];
} else {
mSpareBlock = null;
}
return result;
}
/**
* Method used to add bufferful of data to the aggregator, and
* get another buffer to read more data into. Returned buffer
* is generally as big as or bigger than the given buffer, to try
* to improve performance for larger aggregations.
*
* @return Buffer in which to read additional data
*/
public byte[] addFullBlock(byte[] block)
{
int blockLen = block.length;
if (mBlocks == null) {
mBlocks = new byte[DEFAULT_BLOCK_ARRAY_SIZE][];
} else {
int oldLen = mBlocks.length;
if (mBlockCount >= oldLen) {
byte[][] old = mBlocks;
mBlocks = new byte[oldLen + oldLen][];
System.arraycopy(old, 0, mBlocks, 0, oldLen);
}
}
mBlocks[mBlockCount] = block;
++mBlockCount;
mTotalLen += blockLen;
/* Let's allocate block that's half the total size, except
* never smaller than twice the initial block size.
* The idea is just to grow with reasonable rate, to optimize
* between minimal number of chunks and minimal amount of
* wasted space.
*/
int newSize = Math.max((mTotalLen >> 1), (INITIAL_BLOCK_SIZE + INITIAL_BLOCK_SIZE));
return new byte[newSize];
}
/**
* Method called when results are finalized and we can get the
* full aggregated result buffer to return to the caller
*/
public byte[] aggregateAll(byte[] lastBlock, int lastLen)
{
int totalLen = mTotalLen + lastLen;
if (totalLen == 0) { // quick check: nothing aggregated?
return NO_BYTES;
}
byte[] result = new byte[totalLen];
int offset = 0;
if (mBlocks != null) {
for (int i = 0; i < mBlockCount; ++i) {
byte[] block = mBlocks[i];
int len = block.length;
System.arraycopy(block, 0, result, offset, len);
offset += len;
}
}
System.arraycopy(lastBlock, 0, result, offset, lastLen);
// can reuse the last block: should be the biggest one we've handed
mSpareBlock = lastBlock;
offset += lastLen;
if (offset != totalLen) { // just a sanity check
throw new RuntimeException("Internal error: total len assumed to be "+totalLen+", copied "+offset+" bytes");
}
return result;
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2WriterAdapter.java 100644 0 0 52623 11520453235 22043 0 ustar 0 0 /* Stax2 API extension for Streaming Api for Xml processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.ri.typed.SimpleValueEncoder;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
// Not from Stax 1.0, but Stax2 does provide it:
import org.codehaus.stax2.util.StreamWriterDelegate;
import org.codehaus.stax2.validation.ValidationProblemHandler;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.XMLValidator;
/**
* This adapter implements parts of {@link XMLStreamWriter2}, the
* extended stream writer defined by Stax2 extension, by wrapping
* a vanilla Stax 1.0 {@link XMLStreamReader} implementation.
*
*
*/
public class Stax2WriterAdapter
extends StreamWriterDelegate
implements XMLStreamWriter2 /* From Stax2 */
,XMLStreamConstants
{
/**
* Encoding we have determined to be used, according to method
* calls (write start document etc.)
*/
protected String mEncoding;
protected SimpleValueEncoder mValueEncoder;
protected final boolean mNsRepairing;
/*
////////////////////////////////////////////////////
// Life-cycle methods
////////////////////////////////////////////////////
*/
protected Stax2WriterAdapter(XMLStreamWriter sw)
{
super(sw);
mDelegate = sw;
Object value = sw.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
mNsRepairing = (value instanceof Boolean) && ((Boolean) value).booleanValue();
}
/**
* Method that should be used to add dynamic support for
* {@link XMLStreamWriter2}. Method will check whether the
* stream reader passed happens to be a {@link XMLStreamWriter2};
* and if it is, return it properly cast. If not, it will create
* necessary wrapper to support features needed by StaxMate,
* using vanilla Stax 1.0 interface.
*/
public static XMLStreamWriter2 wrapIfNecessary(XMLStreamWriter sw)
{
if (sw instanceof XMLStreamWriter2) {
return (XMLStreamWriter2) sw;
}
return new Stax2WriterAdapter(sw);
}
/*
/////////////////////////////////////////////////
// TypedXMLStreamWriter2 implementation
// (Typed Access API, Stax v3.0)
/////////////////////////////////////////////////
*/
// // // Typed element content write methods
public void writeBoolean(boolean b) throws XMLStreamException
{
mDelegate.writeCharacters(b ? "true" : "false");
}
public void writeInt(int value) throws XMLStreamException
{
mDelegate.writeCharacters(String.valueOf(value));
}
public void writeLong(long value) throws XMLStreamException
{
mDelegate.writeCharacters(String.valueOf(value));
}
public void writeFloat(float value) throws XMLStreamException
{
mDelegate.writeCharacters(String.valueOf(value));
}
public void writeDouble(double value) throws XMLStreamException
{
mDelegate.writeCharacters(String.valueOf(value));
}
public void writeInteger(BigInteger value) throws XMLStreamException
{
mDelegate.writeCharacters(value.toString());
}
public void writeDecimal(BigDecimal value) throws XMLStreamException
{
mDelegate.writeCharacters(value.toString());
}
public void writeQName(QName name) throws XMLStreamException
{
mDelegate.writeCharacters(serializeQNameValue(name));
}
public void writeIntArray(int[] value, int from, int length)
throws XMLStreamException
{
mDelegate.writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeLongArray(long[] value, int from, int length)
throws XMLStreamException
{
mDelegate.writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeFloatArray(float[] value, int from, int length)
throws XMLStreamException
{
mDelegate.writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeDoubleArray(double[] value, int from, int length)
throws XMLStreamException
{
mDelegate.writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeBinary(Base64Variant v, byte[] value, int from, int length)
throws XMLStreamException
{
mDelegate.writeCharacters(getValueEncoder().encodeAsString(v, value, from, length));
}
public void writeBinary(byte[] value, int from, int length)
throws XMLStreamException
{
writeBinary(Base64Variants.getDefaultVariant(), value, from, length);
}
// // // Typed attribute value write methods
public void writeBooleanAttribute(String prefix, String nsURI, String localName, boolean b) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, b ? "true" : "false");
}
public void writeIntAttribute(String prefix, String nsURI, String localName, int value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeLongAttribute(String prefix, String nsURI, String localName, long value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeFloatAttribute(String prefix, String nsURI, String localName, float value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeDoubleAttribute(String prefix, String nsURI, String localName, double value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeIntegerAttribute(String prefix, String nsURI, String localName, BigInteger value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, value.toString());
}
public void writeDecimalAttribute(String prefix, String nsURI, String localName, BigDecimal value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, value.toString());
}
public void writeQNameAttribute(String prefix, String nsURI, String localName, QName name) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName, serializeQNameValue(name));
}
public void writeIntArrayAttribute(String prefix, String nsURI, String localName, int[] value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeLongArrayAttribute(String prefix, String nsURI, String localName, long[] value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeFloatArrayAttribute(String prefix, String nsURI, String localName, float[] value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeDoubleArrayAttribute(String prefix, String nsURI, String localName, double[] value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeBinaryAttribute(String prefix, String nsURI, String localName, byte[] value) throws XMLStreamException
{
writeBinaryAttribute(Base64Variants.getDefaultVariant(), prefix, nsURI, localName, value);
}
public void writeBinaryAttribute(Base64Variant v, String prefix, String nsURI, String localName, byte[] value) throws XMLStreamException
{
mDelegate.writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(v, value, 0, value.length));
}
/*
////////////////////////////////////////////////////
// XMLStreamWriter2 (StAX2) implementation
////////////////////////////////////////////////////
*/
public boolean isPropertySupported(String name)
{
/* No real clean way to check this, so let's just fake by
* claiming nothing is supported
*/
return false;
}
public boolean setProperty(String name, Object value)
{
throw new IllegalArgumentException("No settable property '"+name+"'");
}
public XMLStreamLocation2 getLocation()
{
// No easy way to keep track of it, without impl support
return null;
}
public String getEncoding()
{
// We may have been able to infer it... if so:
return mEncoding;
}
public void writeCData(char[] text, int start, int len)
throws XMLStreamException
{
writeCData(new String(text, start, len));
}
public void writeDTD(String rootName, String systemId, String publicId,
String internalSubset)
throws XMLStreamException
{
/* This may or may not work... depending on how well underlying
* implementation follows stax 1.0 spec (it should work)
*/
StringBuffer sb = new StringBuffer();
sb.append(" 0) {
sb.append(" [");
sb.append(internalSubset);
sb.append(']');
}
sb.append('>');
writeDTD(sb.toString());
}
public void writeFullEndElement()
throws XMLStreamException
{
/* It may be possible to fake it, by pretending to write
* character output, which in turn should prevent writing of
* an empty element...
*/
mDelegate.writeCharacters("");
mDelegate.writeEndElement();
}
public void writeSpace(String text)
throws XMLStreamException
{
/* Hmmh. Two choices: either try to write as regular characters,
* or output as is via raw calls. Latter would be safer, if we
* had access to it; former may escape incorrectly.
* While this may not be optimal, let's try former
*/
writeRaw(text);
}
public void writeSpace(char[] text, int offset, int length)
throws XMLStreamException
{
// See comments above...
writeRaw(text, offset, length);
}
public void writeStartDocument(String version, String encoding,
boolean standAlone)
throws XMLStreamException
{
// No good way to do it, so let's do what we can...
writeStartDocument(encoding, version);
}
/*
///////////////////////////////
// Stax2, Pass-through methods
///////////////////////////////
*/
public void writeRaw(String text)
throws XMLStreamException
{
writeRaw(text, 0, text.length());
}
public void writeRaw(String text, int offset, int len)
throws XMLStreamException
{
// There is no clean way to implement this via Stax 1.0, alas...
throw new UnsupportedOperationException("Not implemented");
}
public void writeRaw(char[] text, int offset, int length)
throws XMLStreamException
{
writeRaw(new String(text, offset, length));
}
public void copyEventFromReader(XMLStreamReader2 sr, boolean preserveEventData)
throws XMLStreamException
{
switch (sr.getEventType()) {
case START_DOCUMENT:
{
String version = sr.getVersion();
/* No real declaration? If so, we don't want to output
* anything, to replicate as closely as possible the
* source document
*/
if (version == null || version.length() == 0) {
; // no output if no real input
} else {
if (sr.standaloneSet()) {
writeStartDocument(sr.getVersion(),
sr.getCharacterEncodingScheme(),
sr.isStandalone());
} else {
writeStartDocument(sr.getCharacterEncodingScheme(),
sr.getVersion());
}
}
}
return;
case END_DOCUMENT:
writeEndDocument();
return;
// Element start/end events:
case START_ELEMENT:
/* Start element is bit trickier to output since there
* may be differences between repairing/non-repairing
* writers. But let's try a generic handling here.
*/
copyStartElement(sr);
return;
case END_ELEMENT:
writeEndElement();
return;
case SPACE:
writeSpace(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case CDATA:
writeCData(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case CHARACTERS:
writeCharacters(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case COMMENT:
writeComment(sr.getText());
return;
case PROCESSING_INSTRUCTION:
writeProcessingInstruction(sr.getPITarget(), sr.getPIData());
return;
case DTD:
{
DTDInfo info = sr.getDTDInfo();
if (info == null) {
/* Hmmmh. Can this happen for non-DTD-aware readers?
* And if so, what should we do?
*/
throw new XMLStreamException("Current state DOCTYPE, but not DTDInfo Object returned -- reader doesn't support DTDs?");
}
writeDTD(info.getDTDRootName(), info.getDTDSystemId(),
info.getDTDPublicId(), info.getDTDInternalSubset());
}
return;
case ENTITY_REFERENCE:
writeEntityRef(sr.getLocalName());
return;
case ATTRIBUTE:
case NAMESPACE:
case ENTITY_DECLARATION:
case NOTATION_DECLARATION:
// Let's just fall back to throw the exception
}
throw new XMLStreamException("Unrecognized event type ("
+sr.getEventType()+"); not sure how to copy");
}
/*
///////////////////////////////
// Stax2, output handling
///////////////////////////////
*/
public void closeCompletely() throws XMLStreamException
{
/* 06-Nov-2008, TSa: alas, there is no way to properly implement
* this. Should we throw an exception? For now, let's just call
* regular close; not quite the same, but better than nothing
*/
close();
}
/*
///////////////////////////////
// Stax2, validation
///////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
// !!! TODO: try to implement?
throw new UnsupportedOperationException("Not yet implemented");
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
return null;
}
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
/* Not a real problem: although we can't do anything with it
* (without real validator integration)
*/
return null;
}
/*
///////////////////////////////
// Helper methods
///////////////////////////////
*/
protected void copyStartElement(XMLStreamReader sr)
throws XMLStreamException
{
// Any namespace declarations/bindings?
int nsCount = sr.getNamespaceCount();
if (nsCount > 0) { // yup, got some...
/* First, need to (or at least, should?) add prefix bindings:
* (may not be 100% required, but probably a good thing to do,
* just so that app code has access to prefixes then)
*/
for (int i = 0; i < nsCount; ++i) {
String prefix = sr.getNamespacePrefix(i);
String uri = sr.getNamespaceURI(i);
if (prefix == null || prefix.length() == 0) { // default NS
setDefaultNamespace(uri);
} else {
setPrefix(prefix, uri);
}
}
}
writeStartElement(sr.getPrefix(), sr.getLocalName(), sr.getNamespaceURI());
if (nsCount > 0) {
// And then output actual namespace declarations:
for (int i = 0; i < nsCount; ++i) {
String prefix = sr.getNamespacePrefix(i);
String uri = sr.getNamespaceURI(i);
if (prefix == null || prefix.length() == 0) { // default NS
writeDefaultNamespace(uri);
} else {
writeNamespace(prefix, uri);
}
}
}
/* And then let's just output attributes. But should we copy the
* implicit attributes (created via attribute defaulting?)
*/
int attrCount = sr.getAttributeCount();
if (attrCount > 0) {
for (int i = 0; i < attrCount; ++i) {
writeAttribute(sr.getAttributePrefix(i),
sr.getAttributeNamespace(i),
sr.getAttributeLocalName(i),
sr.getAttributeValue(i));
}
}
}
/**
* Method called to serialize given qualified name into valid
* String serialization, taking into account existing namespace
* bindings.
*/
protected String serializeQNameValue(QName name)
throws XMLStreamException
{
String prefix;
// Ok as is? In repairing mode need to ensure it's properly bound
if (mNsRepairing) {
String uri = name.getNamespaceURI();
// First: let's see if a valid binding already exists:
NamespaceContext ctxt = getNamespaceContext();
prefix = (ctxt == null) ? null : ctxt.getPrefix(uri);
if (prefix == null) {
// nope: need to (try to) bind
String origPrefix = name.getPrefix();
if (origPrefix == null || origPrefix.length() == 0) {
prefix = "";
/* note: could cause a namespace conflict... but
* there is nothing we can do with just stax1 stream
* writer
*/
writeDefaultNamespace(uri);
} else {
prefix = origPrefix;
writeNamespace(prefix, uri);
}
}
} else { // in non-repairing, good as is
prefix = name.getPrefix();
}
String local = name.getLocalPart();
if (prefix == null || prefix.length() == 0) {
return local;
}
// Not efficient... but should be ok
return prefix + ":" + local;
}
protected SimpleValueEncoder getValueEncoder()
{
if (mValueEncoder == null) {
mValueEncoder = new SimpleValueEncoder();
}
return mValueEncoder;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/Stax2WriterImpl.java 100644 0 0 25747 11520453235 21373 0 ustar 0 0 /* Stax2 API extension for Streaming Api for Xml processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri;
import javax.xml.stream.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.validation.*;
/**
* This is a partial base implementation of {@link XMLStreamWriter2},
* the extended stream writer that is part of Stax2.
*/
public abstract class Stax2WriterImpl
implements XMLStreamWriter2 /* From Stax2 */
,XMLStreamConstants
{
/*
///////////////////////////////////////////////////////////
// Life-cycle methods
///////////////////////////////////////////////////////////
*/
protected Stax2WriterImpl() { }
/*
///////////////////////////////////////////////////////////
// XMLStreamWriter2 (StAX2) implementation
///////////////////////////////////////////////////////////
*/
public boolean isPropertySupported(String name)
{
/* No base properties (or should we have something for impl
* name, version?)
*/
return false;
}
public boolean setProperty(String name, Object value)
{
throw new IllegalArgumentException("No settable property '"+name+"'");
}
public abstract XMLStreamLocation2 getLocation();
public abstract String getEncoding();
public void writeCData(char[] text, int start, int len)
throws XMLStreamException
{
writeCData(new String(text, start, len));
}
public void writeDTD(String rootName, String systemId, String publicId,
String internalSubset)
throws XMLStreamException
{
/* This may or may not work... depending on how well underlying
* implementation follows stax 1.0 spec (it should work)
*/
StringBuffer sb = new StringBuffer();
sb.append(" 0) {
sb.append(" [");
sb.append(internalSubset);
sb.append(']');
}
sb.append('>');
writeDTD(sb.toString());
}
public void writeFullEndElement()
throws XMLStreamException
{
/* This should work with base Stax 1.0 implementations.
* Sub-classes are, however, encouraged to implement it
* more directly, if possible.
*/
writeCharacters("");
writeEndElement();
}
public void writeSpace(String text)
throws XMLStreamException
{
/* Hmmh. Two choices: either try to write as regular characters,
* or output as is via raw calls. Latter would be safer, if we
* had access to it; former may escape incorrectly.
* While this may not be optimal, let's try former
*/
writeRaw(text);
}
public void writeSpace(char[] text, int offset, int length)
throws XMLStreamException
{
// See comments above...
writeRaw(text, offset, length);
}
public abstract void writeStartDocument(String version, String encoding,
boolean standAlone)
throws XMLStreamException;
/*
///////////////////////////////////////////////////////////
// Stax2, Pass-through methods
///////////////////////////////////////////////////////////
*/
public void writeRaw(String text)
throws XMLStreamException
{
writeRaw(text, 0, text.length());
}
public abstract void writeRaw(String text, int offset, int len)
throws XMLStreamException;
public abstract void writeRaw(char[] text, int offset, int length)
throws XMLStreamException;
public void copyEventFromReader(XMLStreamReader2 sr, boolean preserveEventData)
throws XMLStreamException
{
switch (sr.getEventType()) {
case START_DOCUMENT:
{
String version = sr.getVersion();
/* No real declaration? If so, we don't want to output
* anything, to replicate as closely as possible the
* source document
*/
if (version == null || version.length() == 0) {
; // no output if no real input
} else {
if (sr.standaloneSet()) {
writeStartDocument(sr.getVersion(),
sr.getCharacterEncodingScheme(),
sr.isStandalone());
} else {
writeStartDocument(sr.getCharacterEncodingScheme(),
sr.getVersion());
}
}
}
return;
case END_DOCUMENT:
writeEndDocument();
return;
// Element start/end events:
case START_ELEMENT:
/* Start element is bit trickier to output since there
* may be differences between repairing/non-repairing
* writers. But let's try a generic handling here.
*/
copyStartElement(sr);
return;
case END_ELEMENT:
writeEndElement();
return;
case SPACE:
writeSpace(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case CDATA:
writeCData(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case CHARACTERS:
writeCharacters(sr.getTextCharacters(), sr.getTextStart(), sr.getTextLength());
return;
case COMMENT:
writeComment(sr.getText());
return;
case PROCESSING_INSTRUCTION:
writeProcessingInstruction(sr.getPITarget(), sr.getPIData());
return;
case DTD:
{
DTDInfo info = sr.getDTDInfo();
if (info == null) {
/* Hmmmh. Can this happen for non-DTD-aware readers?
* And if so, what should we do?
*/
throw new XMLStreamException("Current state DOCTYPE, but not DTDInfo Object returned -- reader doesn't support DTDs?");
}
writeDTD(info.getDTDRootName(), info.getDTDSystemId(),
info.getDTDPublicId(), info.getDTDInternalSubset());
}
return;
case ENTITY_REFERENCE:
writeEntityRef(sr.getLocalName());
return;
case ATTRIBUTE:
case NAMESPACE:
case ENTITY_DECLARATION:
case NOTATION_DECLARATION:
// Let's just fall back to throw the exception
}
throw new XMLStreamException("Unrecognized event type ("
+sr.getEventType()+"); not sure how to copy");
}
/*
///////////////////////////////////////////////////////////
// Stax2, validation
///////////////////////////////////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
throw new UnsupportedOperationException("Not yet implemented");
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
return null;
}
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
/* Not a real problem: although we can't do anything with it
* (without real validator integration)
*/
return null;
}
/*
///////////////////////////////////////////////////////////
// Helper methods
///////////////////////////////////////////////////////////
*/
/**
* Basic implementation of copy operation. It is likely that
* sub-classes can implement more efficient copy operations: if so,
* they should do so.
*/
protected void copyStartElement(XMLStreamReader sr)
throws XMLStreamException
{
// Any namespace declarations/bindings?
int nsCount = sr.getNamespaceCount();
if (nsCount > 0) { // yup, got some...
/* First, need to (or at least, should?) add prefix bindings:
* (may not be 100% required, but probably a good thing to do,
* just so that app code has access to prefixes then)
*/
for (int i = 0; i < nsCount; ++i) {
String prefix = sr.getNamespacePrefix(i);
String uri = sr.getNamespaceURI(i);
if (prefix == null || prefix.length() == 0) { // default NS
setDefaultNamespace(uri);
} else {
setPrefix(prefix, uri);
}
}
}
writeStartElement(sr.getPrefix(), sr.getLocalName(), sr.getNamespaceURI());
if (nsCount > 0) {
// And then output actual namespace declarations:
for (int i = 0; i < nsCount; ++i) {
String prefix = sr.getNamespacePrefix(i);
String uri = sr.getNamespaceURI(i);
if (prefix == null || prefix.length() == 0) { // default NS
writeDefaultNamespace(uri);
} else {
writeNamespace(prefix, uri);
}
}
}
/* And then let's just output attributes. But should we copy the
* implicit attributes (created via attribute defaulting?)
*/
int attrCount = sr.getAttributeCount();
if (attrCount > 0) {
for (int i = 0; i < attrCount; ++i) {
writeAttribute(sr.getAttributePrefix(i),
sr.getAttributeNamespace(i),
sr.getAttributeLocalName(i),
sr.getAttributeValue(i));
}
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/dom/DOMWrappingReader.java 100644 0 0 223445 11520453235 22417 0 ustar 0 0 /* Stax2 API extension for Streaming API for XML processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.dom;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import org.w3c.dom.*;
import org.codehaus.stax2.AttributeInfo;
import org.codehaus.stax2.DTDInfo;
import org.codehaus.stax2.LocationInfo;
import org.codehaus.stax2.XMLStreamLocation2;
import org.codehaus.stax2.XMLStreamReader2;
import org.codehaus.stax2.ri.EmptyIterator;
import org.codehaus.stax2.ri.EmptyNamespaceContext;
import org.codehaus.stax2.ri.SingletonIterator;
import org.codehaus.stax2.ri.Stax2Util;
import org.codehaus.stax2.ri.typed.StringBase64Decoder;
import org.codehaus.stax2.ri.typed.ValueDecoderFactory;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import org.codehaus.stax2.typed.TypedArrayDecoder;
import org.codehaus.stax2.typed.TypedValueDecoder;
import org.codehaus.stax2.typed.TypedXMLStreamException;
import org.codehaus.stax2.validation.DTDValidationSchema;
import org.codehaus.stax2.validation.ValidationProblemHandler;
import org.codehaus.stax2.validation.XMLValidationSchema;
import org.codehaus.stax2.validation.XMLValidator;
/**
* This is an adapter class that presents a DOM document as if it was
* a regular {@link XMLStreamReader}. This is mostly useful for
* inter-operability purposes, and should only be used when the
* input has to come as a DOM object and the original xml content
* is not available as a stream.
*javax.xml.transform.dom.DOMSource
. It can however be
* used for both full documents, and single element root fragments,
* depending on what node is passed as the argument.
*
*
*/
public abstract class DOMWrappingReader
implements XMLStreamReader2,
AttributeInfo, DTDInfo, LocationInfo,
NamespaceContext,
XMLStreamConstants
{
protected final static int INT_SPACE = 0x0020;
// // // Bit masks used for quick type comparisons
final private static int MASK_GET_TEXT =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << COMMENT) | (1 << DTD) | (1 << ENTITY_REFERENCE);
final private static int MASK_GET_TEXT_XXX =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE) | (1 << COMMENT);
final private static int MASK_GET_ELEMENT_TEXT =
(1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
| (1 << ENTITY_REFERENCE);
final protected static int MASK_TYPED_ACCESS_BINARY =
(1 << START_ELEMENT) // note: END_ELEMENT handled separately
| (1 << CHARACTERS) | (1 << CDATA) | (1 << SPACE)
;
// // // Enumerated error case ids
/**
* Current state not START_ELEMENT, should be
*/
protected final static int ERR_STATE_NOT_START_ELEM = 1;
/**
* Current state not START_ELEMENT or END_ELEMENT, should be
*/
protected final static int ERR_STATE_NOT_ELEM = 2;
/**
* Current state not PROCESSING_INSTRUCTION
*/
protected final static int ERR_STATE_NOT_PI = 3;
/**
* Current state not one where getText() can be used
*/
protected final static int ERR_STATE_NOT_TEXTUAL = 4;
/**
* Current state not one where getTextXxx() can be used
*/
protected final static int ERR_STATE_NOT_TEXTUAL_XXX = 5;
protected final static int ERR_STATE_NOT_TEXTUAL_OR_ELEM = 6;
protected final static int ERR_STATE_NO_LOCALNAME = 7;
// // // Configuration:
protected final String _systemId;
protected final Node _rootNode;
/**
* Whether stream reader is to be namespace aware (as per property
* {@link XMLInputFactory#IS_NAMESPACE_AWARE}) or not
*/
protected final boolean _cfgNsAware;
/**
* Whether stream reader is to coalesce adjacent textual
* (CHARACTERS, SPACE, CDATA) events (as per property
* {@link XMLInputFactory#IS_COALESCING}) or not
*/
protected final boolean _coalescing;
/**
* By default we do not force interning of names: can be
* reset by sub-classes.
*/
protected boolean _cfgInternNames = false;
/**
* By default we do not force interning of namespace URIs: can be
* reset by sub-classes.
*/
protected boolean _cfgInternNsURIs = false;
// // // State:
protected int _currEvent = START_DOCUMENT;
/**
* Current node is the DOM node that contains information
* regarding the current event.
*/
protected Node _currNode;
protected int _depth = 0;
/**
* In coalescing mode, we may need to combine textual content
* from multiple adjacent nodes. Since we shouldn't be modifying
* the underlying DOM tree, need to accumulate it into a temporary
* variable
*/
protected String _coalescedText;
/**
* Helper object used for combining segments of text as needed
*/
protected Stax2Util.TextBuffer _textBuffer = new Stax2Util.TextBuffer();
// // // Attribute/namespace declaration state
/* DOM, alas, does not distinguish between namespace declarations
* and attributes (due to its roots prior to XML namespaces?).
* Because of this, two lists need to be separated. Since this
* information is often not needed, it will be lazily generated.
*/
/**
* Lazily instantiated List of all actual attributes for the
* current (start) element, NOT including namespace declarations.
* As such, elements are {@link org.w3c.dom.Attr} instances.
*
* Reads the content of a text-only element, an exception is thrown if
* this is not a text-only element.
* Regardless of value of javax.xml.stream.isCoalescing this method always
* returns coalesced content.
*
*/
public String getElementText()
throws XMLStreamException
{
if (_currEvent != START_ELEMENT) {
/* Quite illogical: this is not an IllegalStateException
* like other similar ones, but rather an XMLStreamException.
* But that's how Stax JavaDocs outline how it should be.
*/
reportParseProblem(ERR_STATE_NOT_START_ELEM);
}
// As per [WSTX-244], handling of coalescing, regular differ a lot, so:
if (_coalescing) {
String text = null;
// Need to loop to get rid of PIs, comments
while (true) {
int type = next();
if (type == END_ELEMENT) {
break;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
reportParseProblem(ERR_STATE_NOT_TEXTUAL);
}
if (text == null) {
text = getText();
} else { // uncommon but possible (with comments, PIs):
text = text + getText();
}
}
return (text == null) ? "" : text;
}
_textBuffer.reset();
// Need to loop to get rid of PIs, comments
while (true) {
int type = next();
if (type == END_ELEMENT) {
break;
}
if (type == COMMENT || type == PROCESSING_INSTRUCTION) {
continue;
}
if (((1 << type) & MASK_GET_ELEMENT_TEXT) == 0) {
reportParseProblem(ERR_STATE_NOT_TEXTUAL);
}
_textBuffer.append(getText());
}
return _textBuffer.get();
}
/**
* Returns type of the last event returned; or START_DOCUMENT before
* any events has been explicitly returned.
*/
public int getEventType()
{
return _currEvent;
}
public String getLocalName()
{
if (_currEvent == START_ELEMENT || _currEvent == END_ELEMENT) {
return _internName(_safeGetLocalName(_currNode));
}
if (_currEvent != ENTITY_REFERENCE) {
reportWrongState(ERR_STATE_NO_LOCALNAME);
}
return _internName(_currNode.getNodeName());
}
public final Location getLocation() {
return getStartLocation();
}
public QName getName()
{
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
return _constructQName(_currNode.getNamespaceURI(), _safeGetLocalName(_currNode), _currNode.getPrefix());
}
// // // Namespace access
public NamespaceContext getNamespaceContext() {
return this;
}
public int getNamespaceCount()
{
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_ELEM);
}
if (_nsDeclList == null) {
if (!_cfgNsAware) {
return 0;
}
_calcNsAndAttrLists(_currEvent == START_ELEMENT);
}
return _nsDeclList.size() / 2;
}
/**
* Alas, DOM does not expose any of information necessary for
* determining actual declarations. Thus, have to indicate that
* there are no declarations.
*/
public String getNamespacePrefix(int index) {
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_ELEM);
}
if (_nsDeclList == null) {
if (!_cfgNsAware) {
handleIllegalNsIndex(index);
}
_calcNsAndAttrLists(_currEvent == START_ELEMENT);
}
if (index < 0 || (index + index) >= _nsDeclList.size()) {
handleIllegalNsIndex(index);
}
// Note: _nsDeclList entries have been appropriately intern()ed if need be
return (String) _nsDeclList.get(index + index);
}
public String getNamespaceURI() {
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_ELEM);
}
return _internNsURI(_currNode.getNamespaceURI());
}
public String getNamespaceURI(int index) {
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_ELEM);
}
if (_nsDeclList == null) {
if (!_cfgNsAware) {
handleIllegalNsIndex(index);
}
_calcNsAndAttrLists(_currEvent == START_ELEMENT);
}
if (index < 0 || (index + index) >= _nsDeclList.size()) {
handleIllegalNsIndex(index);
}
// Note: _nsDeclList entries have been appropriately intern()ed if need be
return (String) _nsDeclList.get(index + index + 1);
}
// Note: implemented as part of NamespaceContext
//public String getNamespaceURI(String prefix)
public String getPIData() {
if (_currEvent != PROCESSING_INSTRUCTION) {
reportWrongState(ERR_STATE_NOT_PI);
}
return _currNode.getNodeValue();
}
public String getPITarget() {
if (_currEvent != PROCESSING_INSTRUCTION) {
reportWrongState(ERR_STATE_NOT_PI);
}
return _internName(_currNode.getNodeName());
}
public String getPrefix() {
if (_currEvent != START_ELEMENT && _currEvent != END_ELEMENT) {
reportWrongState(ERR_STATE_NOT_ELEM);
}
return _internName(_currNode.getPrefix());
}
public String getText()
{
if (_coalescedText != null) {
return _coalescedText;
}
if (((1 << _currEvent) & MASK_GET_TEXT) == 0) {
reportWrongState(ERR_STATE_NOT_TEXTUAL);
}
return _currNode.getNodeValue();
}
public char[] getTextCharacters()
{
String text = getText();
return text.toCharArray();
}
public int getTextCharacters(int sourceStart, char[] target, int targetStart, int len)
{
if (((1 << _currEvent) & MASK_GET_TEXT_XXX) == 0) {
reportWrongState(ERR_STATE_NOT_TEXTUAL_XXX);
}
String text = getText();
if (len > text.length()) {
len = text.length();
}
text.getChars(sourceStart, sourceStart+len, target, targetStart);
return len;
}
public int getTextLength()
{
if (((1 << _currEvent) & MASK_GET_TEXT_XXX) == 0) {
reportWrongState(ERR_STATE_NOT_TEXTUAL_XXX);
}
return getText().length();
}
public int getTextStart()
{
if (((1 << _currEvent) & MASK_GET_TEXT_XXX) == 0) {
reportWrongState(ERR_STATE_NOT_TEXTUAL_XXX);
}
return 0;
}
public boolean hasName() {
return (_currEvent == START_ELEMENT) || (_currEvent == END_ELEMENT);
}
public boolean hasNext() {
return (_currEvent != END_DOCUMENT);
}
public boolean hasText() {
return (((1 << _currEvent) & MASK_GET_TEXT) != 0);
}
public boolean isAttributeSpecified(int index)
{
if (_currEvent != START_ELEMENT) {
reportWrongState(ERR_STATE_NOT_START_ELEM);
}
Element elem = (Element) _currNode;
Attr attr = (Attr) elem.getAttributes().item(index);
if (attr == null) {
handleIllegalAttrIndex(index);
return false;
}
return attr.getSpecified();
}
public boolean isCharacters()
{
return (_currEvent == CHARACTERS);
}
public boolean isEndElement() {
return (_currEvent == END_ELEMENT);
}
public boolean isStartElement() {
return (_currEvent == START_ELEMENT);
}
public boolean isWhiteSpace()
{
if (_currEvent == CHARACTERS || _currEvent == CDATA) {
String text = getText();
for (int i = 0, len = text.length(); i < len; ++i) {
/* !!! If xml 1.1 was to be handled, should check for
* LSEP and NEL too?
*/
if (text.charAt(i) > INT_SPACE) {
return false;
}
}
return true;
}
return (_currEvent == SPACE);
}
public void require(int type, String nsUri, String localName)
throws XMLStreamException
{
int curr = _currEvent;
/* There are some special cases; specifically, SPACE and CDATA
* are sometimes reported as CHARACTERS. Let's be lenient by
* allowing both 'real' and reported types, for now.
*/
if (curr != type) {
if (curr == CDATA) {
curr = CHARACTERS;
} else if (curr == SPACE) {
curr = CHARACTERS;
}
}
if (type != curr) {
throwStreamException("Required type "+Stax2Util.eventTypeDesc(type)
+", current type "
+Stax2Util.eventTypeDesc(curr));
}
if (localName != null) {
if (curr != START_ELEMENT && curr != END_ELEMENT
&& curr != ENTITY_REFERENCE) {
throwStreamException("Required a non-null local name, but current token not a START_ELEMENT, END_ELEMENT or ENTITY_REFERENCE (was "+Stax2Util.eventTypeDesc(_currEvent)+")");
}
String n = getLocalName();
if (n != localName && !n.equals(localName)) {
throwStreamException("Required local name '"+localName+"'; current local name '"+n+"'.");
}
}
if (nsUri != null) {
if (curr != START_ELEMENT && curr != END_ELEMENT) {
throwStreamException("Required non-null NS URI, but current token not a START_ELEMENT or END_ELEMENT (was "+Stax2Util.eventTypeDesc(curr)+")");
}
String uri = getNamespaceURI();
// No namespace?
if (nsUri.length() == 0) {
if (uri != null && uri.length() > 0) {
throwStreamException("Required empty namespace, instead have '"+uri+"'.");
}
} else {
if ((nsUri != uri) && !nsUri.equals(uri)) {
throwStreamException("Required namespace '"+nsUri+"'; have '"
+uri+"'.");
}
}
}
// Ok, fine, all's good
}
/*
////////////////////////////////////////////////////
// XMLStreamReader, iterating
////////////////////////////////////////////////////
*/
public int next()
throws XMLStreamException
{
_coalescedText = null;
/* For most events, we just need to find the next sibling; and
* that failing, close the parent element. But there are couple
* of special cases, which are handled first:
*/
switch (_currEvent) {
case START_DOCUMENT: // initial state
/* What to do here depends on what kind of node we started
* with...
*/
switch (_currNode.getNodeType()) {
case Node.DOCUMENT_NODE:
case Node.DOCUMENT_FRAGMENT_NODE:
// For doc, fragment, need to find first child
_currNode = _currNode.getFirstChild();
// as per [WSTX-259], need to handle degenerate case of empty fragment, too
if (_currNode == null) {
return (_currEvent = END_DOCUMENT);
}
break;
case Node.ELEMENT_NODE:
// For element, curr node is fine:
return (_currEvent = START_ELEMENT);
default:
throw new XMLStreamException("Internal error: unexpected DOM root node type "+_currNode.getNodeType()+" for node '"+_currNode+"'");
}
break;
case END_DOCUMENT: // end reached: should not call!
throw new java.util.NoSuchElementException("Can not call next() after receiving END_DOCUMENT");
case START_ELEMENT: // element returned, need to traverse children, if any
++_depth;
_attrList = null; // so it will not get reused accidentally
{
Node firstChild = _currNode.getFirstChild();
if (firstChild == null) { // empty? need to return virtual END_ELEMENT
/* Note: need not clear namespace declarations, because
* it'll be the same as for the start elem!
*/
return (_currEvent = END_ELEMENT);
}
_nsDeclList = null;
/* non-empty is easy: let's just swap curr node, and
* fall through to regular handling
*/
_currNode = firstChild;
break;
}
case END_ELEMENT:
--_depth;
// Need to clear these lists
_attrList = null;
_nsDeclList = null;
/* One special case: if we hit the end of children of
* the root element (when tree constructed with Element,
* instead of Document or DocumentFragment). If so, it'll
* be END_DOCUMENT:
*/
if (_currNode == _rootNode) {
return (_currEvent = END_DOCUMENT);
}
// Otherwise need to fall through to default handling:
default:
/* For anything else, we can and should just get the
* following sibling.
*/
{
Node next = _currNode.getNextSibling();
// If sibling, let's just assign and fall through
if (next != null) {
_currNode = next;
break;
}
/* Otherwise, need to climb up _the stack and either
* return END_ELEMENT (if parent is element) or
* END_DOCUMENT (if not; needs to be root, then)
*/
_currNode = _currNode.getParentNode();
int type = _currNode.getNodeType();
if (type == Node.ELEMENT_NODE) {
return (_currEvent = END_ELEMENT);
}
// Let's do sanity check; should really be Doc/DocFragment
if (_currNode != _rootNode ||
(type != Node.DOCUMENT_NODE && type != Node.DOCUMENT_FRAGMENT_NODE)) {
throw new XMLStreamException("Internal error: non-element parent node ("+type+") that is not the initial root node");
}
return (_currEvent = END_DOCUMENT);
}
}
// Ok, need to determine current node type:
switch (_currNode.getNodeType()) {
case Node.CDATA_SECTION_NODE:
if (_coalescing) {
coalesceText(CDATA);
} else {
_currEvent = CDATA;
}
break;
case Node.COMMENT_NODE:
_currEvent = COMMENT;
break;
case Node.DOCUMENT_TYPE_NODE:
_currEvent = DTD;
break;
case Node.ELEMENT_NODE:
_currEvent = START_ELEMENT;
break;
case Node.ENTITY_REFERENCE_NODE:
_currEvent = ENTITY_REFERENCE;
break;
case Node.PROCESSING_INSTRUCTION_NODE:
_currEvent = PROCESSING_INSTRUCTION;
break;
case Node.TEXT_NODE:
if (_coalescing) {
coalesceText(CHARACTERS);
} else {
_currEvent = CHARACTERS;
}
break;
// Should not get other nodes (notation/entity decl., attr)
case Node.ATTRIBUTE_NODE:
case Node.ENTITY_NODE:
case Node.NOTATION_NODE:
throw new XMLStreamException("Internal error: unexpected DOM node type "+_currNode.getNodeType()+" (attr/entity/notation?), for node '"+_currNode+"'");
default:
throw new XMLStreamException("Internal error: unrecognized DOM node type "+_currNode.getNodeType()+", for node '"+_currNode+"'");
}
return _currEvent;
}
public int nextTag()
throws XMLStreamException
{
while (true) {
int next = next();
switch (next) {
case SPACE:
case COMMENT:
case PROCESSING_INSTRUCTION:
continue;
case CDATA:
case CHARACTERS:
if (isWhiteSpace()) {
continue;
}
throwStreamException("Received non-all-whitespace CHARACTERS or CDATA event in nextTag().");
break; // never gets here, but jikes complains without
case START_ELEMENT:
case END_ELEMENT:
return next;
}
throwStreamException("Received event "+Stax2Util.eventTypeDesc(next)
+", instead of START_ELEMENT or END_ELEMENT.");
}
}
/**
*
Precondition: the current event is START_ELEMENT.
*
Postcondition: the current event is the corresponding END_ELEMENT.
*this
.
*/
public DTDInfo getDTDInfo() throws XMLStreamException
{
/* Let's not allow it to be accessed during other events -- that
* way callers won't count on it being available afterwards.
*/
if (_currEvent != DTD) {
return null;
}
return this;
}
// // // StAX2, Additional location information
/**
* Location information is always accessible, for this reader.
*/
public final LocationInfo getLocationInfo() {
return this;
}
// // // StAX2, Pass-through text accessors
/**
* Method similar to {@link #getText()}, except
* that it just uses provided Writer to write all textual content.
* For further optimization, it may also be allowed to do true
* pass-through, thus possibly avoiding one temporary copy of the
* data.
*getText
will return
* proper conntets. If false, reader is allowed to skip creation
* of such copies: this can improve performance, but it also means
* that further calls to getText
is not guaranteed to
* return meaningful data.
*
* @return Number of characters written to the reader
*/
public int getText(Writer w, boolean preserveContents)
throws IOException, XMLStreamException
{
String text = getText();
w.write(text);
return text.length();
}
// // // StAX 2, Other accessors
/**
* @return Number of open elements in the stack; 0 when parser is in
* prolog/epilog, 1 inside root element and so on.
*/
public int getDepth() {
return _depth;
}
/**
* @return True, if cursor points to a start or end element that is
* constructed from 'empty' element (ends with '/>');
* false otherwise.
*/
public boolean isEmptyElement() throws XMLStreamException
{
// No way to really figure it out via DOM is there?
return false;
}
public NamespaceContext getNonTransientNamespaceContext()
{
/* Since DOM does not expose enough functionality to figure
* out complete declaration stack, can not implement.
* Can either return null, or a dummy instance. For now, let's
* do latter:
*/
return EmptyNamespaceContext.getInstance();
}
public String getPrefixedName()
{
switch (_currEvent) {
case START_ELEMENT:
case END_ELEMENT:
{
String prefix = _currNode.getPrefix();
String ln = _safeGetLocalName(_currNode);
if (prefix == null) {
return _internName(ln);
}
StringBuffer sb = new StringBuffer(ln.length() + 1 + prefix.length());
sb.append(prefix);
sb.append(':');
sb.append(ln);
return _internName(sb.toString());
}
case ENTITY_REFERENCE:
return getLocalName();
case PROCESSING_INSTRUCTION:
return getPITarget();
case DTD:
return getDTDRootName();
}
throw new IllegalStateException("Current state ("+Stax2Util.eventTypeDesc(_currEvent)+") not START_ELEMENT, END_ELEMENT, ENTITY_REFERENCE, PROCESSING_INSTRUCTION or DTD");
}
public void closeCompletely() throws XMLStreamException
{
// Nothing special to do...
}
/*
////////////////////////////////////////////////////
// DTDInfo implementation (StAX 2)
////////////////////////////////////////////////////
*/
public Object getProcessedDTD() {
return null;
}
public String getDTDRootName() {
if (_currEvent == DTD) {
return _internName(((DocumentType) _currNode).getName());
}
return null;
}
public String getDTDPublicId() {
if (_currEvent == DTD) {
return ((DocumentType) _currNode).getPublicId();
}
return null;
}
public String getDTDSystemId() {
if (_currEvent == DTD) {
return ((DocumentType) _currNode).getSystemId();
}
return null;
}
/**
* @return Internal subset portion of the DOCTYPE declaration, if any;
* empty String if none
*/
public String getDTDInternalSubset() {
/* DOM (level 3) doesn't expose anything extra; would need to
* synthetize subset... which would only contain some of the
* entity and notation declarations.
*/
return null;
}
// // StAX2, v2.0
public DTDValidationSchema getProcessedDTDSchema() {
return null;
}
/*
////////////////////////////////////////////////////
// LocationInfo implementation (StAX 2)
////////////////////////////////////////////////////
*/
// // // First, the "raw" offset accessors:
public long getStartingByteOffset() {
// !!! TBI
return -1L;
}
public long getStartingCharOffset() {
// !!! TBI
return 0;
}
public long getEndingByteOffset() throws XMLStreamException
{
// !!! TBI
return -1;
}
public long getEndingCharOffset() throws XMLStreamException
{
// !!! TBI
return -1;
}
// // // and then the object-based access methods:
public XMLStreamLocation2 getStartLocation()
{
return XMLStreamLocation2.NOT_AVAILABLE;
}
public XMLStreamLocation2 getCurrentLocation()
{
return XMLStreamLocation2.NOT_AVAILABLE;
}
public final XMLStreamLocation2 getEndLocation()
throws XMLStreamException
{
return XMLStreamLocation2.NOT_AVAILABLE;
}
/*
////////////////////////////////////////////////////
// Stax2 validation: !!! TODO
////////////////////////////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
// Not implemented by the basic reader:
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
// Not implemented by the basic reader:
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
// Not implemented by the basic reader:
return null;
}
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
// Not implemented by the basic reader
return null;
}
/*
////////////////////////////////////////////
// Internal methods, text gathering
////////////////////////////////////////////
*/
protected void coalesceText(int initialType)
{
_textBuffer.reset();
_textBuffer.append(_currNode.getNodeValue());
Node n;
while ((n = _currNode.getNextSibling()) != null) {
int type = n.getNodeType();
if (type != Node.TEXT_NODE && type != Node.CDATA_SECTION_NODE) {
break;
}
_currNode = n;
_textBuffer.append(_currNode.getNodeValue());
}
_coalescedText = _textBuffer.get();
// Either way, type gets always set to be CHARACTERS
_currEvent = CHARACTERS;
}
/*
////////////////////////////////////////////
// Internal methods, namespace support
////////////////////////////////////////////
*/
private QName _constructQName(String uri, String ln, String prefix)
{
// Stupid QName impls barf on nulls...
return new QName(_internNsURI(uri), _internName(ln), _internName(prefix));
}
/**
* @param attrsToo Whether to include actual attributes too, or
* just namespace declarations
*/
private void _calcNsAndAttrLists(boolean attrsToo)
{
NamedNodeMap attrsIn = _currNode.getAttributes();
// A common case: neither attrs nor ns decls, can use short-cut
int len = attrsIn.getLength();
if (len == 0) {
_attrList = _nsDeclList = Collections.EMPTY_LIST;
return;
}
if (!_cfgNsAware) {
_attrList = new ArrayList(len);
for (int i = 0; i < len; ++i) {
_attrList.add(attrsIn.item(i));
}
_nsDeclList = Collections.EMPTY_LIST;
return;
}
// most should be attributes... and possibly no ns decls:
ArrayList attrsOut = null;
ArrayList nsOut = null;
for (int i = 0; i < len; ++i) {
Node attr = attrsIn.item(i);
String prefix = attr.getPrefix();
// Prefix?
if (prefix == null || prefix.length() == 0) { // nope
// default ns decl?
if (!"xmlns".equals(attr.getLocalName())) { // nope
if (attrsToo) {
if (attrsOut == null) {
attrsOut = new ArrayList(len - i);
}
attrsOut.add(attr);
}
continue;
}
prefix = null;
} else { // explicit ns decl?
if (!"xmlns".equals(prefix)) { // nope
if (attrsToo) {
if (attrsOut == null) {
attrsOut = new ArrayList(len - i);
}
attrsOut.add(attr);
}
continue;
}
prefix = attr.getLocalName();
}
if (nsOut == null) {
nsOut = new ArrayList((len - i) * 2);
}
nsOut.add(_internName(prefix));
nsOut.add(_internNsURI(attr.getNodeValue()));
}
_attrList = (attrsOut == null) ? Collections.EMPTY_LIST : attrsOut;
_nsDeclList = (nsOut == null) ? Collections.EMPTY_LIST : nsOut;
}
private void handleIllegalAttrIndex(int index)
{
Element elem = (Element) _currNode;
NamedNodeMap attrs = elem.getAttributes();
int len = attrs.getLength();
String msg = "Illegal attribute index "+index+"; element <"+elem.getNodeName()+"> has "+((len == 0) ? "no" : String.valueOf(len))+" attributes";
throw new IllegalArgumentException(msg);
}
private void handleIllegalNsIndex(int index)
{
String msg = "Illegal namespace declaration index "+index+" (has "+getNamespaceCount()+" ns declarations)";
throw new IllegalArgumentException(msg);
}
/**
* Due to differences in how namespace-aware and non-namespace modes
* work in DOM, different methods are needed. We may or may not be
* able to detect namespace-awareness mode of the source Nodes
* directly; but at any rate, should contain some logic for handling
* problem cases.
*/
private String _safeGetLocalName(Node n)
{
String ln = n.getLocalName();
if (ln == null) {
ln = n.getNodeName();
}
return ln;
}
/*
///////////////////////////////////////////////
// Overridable error reporting methods
///////////////////////////////////////////////
*/
protected void reportWrongState(int errorType)
{
throw new IllegalStateException(findErrorDesc(errorType, _currEvent));
}
protected void reportParseProblem(int errorType)
throws XMLStreamException
{
throwStreamException(findErrorDesc(errorType, _currEvent));
}
protected void throwStreamException(String msg)
throws XMLStreamException
{
throwStreamException(msg, getErrorLocation());
}
protected Location getErrorLocation()
{
Location loc = getCurrentLocation();
if (loc == null) {
loc = getLocation();
}
return loc;
}
/**
* Method called to wrap or convert given conversion-fail exception
* into a full {@link TypedXMLStreamException},
*
* @param iae Problem as reported by converter
* @param lexicalValue Lexical value (element content, attribute value)
* that could not be converted succesfully.
*/
protected TypedXMLStreamException _constructTypeException(IllegalArgumentException iae, String lexicalValue)
{
String msg = iae.getMessage();
if (msg == null) {
msg = "";
}
Location loc = getStartLocation();
if (loc == null) {
return new TypedXMLStreamException(lexicalValue, msg, iae);
}
return new TypedXMLStreamException(lexicalValue, msg, loc);
}
protected TypedXMLStreamException _constructTypeException(String msg, String lexicalValue)
{
Location loc = getStartLocation();
if (loc == null) {
return new TypedXMLStreamException(lexicalValue, msg);
}
return new TypedXMLStreamException(lexicalValue, msg, loc);
}
/*
///////////////////////////////////////////////
// Other internal methods
///////////////////////////////////////////////
*/
protected ValueDecoderFactory _decoderFactory()
{
if (_decoderFactory == null) {
_decoderFactory = new ValueDecoderFactory();
}
return _decoderFactory;
}
protected StringBase64Decoder _base64Decoder()
{
if (_base64Decoder == null) {
_base64Decoder = new StringBase64Decoder();
}
return _base64Decoder;
}
/**
* Method used to locate error message description to use.
* Calls sub-classes findErrorDesc()
first, and only
* if no message found, uses default messages defined here.
*/
protected String findErrorDesc(int errorType, int currEvent)
{
String evtDesc = Stax2Util.eventTypeDesc(currEvent);
switch (errorType) {
case ERR_STATE_NOT_START_ELEM:
return "Current event "+evtDesc+", needs to be START_ELEMENT";
case ERR_STATE_NOT_ELEM:
return "Current event "+evtDesc+", needs to be START_ELEMENT or END_ELEMENT";
case ERR_STATE_NO_LOCALNAME:
return "Current event ("+evtDesc+") has no local name";
case ERR_STATE_NOT_PI:
return "Current event ("+evtDesc+") needs to be PROCESSING_INSTRUCTION";
case ERR_STATE_NOT_TEXTUAL:
return "Current event ("+evtDesc+") not a textual event";
case ERR_STATE_NOT_TEXTUAL_OR_ELEM:
return "Current event ("+evtDesc+" not START_ELEMENT, END_ELEMENT, CHARACTERS or CDATA";
case ERR_STATE_NOT_TEXTUAL_XXX:
return "Current event "+evtDesc+", needs to be one of CHARACTERS, CDATA, SPACE or COMMENT";
}
// should never happen, but it'd be bad to throw another exception...
return "Internal error (unrecognized error type: "+errorType+")";
}
/**
* Method called to do additional intern()ing for a name, if and as
* necessary
*/
protected String _internName(String name)
{
if (name == null) {
return "";
}
return _cfgInternNames ? name.intern() : name;
}
protected String _internNsURI(String uri)
{
if (uri == null) {
return "";
}
return _cfgInternNsURIs ? uri.intern() : uri;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/dom/DOMWrappingWriter.java 100644 0 0 51475 11520453235 22453 0 ustar 0 0 /* Stax2 API extension for Streaming Api for Xml processing (StAX).
*
* Copyright (c) 2006- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in the file LICENSE which is
* included with the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.dom;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import org.w3c.dom.*;
import org.codehaus.stax2.XMLStreamLocation2;
import org.codehaus.stax2.XMLStreamReader2;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.ri.typed.SimpleValueEncoder;
import org.codehaus.stax2.typed.Base64Variant;
import org.codehaus.stax2.typed.Base64Variants;
import org.codehaus.stax2.validation.*;
/**
* This is an adapter class that partially implements {@link XMLStreamWriter}
* as a facade on top of a DOM document or Node, allowing one
* to basically construct DOM trees via Stax API.
* It is meant to serve as basis for a full implementation.
*javax.xml.transform.dom.DOMResult
. It can however be
* used for both full documents, and single element root fragments,
* depending on what node is passed as the argument.
*>p>
* One more implementation note: much code is identical to one
* used by {@link org.codehaus.stax2.ri.Stax2WriterAdapter}.
* Alas it is hard to reuse it without cut'n pasting.
*
* @author Tatu Saloranta
*
* @since 3.0
*/
public abstract class DOMWrappingWriter
implements XMLStreamWriter2
{
// // Constants to use as defaults for "writeStartDocument"
final static String DEFAULT_OUTPUT_ENCODING = "UTF-8";
final static String DEFAULT_XML_VERSION = "1.0";
/*
////////////////////////////////////////////////////
// Configuration
////////////////////////////////////////////////////
*/
protected final boolean mNsAware;
protected final boolean mNsRepairing;
/**
* This member variable is to keep information about encoding
* that seems to be used for the document (or fragment) to output,
* if known.
*/
protected String mEncoding = null;
/**
* If we are being given info about existing bindings, it'll come
* as a NamespaceContext.
*/
protected NamespaceContext mNsContext;
/*
////////////////////////////////////////////////////
// State
////////////////////////////////////////////////////
*/
/**
* We need a reference to the document hosting nodes to
* be able to create new nodes
*/
protected final Document mDocument;
/*
////////////////////////////////////////////////////
// Helper objects
////////////////////////////////////////////////////
*/
/**
* Encoding of typed values is used the standard encoder
* included in RI.
*/
protected SimpleValueEncoder mValueEncoder;
/*
////////////////////////////////////////////////////
// Life-cycle
////////////////////////////////////////////////////
*/
protected DOMWrappingWriter(Node treeRoot,
boolean nsAware, boolean nsRepairing)
throws XMLStreamException
{
if (treeRoot == null) {
throw new IllegalArgumentException("Can not pass null Node for constructing a DOM-based XMLStreamWriter");
}
mNsAware = nsAware;
mNsRepairing = nsRepairing;
/* Ok; we need a document node; or an element node; or a document
* fragment node.
*/
switch (treeRoot.getNodeType()) {
case Node.DOCUMENT_NODE: // fine
mDocument = (Document) treeRoot;
/* Should try to find encoding, version and stand-alone
* settings... but is there a standard way of doing that?
*/
break;
case Node.ELEMENT_NODE: // can make sub-tree... ok
mDocument = treeRoot.getOwnerDocument();
break;
case Node.DOCUMENT_FRAGMENT_NODE: // as with element...
mDocument = treeRoot.getOwnerDocument();
// Above types are fine
break;
default: // other Nodes not usable
throw new XMLStreamException("Can not create an XMLStreamWriter for a DOM node of type "+treeRoot.getClass());
}
if (mDocument == null) {
throw new XMLStreamException("Can not create an XMLStreamWriter for given node (of type "+treeRoot.getClass()+"): did not have owner document");
}
}
/*
////////////////////////////////////////////////////
// Partial XMLStreamWriter API (Stax 1.0) impl
////////////////////////////////////////////////////
*/
public void close() {
// NOP
}
public void flush() {
// NOP
}
public abstract NamespaceContext getNamespaceContext();
public abstract String getPrefix(String uri);
public abstract Object getProperty(String name);
public abstract void setDefaultNamespace(String uri);
public void setNamespaceContext(NamespaceContext context) {
mNsContext = context;
}
public abstract void setPrefix(String prefix, String uri)
throws XMLStreamException;
public abstract void writeAttribute(String localName, String value)
throws XMLStreamException;
public abstract void writeAttribute(String nsURI, String localName, String value)
throws XMLStreamException;
public abstract void writeAttribute(String prefix, String nsURI, String localName, String value)
throws XMLStreamException;
public void writeCData(String data)
throws XMLStreamException
{
appendLeaf(mDocument.createCDATASection(data));
}
public void writeCharacters(char[] text, int start, int len)
throws XMLStreamException
{
writeCharacters(new String(text, start, len));
}
public void writeCharacters(String text)
throws XMLStreamException
{
appendLeaf(mDocument.createTextNode(text));
}
public void writeComment(String data)
throws XMLStreamException
{
appendLeaf(mDocument.createCDATASection(data));
}
public abstract void writeDefaultNamespace(String nsURI)
throws XMLStreamException;
public void writeDTD(String dtd)
throws XMLStreamException
{
/* Would need to parse contents, not easy to do via DOM
* in any case.
*/
reportUnsupported("writeDTD()");
}
public abstract void writeEmptyElement(String localName)
throws XMLStreamException;
public abstract void writeEmptyElement(String nsURI, String localName)
throws XMLStreamException;
public abstract void writeEmptyElement(String prefix, String localName, String nsURI)
throws XMLStreamException;
public abstract void writeEndDocument() throws XMLStreamException;
public void writeEntityRef(String name) throws XMLStreamException
{
appendLeaf(mDocument.createEntityReference(name));
}
public void writeProcessingInstruction(String target)
throws XMLStreamException
{
writeProcessingInstruction(target, null);
}
public void writeProcessingInstruction(String target, String data)
throws XMLStreamException
{
appendLeaf(mDocument.createProcessingInstruction(target, data));
}
public void writeStartDocument()
throws XMLStreamException
{
/* Note: while these defaults are not very intuitive, they
* are what Stax 1.0 specification clearly mandates:
*/
writeStartDocument(DEFAULT_OUTPUT_ENCODING, DEFAULT_XML_VERSION);
}
public void writeStartDocument(String version)
throws XMLStreamException
{
writeStartDocument(null, version);
}
public void writeStartDocument(String encoding, String version)
throws XMLStreamException
{
// Is there anything here we can or should do? No?
mEncoding = encoding;
}
/*
////////////////////////////////////////////////////
// XMLStreamWriter2 API (Stax2 v3.0):
// additional accessors
////////////////////////////////////////////////////
*/
public XMLStreamLocation2 getLocation() {
// !!! TBI
return null;
}
public String getEncoding() {
return mEncoding;
}
public abstract boolean isPropertySupported(String name);
public abstract boolean setProperty(String name, Object value);
/*
////////////////////////////////////////////////////
// XMLStreamWriter2 API (Stax2 v2.0):
// extended write methods
////////////////////////////////////////////////////
*/
public void writeCData(char[] text, int start, int len)
throws XMLStreamException
{
writeCData(new String(text, start, len));
}
public abstract void writeDTD(String rootName, String systemId, String publicId,
String internalSubset)
throws XMLStreamException;
//public void writeDTD(String rootName, String systemId, String publicId, String internalSubset)
public void writeFullEndElement() throws XMLStreamException
{
// No difference with DOM
writeEndElement();
}
public void writeSpace(char[] text, int start, int len)
throws XMLStreamException
{
writeSpace(new String(text, start, len));
}
public void writeSpace(String text)
throws XMLStreamException
{
/* This won't work all that well, given there's no way to
* prevent quoting/escaping. But let's do what we can, since
* the alternative (throwing an exception) doesn't seem
* especially tempting choice.
*/
writeCharacters(text);
}
public void writeStartDocument(String version, String encoding, boolean standAlone)
throws XMLStreamException
{
writeStartDocument(encoding, version);
}
/*
////////////////////////////////////////////////////
// XMLStreamWriter2 API (Stax2 v2.0): validation
////////////////////////////////////////////////////
*/
public XMLValidator validateAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
// !!! TBI
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidationSchema schema)
throws XMLStreamException
{
// !!! TBI
return null;
}
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException
{
// !!! TBI
return null;
}
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h)
{
// !!! TBI
return null;
}
/*
///////////////////////////////
// Stax2, pass-through methods
///////////////////////////////
*/
public void writeRaw(String text)
throws XMLStreamException
{
reportUnsupported("writeRaw()");
}
public void writeRaw(String text, int start, int offset)
throws XMLStreamException
{
reportUnsupported("writeRaw()");
}
public void writeRaw(char[] text, int offset, int length)
throws XMLStreamException
{
reportUnsupported("writeRaw()");
}
public void copyEventFromReader(XMLStreamReader2 r, boolean preserveEventData)
throws XMLStreamException
{
// !!! TBI
}
/*
///////////////////////////////
// Stax2, output handling
///////////////////////////////
*/
public void closeCompletely()
{
// NOP
}
/*
/////////////////////////////////////////////////
// TypedXMLStreamWriter2 implementation
// (Typed Access API, Stax v3.0)
/////////////////////////////////////////////////
*/
// // // Typed element content write methods
public void writeBoolean(boolean value) throws XMLStreamException
{
writeCharacters(value ? "true" : "false");
}
public void writeInt(int value) throws XMLStreamException
{
writeCharacters(String.valueOf(value));
}
public void writeLong(long value) throws XMLStreamException
{
writeCharacters(String.valueOf(value));
}
public void writeFloat(float value) throws XMLStreamException
{
writeCharacters(String.valueOf(value));
}
public void writeDouble(double value) throws XMLStreamException
{
writeCharacters(String.valueOf(value));
}
public void writeInteger(BigInteger value) throws XMLStreamException
{
writeCharacters(value.toString());
}
public void writeDecimal(BigDecimal value) throws XMLStreamException
{
writeCharacters(value.toString());
}
public void writeQName(QName name) throws XMLStreamException
{
writeCharacters(serializeQNameValue(name));
}
public void writeIntArray(int[] value, int from, int length)
throws XMLStreamException
{
/* true -> start with space, to allow for multiple consecutive
* to be written
*/
writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeLongArray(long[] value, int from, int length)
throws XMLStreamException
{
// true -> start with space, for multiple segments
writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeFloatArray(float[] value, int from, int length)
throws XMLStreamException
{
// true -> start with space, for multiple segments
writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeDoubleArray(double[] value, int from, int length)
throws XMLStreamException
{
// true -> start with space, for multiple segments
writeCharacters(getValueEncoder().encodeAsString(value, from, length));
}
public void writeBinary(byte[] value, int from, int length)
throws XMLStreamException
{
writeBinary(Base64Variants.getDefaultVariant(), value, from, length);
}
public void writeBinary(Base64Variant v, byte[] value, int from, int length)
throws XMLStreamException
{
writeCharacters(getValueEncoder().encodeAsString(v, value, from, length));
}
// // // Typed attribute value write methods
public void writeBooleanAttribute(String prefix, String nsURI, String localName, boolean value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, value ? "true" : "false");
}
public void writeIntAttribute(String prefix, String nsURI, String localName, int value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeLongAttribute(String prefix, String nsURI, String localName, long value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeFloatAttribute(String prefix, String nsURI, String localName, float value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeDoubleAttribute(String prefix, String nsURI, String localName, double value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, String.valueOf(value));
}
public void writeIntegerAttribute(String prefix, String nsURI, String localName, BigInteger value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, value.toString());
}
public void writeDecimalAttribute(String prefix, String nsURI, String localName, BigDecimal value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, value.toString());
}
public void writeQNameAttribute(String prefix, String nsURI, String localName, QName name)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName, serializeQNameValue(name));
}
public void writeIntArrayAttribute(String prefix, String nsURI, String localName, int[] value)
throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeLongArrayAttribute(String prefix, String nsURI, String localName, long[] value) throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeFloatArrayAttribute(String prefix, String nsURI, String localName, float[] value) throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeDoubleArrayAttribute(String prefix, String nsURI, String localName, double[] value) throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(value, 0, value.length));
}
public void writeBinaryAttribute(String prefix, String nsURI, String localName, byte[] value) throws XMLStreamException
{
writeBinaryAttribute(Base64Variants.getDefaultVariant(), prefix, nsURI, localName, value);
}
public void writeBinaryAttribute(Base64Variant v, String prefix, String nsURI, String localName, byte[] value) throws XMLStreamException
{
writeAttribute(prefix, nsURI, localName,
getValueEncoder().encodeAsString(v, value, 0, value.length));
}
/*
////////////////////////////////////////////////////
// Abstract methods for sub-classes to implement
////////////////////////////////////////////////////
*/
protected abstract void appendLeaf(Node n)
throws IllegalStateException;
/*
////////////////////////////////////////////////////
// Shared package methods
////////////////////////////////////////////////////
*/
/**
* Method called to serialize given qualified name into valid
* String serialization, taking into account existing namespace
* bindings.
*/
protected String serializeQNameValue(QName name)
throws XMLStreamException
{
String prefix;
// Ok as is? In repairing mode need to ensure it's properly bound
if (mNsRepairing) {
String uri = name.getNamespaceURI();
// First: let's see if a valid binding already exists:
NamespaceContext ctxt = getNamespaceContext();
prefix = (ctxt == null) ? null : ctxt.getPrefix(uri);
if (prefix == null) {
// nope: need to (try to) bind
String origPrefix = name.getPrefix();
if (origPrefix == null || origPrefix.length() == 0) {
prefix = "";
/* note: could cause a namespace conflict... but
* there is nothing we can do with just stax1 stream
* writer
*/
writeDefaultNamespace(uri);
} else {
prefix = origPrefix;
writeNamespace(prefix, uri);
}
}
} else { // in non-repairing, good as is
prefix = name.getPrefix();
}
String local = name.getLocalPart();
if (prefix == null || prefix.length() == 0) {
return local;
}
// Not efficient... but should be ok
return prefix + ":" + local;
}
protected SimpleValueEncoder getValueEncoder()
{
if (mValueEncoder == null) {
mValueEncoder = new SimpleValueEncoder();
}
return mValueEncoder;
}
/*
////////////////////////////////////////////////////
// Package methods, basic output problem reporting
////////////////////////////////////////////////////
*/
protected static void throwOutputError(String msg)
throws XMLStreamException
{
throw new XMLStreamException(msg);
}
protected static void throwOutputError(String format, Object arg)
throws XMLStreamException
{
String msg = MessageFormat.format(format, new Object[] { arg });
throwOutputError(msg);
}
protected void reportUnsupported(String operName)
{
throw new UnsupportedOperationException(operName+" can not be used with DOM-backed writer");
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/AttributeEventImpl.java 100644 0 0 12015 11520453235 22720 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.Attribute;
import org.codehaus.stax2.XMLStreamWriter2;
public class AttributeEventImpl
extends BaseEventImpl
implements Attribute
{
final QName mName;
final String mValue;
final boolean mWasSpecified;
public AttributeEventImpl(Location loc, String localName, String uri, String prefix,
String value, boolean wasSpecified)
{
super(loc);
mValue = value;
if (prefix == null) {
if (uri == null) {
mName = new QName(localName);
} else {
mName = new QName(uri, localName);
}
} else {
if (uri == null) {
uri = ""; // only because QName will barf otherwise...
}
mName = new QName(uri, localName, prefix);
}
mWasSpecified = wasSpecified;
}
public AttributeEventImpl(Location loc, QName name, String value, boolean wasSpecified)
{
super(loc);
mName = name;
mValue = value;
mWasSpecified = wasSpecified;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return ATTRIBUTE;
}
public boolean isAttribute() { return true; }
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
/* Specs don't really specify exactly what to output... but
* let's do a reasonable guess:
*/
String prefix = mName.getPrefix();
try {
if (prefix != null && prefix.length() > 0) {
w.write(prefix);
w.write(':');
}
w.write(mName.getLocalPart());
w.write('=');
w.write('"');
writeEscapedAttrValue(w, mValue);
w.write('"');
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
QName n = mName;
w.writeAttribute(n.getPrefix(), n.getLocalPart(),
n.getNamespaceURI(), mValue);
}
/*
///////////////////////////////////////////
// Attribute implementation
///////////////////////////////////////////
*/
public String getDTDType() {
/* !!! TBI: 07-Sep-2004, TSa: Need to figure out an efficient way
* to pass this info...
*/
return "CDATA";
}
public QName getName()
{
return mName;
}
public String getValue()
{
return mValue;
}
public boolean isSpecified()
{
return mWasSpecified;
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof Attribute)) return false;
Attribute other = (Attribute) o;
if (mName.equals(other.getName())
&& mValue.equals(other.getValue())) {
/* But now; do we care about compatibility of
* DTD/Schema datatype and whether it's created
* from attribute defaulting? Let's start by being
* conservative and require those to match
*/
if (isSpecified() == other.isSpecified()) {
return stringsWithNullsEqual(getDTDType(), other.getDTDType());
}
}
return false;
}
public int hashCode()
{
/* Hmmh. Definitely need hashCode of name; but how about
* value? That's potentially more expensive. But, if
* using code wants to avoid value, it should key off name
* anyway.
*/
return mName.hashCode() ^ mValue.hashCode();
}
/*
///////////////////////////////////////////
// Internal methods
///////////////////////////////////////////
*/
protected static void writeEscapedAttrValue(Writer w, String value)
throws IOException
{
int i = 0;
int len = value.length();
do {
int start = i;
char c = '\u0000';
for (; i < len; ++i) {
c = value.charAt(i);
if (c == '<' || c == '&' || c == '"') {
break;
}
}
int outLen = i - start;
if (outLen > 0) {
w.write(value, start, outLen);
}
if (i < len) {
if (c == '<') {
w.write("<");
} else if (c == '&') {
w.write("&");
} else if (c == '"') {
w.write(""");
}
}
} while (++i < len);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/BaseEventImpl.java 100644 0 0 10221 11520453235 21624 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import org.codehaus.stax2.*;
import org.codehaus.stax2.evt.XMLEvent2;
/**
* This abstract base class implements common functionality for
* Stax2 reference implementation's event API part.
*
* @author Tatu Saloranta
*/
public abstract class BaseEventImpl
implements XMLEvent2
{
/**
* Location where token started; exact definition may depends
* on event type.
*/
protected final Location mLocation;
protected BaseEventImpl(Location loc)
{
mLocation = loc;
}
/*
//////////////////////////////////////////////
// Skeleton XMLEvent API
//////////////////////////////////////////////
*/
public Characters asCharacters() {
return (Characters) this;
}
public EndElement asEndElement() {
return (EndElement) this;
}
public StartElement asStartElement() {
return (StartElement) this;
}
public abstract int getEventType();
public Location getLocation() {
return mLocation;
}
public QName getSchemaType() {
return null;
}
public boolean isAttribute()
{
return false;
}
public boolean isCharacters()
{
return false;
}
public boolean isEndDocument()
{
return false;
}
public boolean isEndElement()
{
return false;
}
public boolean isEntityReference()
{
return false;
}
public boolean isNamespace()
{
return false;
}
public boolean isProcessingInstruction()
{
return false;
}
public boolean isStartDocument()
{
return false;
}
public boolean isStartElement()
{
return false;
}
public abstract void writeAsEncodedUnicode(Writer w)
throws XMLStreamException;
/*
//////////////////////////////////////////////
// XMLEvent2 (StAX2)
//////////////////////////////////////////////
*/
public abstract void writeUsing(XMLStreamWriter2 w) throws XMLStreamException;
/*
///////////////////////////////////////////
// Overridden standard methods
///////////////////////////////////////////
*/
/**
* Declared abstract to force redefinition by sub-classes
*/
public abstract boolean equals(Object o);
/**
* Declared abstract to force redefinition by sub-classes
*/
public abstract int hashCode();
public String toString() {
return "[Stax Event #"+getEventType()+"]";
}
/*
//////////////////////////////////////////////
// Helper methods
//////////////////////////////////////////////
*/
protected void throwFromIOE(IOException ioe)
throws XMLStreamException
{
throw new XMLStreamException(ioe.getMessage(), ioe);
}
/**
* Comparison method that will consider null Strings to be
* equivalent to empty Strings for comparison purposes; and
* compare equality with that caveat.
*/
protected static boolean stringsWithNullsEqual(String s1, String s2)
{
if (s1 == null || s1.length() == 0) {
return (s2 == null) || (s2.length() == 0);
}
return (s2 != null) && s1.equals(s2);
}
protected static boolean iteratedEquals(Iterator it1, Iterator it2)
{
if (it1 == null || it2 == null) { // if one is null, both have to be
return (it1 == it2);
}
// Otherwise, loop-de-loop...
while (it1.hasNext()) {
if (!it2.hasNext()) {
return false;
}
Object o1 = it1.next();
Object o2 = it2.next();
if (!o1.equals(o2)) {
return false;
}
}
return true;
}
protected static int addHash(Iterator it, int baseHash)
{
int hash = baseHash;
if (it != null) {
while (it.hasNext()) {
hash ^= it.next().hashCode();
}
}
return hash;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/CharactersEventImpl.java 100644 0 0 13310 11520453235 23033 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.Characters;
import org.codehaus.stax2.XMLStreamWriter2;
public class CharactersEventImpl
extends BaseEventImpl
implements Characters
{
final String mContent;
final boolean mIsCData;
final boolean mIgnorableWS;
boolean mWhitespaceChecked = false;
boolean mIsWhitespace = false;
/**
* Constructor for regular unspecified (but non-CDATA) characters
* event type, which may or may not be all whitespace, but is not
* specified as ignorable white space.
*/
public CharactersEventImpl(Location loc, String content, boolean cdata)
{
super(loc);
mContent = content;
mIsCData = cdata;
mIgnorableWS = false;
}
/**
* Constructor for creating white space characters...
*/
private CharactersEventImpl(Location loc, String content,
boolean cdata, boolean allWS, boolean ignorableWS)
{
super(loc);
mContent = content;
mIsCData = cdata;
mIsWhitespace = allWS;
if (allWS) {
mWhitespaceChecked = true;
mIgnorableWS = ignorableWS;
} else {
mWhitespaceChecked = false;
mIgnorableWS = false;
}
}
public final static CharactersEventImpl createIgnorableWS(Location loc, String content) {
return new CharactersEventImpl(loc, content, false, true, true);
}
public final static CharactersEventImpl createNonIgnorableWS(Location loc, String content) {
return new CharactersEventImpl(loc, content, false, true, false);
}
/*
/////////////////////////////////////////////////////
// Implementation of abstract base methods, overrides
/////////////////////////////////////////////////////
*/
public Characters asCharacters() { // overriden to save a cast
return this;
}
public int getEventType() {
return mIsCData ? CDATA : CHARACTERS;
}
public boolean isCharacters() { return true; }
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
if (mIsCData) {
w.write("");
} else {
writeEscapedXMLText(w, mContent);
}
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
if (mIsCData) {
w.writeCData(mContent);
} else {
w.writeCharacters(mContent);
}
}
/*
///////////////////////////////////////////
// Characters implementation
///////////////////////////////////////////
*/
public String getData() {
return mContent;
}
public boolean isCData() {
return mIsCData;
}
public boolean isIgnorableWhiteSpace() {
return mIgnorableWS;
}
public boolean isWhiteSpace() {
// Better only do white space check, if it's done already...
if (!mWhitespaceChecked) {
mWhitespaceChecked = true;
String str = mContent;
int i = 0;
int len = str.length();
for (; i < len; ++i) {
if (str.charAt(i) > 0x0020) {
break;
}
}
mIsWhitespace = (i == len);
}
return mIsWhitespace;
}
/*
///////////////////////////////////////////
// Additional public, but non-Stax-API methods
///////////////////////////////////////////
*/
public void setWhitespaceStatus(boolean status)
{
mWhitespaceChecked = true;
mIsWhitespace = status;
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof Characters)) return false;
Characters other = (Characters) o;
// Obviously textual content has to match
if (mContent.equals(other.getData())) {
// But how about type (CDATA vs CHARACTERS)?
// For now, let's require type match too
return isCData() == other.isCData();
}
return false;
}
public int hashCode()
{
return mContent.hashCode();
}
/*
///////////////////////////////////////////
// Internal methods
///////////////////////////////////////////
*/
protected static void writeEscapedXMLText(Writer w, String text)
throws IOException
{
final int len = text.length();
int i = 0;
while (i < len) {
int start = i;
char c = '\u0000';
for (; i < len; ) {
c = text.charAt(i);
if (c == '<' || c == '&') {
break;
}
if (c == '>' && i >= 2 && text.charAt(i-1) == ']'
&& text.charAt(i-2) == ']') {
break;
}
++i;
}
int outLen = i - start;
if (outLen > 0) {
w.write(text, start, outLen);
}
if (i < len) {
if (c == '<') {
w.write("<");
} else if (c == '&') {
w.write("&");
} else if (c == '>') {
w.write(">");
}
}
++i;
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/CommentEventImpl.java 100644 0 0 3061 11520453235 22340 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.Comment;
import org.codehaus.stax2.XMLStreamWriter2;
public class CommentEventImpl
extends BaseEventImpl
implements Comment
{
final String mContent;
public CommentEventImpl(Location loc, String content)
{
super(loc);
mContent = content;
}
public String getText()
{
return mContent;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return COMMENT;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write("");
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
w.writeComment(mContent);
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof Comment)) return false;
Comment other = (Comment) o;
return mContent.equals(other.getText());
}
public int hashCode()
{
return mContent.hashCode();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/DTDEventImpl.java 100644 0 0 15316 11520453235 21377 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.*;
import javax.xml.stream.*;
import javax.xml.stream.events.DTD;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.evt.DTD2;
/**
* Vanilla implementation of a DTD event. Note that as is, it is not
* really complete, since there is no way to access declared notations
* and entities, because Stax 1.0 has no method for dispatching calls.
* As such, it is expected that actual implementations would usually
* extend this class, instead of using it as is.
*/
public class DTDEventImpl
extends BaseEventImpl
implements DTD2
{
final String mRootName;
final String mSystemId;
final String mPublicId;
final String mInternalSubset;
final Object mDTD;
/*
/////////////////////////////////////////////////////
// Lazily constructed objects
/////////////////////////////////////////////////////
*/
/**
* Full textual presentation of the DOCTYPE event; usually only
* constructed when needed, but sometimes (when using 'broken'
* older StAX interfaces), may be the only piece that's actually
* passed.
*/
String mFullText = null;
/*
/////////////////////////////////////////////////////
// Constuctors
/////////////////////////////////////////////////////
*/
public DTDEventImpl(Location loc, String rootName,
String sysId, String pubId, String intSubset,
Object dtd)
{
super(loc);
mRootName = rootName;
mSystemId = sysId;
mPublicId = pubId;
mInternalSubset = intSubset;
mFullText = null;
mDTD = dtd;
}
/**
* Constructor used when only partial information is available.
*/
public DTDEventImpl(Location loc, String rootName, String intSubset)
{
this(loc, rootName, null, null, intSubset, null);
}
public DTDEventImpl(Location loc, String fullText)
{
this(loc, null, null, null, null, null);
mFullText = fullText;
}
/*
/////////////////////////////////////////////////////
// Accessors
/////////////////////////////////////////////////////
*/
public String getDocumentTypeDeclaration()
{
try {
return doGetDocumentTypeDeclaration();
} catch (XMLStreamException sex) { // should never happen
throw new RuntimeException("Internal error: "+sex);
}
}
public List getEntities()
{
// !!! TODO: create stax2 abstraction to allow accessing this
return null;
}
public List getNotations()
{
// !!! TODO: create stax2 abstraction to allow accessing this
return null;
}
public Object getProcessedDTD()
{
return mDTD;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return DTD;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
// If we get 'raw' (unparsed) DOCTYPE contents, this is easy...
if (mFullText != null) {
w.write(mFullText);
return;
}
w.write("");
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
if (mRootName != null) {
w.writeDTD(mRootName, mSystemId, mPublicId, mInternalSubset);
return;
}
// Nah, just need to do a "dumb" write...
w.writeDTD(doGetDocumentTypeDeclaration());
}
/*
///////////////////////////////////////////
// Extended interface (DTD2)
///////////////////////////////////////////
*/
public String getRootName() {
return mRootName;
}
public String getSystemId() {
return mSystemId;
}
public String getPublicId() {
return mPublicId;
}
public String getInternalSubset() {
return mInternalSubset;
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof DTD)) return false;
DTD other = (DTD) o;
/* Hmmh. Comparison for this event get very
* tricky, very fast, if one tries to do it correctly
* (partly due to Stax2 incompleteness, but not just
* because of that)... let's actually try to minimize
* work here
*/
return stringsWithNullsEqual(getDocumentTypeDeclaration(),
other.getDocumentTypeDeclaration());
}
public int hashCode()
{
int hash = 0;
if (mRootName != null) hash ^= mRootName.hashCode();
if (mSystemId != null) hash ^= mSystemId.hashCode();
if (mPublicId != null) hash ^= mPublicId.hashCode();
if (mInternalSubset != null) hash ^= mInternalSubset.hashCode();
if (mDTD != null) hash ^= mDTD.hashCode();
if (hash == 0 && mFullText != null) {
hash ^= mFullText.hashCode();
}
return hash;
}
/*
///////////////////////////////////////////
// Internal methods
///////////////////////////////////////////
*/
protected String doGetDocumentTypeDeclaration()
throws XMLStreamException
{
if (mFullText == null) {
int len = 60;
if (mInternalSubset != null) {
len += mInternalSubset.length() + 4;
}
StringWriter sw = new StringWriter(len);
writeAsEncodedUnicode(sw);
mFullText = sw.toString();
}
return mFullText;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/EndDocumentEventImpl.java 100644 0 0 2343 11520453235 23145 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.EndDocument;
import org.codehaus.stax2.XMLStreamWriter2;
public class EndDocumentEventImpl
extends BaseEventImpl
implements EndDocument
{
public EndDocumentEventImpl(Location loc)
{
super(loc);
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return END_DOCUMENT;
}
public boolean isEndDocument() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
// Nothing to output
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
w.writeEndDocument();
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
return (o instanceof EndDocument);
}
public int hashCode()
{
return END_DOCUMENT;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/EndElementEventImpl.java 100644 0 0 10174 11520453235 23001 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.ri.EmptyIterator;
import org.codehaus.stax2.ri.evt.BaseEventImpl;
public class EndElementEventImpl
extends BaseEventImpl
implements EndElement
{
final QName mName;
final ArrayList mNamespaces;
/**
* Constructor usually used when reading events from a stream reader.
*/
public EndElementEventImpl(Location loc, XMLStreamReader r)
{
super(loc);
mName = r.getName();
// Let's figure out if there are any namespace declarations...
int nsCount = r.getNamespaceCount();
if (nsCount == 0) {
mNamespaces = null;
} else {
ArrayList l = new ArrayList(nsCount);
for (int i = 0; i < nsCount; ++i) {
l.add(NamespaceEventImpl.constructNamespace
(loc, r.getNamespacePrefix(i), r.getNamespaceURI(i)));
}
mNamespaces = l;
}
}
/**
* Constructor used by the event factory.
*/
public EndElementEventImpl(Location loc, QName name, Iterator namespaces)
{
super(loc);
mName = name;
if (namespaces == null || !namespaces.hasNext()) {
mNamespaces = null;
} else {
ArrayList l = new ArrayList();
while (namespaces.hasNext()) {
/* Let's do typecast here, to catch any cast errors early;
* not strictly required, but helps in preventing later
* problems
*/
l.add((Namespace) namespaces.next());
}
mNamespaces = l;
}
}
/*
/////////////////////////////////////////////
// Public API
/////////////////////////////////////////////
*/
public QName getName() {
return mName;
}
public Iterator getNamespaces()
{
return (mNamespaces == null) ? EmptyIterator.getInstance()
: mNamespaces.iterator();
}
/*
/////////////////////////////////////////////////////
// Implementation of abstract base methods, overrides
/////////////////////////////////////////////////////
*/
public EndElement asEndElement() { // overriden to save a cast
return this;
}
public int getEventType() {
return END_ELEMENT;
}
public boolean isEndElement() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write("");
String prefix = mName.getPrefix();
if (prefix != null && prefix.length() > 0) {
w.write(prefix);
w.write(':');
}
w.write(mName.getLocalPart());
w.write('>');
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
w.writeEndElement();
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof EndElement)) return false;
EndElement other = (EndElement) o;
// First of all, names must match obviously
if (getName().equals(other.getName())) {
/* But then, what about namespaces etc? For now,
* let's actually not consider namespaces: chances
* are corresponding START_ELEMENT must have matched
* well enough.
*/
return true;
}
return false;
}
public int hashCode()
{
return getName().hashCode();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/EntityDeclarationEventImpl.java 100644 0 0 6122 11520453235 24361 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.EntityDeclaration;
import org.codehaus.stax2.XMLStreamWriter2;
/**
* Simple base implementation that can be used either as a placeholder,
* or a base for 'real' entity declaration implementations.
*/
public class EntityDeclarationEventImpl
extends BaseEventImpl
implements EntityDeclaration
{
protected final String mName;
public EntityDeclarationEventImpl(Location loc, String name)
{
super(loc);
mName = name;
}
/*
///////////////////////////////////////////
// EntityDeclaration
///////////////////////////////////////////
*/
public String getBaseURI()
{
return "";
}
public String getName()
{
return mName;
}
public String getNotationName()
{
return null;
}
public String getPublicId()
{
return null;
}
public String getReplacementText()
{
return null;
}
public String getSystemId()
{
return null;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return ENTITY_DECLARATION;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write("");
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
// Really shouldn't be output. But if we must...
StringWriter strw = new StringWriter();
writeAsEncodedUnicode(strw);
w.writeRaw(strw.toString());
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof EntityDeclaration)) return false;
EntityDeclaration other = (EntityDeclaration) o;
return stringsWithNullsEqual(getName(), other.getName())
&& stringsWithNullsEqual(getBaseURI(), other.getBaseURI())
&& stringsWithNullsEqual(getNotationName(), other.getNotationName())
&& stringsWithNullsEqual(getPublicId(), other.getPublicId())
&& stringsWithNullsEqual(getReplacementText(), other.getReplacementText())
&& stringsWithNullsEqual(getSystemId(), other.getSystemId())
;
}
public int hashCode()
{
// Since we don't have much data, this is easy...
return mName.hashCode();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/EntityReferenceEventImpl.java 100644 0 0 4041 11520453235 24030 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.EntityDeclaration;
import org.codehaus.stax2.XMLStreamWriter2;
public class EntityReferenceEventImpl
extends BaseEventImpl
implements EntityReference
{
protected final EntityDeclaration mDecl;
public EntityReferenceEventImpl(Location loc, EntityDeclaration decl)
{
super(loc);
mDecl = decl;
}
public EntityReferenceEventImpl(Location loc, String name)
{
super(loc);
// note: location will be incorrect...
mDecl = new EntityDeclarationEventImpl(loc, name);
}
public EntityDeclaration getDeclaration()
{
return mDecl;
}
public String getName()
{
return mDecl.getName();
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return ENTITY_REFERENCE;
}
public boolean isEntityReference() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write('&');
w.write(getName());
w.write(';');
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
w.writeEntityRef(getName());
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof EntityReference)) return false;
EntityReference other = (EntityReference) o;
return getName().equals(other.getName());
}
public int hashCode()
{
return getName().hashCode();
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/MergedNsContext.java 100644 0 0 12703 11520453235 22206 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.util.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.events.Namespace;
/**
* Helper class used to combine an enclosing namespace context with
* a list of namespace declarations contained, to result in a single
* namespace context object.
*/
public class MergedNsContext
implements NamespaceContext
{
final NamespaceContext mParentCtxt;
/**
* List of {@link Namespace} instances.
*/
final List mNamespaces;
protected MergedNsContext(NamespaceContext parentCtxt, List localNs)
{
mParentCtxt = parentCtxt;
mNamespaces = (localNs == null) ? Collections.EMPTY_LIST : localNs;
}
public static MergedNsContext construct(NamespaceContext parentCtxt,
List localNs)
{
return new MergedNsContext(parentCtxt, localNs);
}
/*
/////////////////////////////////////////////
// NamespaceContext API
/////////////////////////////////////////////
*/
public String getNamespaceURI(String prefix)
{
if (prefix == null) {
throw new IllegalArgumentException("Illegal to pass null prefix");
}
for (int i = 0, len = mNamespaces.size(); i < len; ++i) {
Namespace ns = (Namespace) mNamespaces.get(i);
if (prefix.equals(ns.getPrefix())) {
return ns.getNamespaceURI();
}
}
// Not found; how about from parent?
if (mParentCtxt != null) {
String uri = mParentCtxt.getNamespaceURI(prefix);
if (uri != null) {
return uri;
}
}
if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {
return XMLConstants.XML_NS_URI;
}
if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
return null;
}
public String getPrefix(String nsURI)
{
if (nsURI == null || nsURI.length() == 0) {
throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
}
/* Ok, first: if we can find it from within current namespaces,
* we are golden:
*/
for (int i = 0, len = mNamespaces.size(); i < len; ++i) {
Namespace ns = (Namespace) mNamespaces.get(i);
if (nsURI.equals(ns.getNamespaceURI())) {
return ns.getPrefix();
}
}
// If not, let's first try the easy way:
if (mParentCtxt != null) {
String prefix = mParentCtxt.getPrefix(nsURI);
if (prefix != null) {
// Must check for masking
String uri2 = getNamespaceURI(prefix);
if (uri2.equals(nsURI)) {
// No masking, we are good:
return prefix;
}
}
// Otherwise, must check other candidates
Iterator it = mParentCtxt.getPrefixes(nsURI);
while (it.hasNext()) {
String p2 = (String) it.next();
if (!p2.equals(prefix)) { // no point re-checking first prefix
// But is it masked?
String uri2 = getNamespaceURI(p2);
if (uri2.equals(nsURI)) {
// No masking, we are good:
return p2;
}
}
}
}
// Ok, but how about pre-defined ones (for xml, xmlns)?
if (nsURI.equals(XMLConstants.XML_NS_URI)) {
return XMLConstants.XML_NS_PREFIX;
}
if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
return XMLConstants.XMLNS_ATTRIBUTE;
}
// Nope, none found:
return null;
}
public Iterator getPrefixes(String nsURI)
{
if (nsURI == null || nsURI.length() == 0) {
throw new IllegalArgumentException("Illegal to pass null/empty prefix as argument.");
}
// Any local bindings?
ArrayList l = null;
for (int i = 0, len = mNamespaces.size(); i < len; ++i) {
Namespace ns = (Namespace) mNamespaces.get(i);
if (nsURI.equals(ns.getNamespaceURI())) {
l = addToList(l, ns.getPrefix());
}
}
// How about parent?
if (mParentCtxt != null) {
Iterator it = mParentCtxt.getPrefixes(nsURI);
while (it.hasNext()) {
String p2 = (String) it.next();
// But is it masked?
String uri2 = getNamespaceURI(p2);
if (uri2.equals(nsURI)) {
// No masking, we are good:
l = addToList(l, p2);
}
}
}
// Ok, but how about pre-defined ones (for xml, xmlns)?
if (nsURI.equals(XMLConstants.XML_NS_URI)) {
l = addToList(l, XMLConstants.XML_NS_PREFIX);
}
if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
l = addToList(l, XMLConstants.XMLNS_ATTRIBUTE);
}
return null;
}
/*
/////////////////////////////////////////////
// Internal methods
/////////////////////////////////////////////
*/
protected ArrayList addToList(ArrayList l, String value)
{
if (l == null) {
l = new ArrayList();
}
l.add(value);
return l;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/NamespaceEventImpl.java 100644 0 0 5034 11520453235 22634 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import javax.xml.XMLConstants;
import javax.xml.stream.*;
import javax.xml.stream.events.Namespace;
/**
* Implementation of {@link Namespace}. Only returned via accessors in
* actual "first class" event objects (start element, end element); never
* directly via event reader.
*/
public class NamespaceEventImpl
extends AttributeEventImpl
implements Namespace
{
final String mPrefix;
final String mURI;
/**
* Constructor for default namespace declaration. Such declarations don't
* have namespace prefix/URI, although semantically it would belong
* to XML namespace URI...
*/
protected NamespaceEventImpl(Location loc, String nsURI)
{
super(loc, XMLConstants.XMLNS_ATTRIBUTE, XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
null,
nsURI, true);
mPrefix = "";
mURI = nsURI;
}
/**
* Constructor for non-default namespace declaration. Such declarations
* belong to "XML namespace" namespace.
*/
protected NamespaceEventImpl(Location loc, String nsPrefix, String nsURI)
{
super(loc, nsPrefix, XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
XMLConstants.XMLNS_ATTRIBUTE,
nsURI, true);
mPrefix = nsPrefix;
mURI = nsURI;
}
public static NamespaceEventImpl constructDefaultNamespace(Location loc, String nsURI)
{
return new NamespaceEventImpl(loc, nsURI);
}
public static NamespaceEventImpl constructNamespace(Location loc, String nsPrefix, String nsURI)
{
if (nsPrefix == null || nsPrefix.length() == 0) { // default NS:
return new NamespaceEventImpl(loc, nsURI);
}
return new NamespaceEventImpl(loc, nsPrefix, nsURI);
}
public String getNamespaceURI() {
return mURI;
}
public String getPrefix() {
return mPrefix;
}
public boolean isDefaultNamespaceDeclaration() {
return (mPrefix.length() == 0);
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return NAMESPACE;
}
public boolean isNamespace() {
return true;
}
// Attribute's implementation for these should be ok:
//public void writeAsEncodedUnicode(Writer w) throws XMLStreamException
//public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
//public boolean equals(Object o)
//public int hashCode()
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/NotationDeclarationEventImpl.java 100644 0 0 6765 11520453235 24715 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.evt.NotationDeclaration2;
public class NotationDeclarationEventImpl
extends BaseEventImpl
implements NotationDeclaration2
{
/**
* Name/id of the notation, used to reference declaration.
*/
final String mName;
final String mPublicId;
final String mSystemId;
public NotationDeclarationEventImpl(Location loc,
String name, String pubId, String sysId)
{
super(loc);
mName = name;
mPublicId = pubId;
mSystemId = sysId;
}
public String getName() {
return mName;
}
public String getPublicId() {
return mPublicId;
}
public String getSystemId() {
return mSystemId;
}
/**
* Empty base implementation: sub-classes should implement
*/
public String getBaseURI()
{
return "";
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return NOTATION_DECLARATION;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write("');
} catch (IOException ie) {
throwFromIOE(ie);
}
}
/**
* This method does not make much sense for this event type -- the reason
* being that the notation declarations can only be written as part of
* a DTD (internal or external subset), not separately. Can basically
* choose to either skip silently (output nothing), or throw an
* exception.
*/
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
/* Fail silently, or throw an exception? Let's do latter; at least
* then we'll get useful (?) bug reports!
*/
throw new XMLStreamException("Can not write notation declarations using an XMLStreamWriter");
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof NotationDeclaration2)) return false;
NotationDeclaration2 other = (NotationDeclaration2) o;
// should we consider Base URI here?
return stringsWithNullsEqual(getName(), other.getName())
&& stringsWithNullsEqual(getPublicId(), other.getPublicId())
&& stringsWithNullsEqual(getSystemId(), other.getSystemId())
&& stringsWithNullsEqual(getBaseURI(), other.getBaseURI())
;
}
public int hashCode()
{
int hash = 0;
if (mName != null) hash ^= mName.hashCode();
if (mPublicId != null) hash ^= mPublicId.hashCode();
if (mSystemId != null) hash ^= mSystemId.hashCode();
return hash;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/ProcInstrEventImpl.java 100644 0 0 4324 11520453235 22664 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.ProcessingInstruction;
import org.codehaus.stax2.*;
public class ProcInstrEventImpl
extends BaseEventImpl
implements ProcessingInstruction
{
final String mTarget;
final String mData;
public ProcInstrEventImpl(Location loc, String target, String data)
{
super(loc);
mTarget = target;
mData = data;
}
public String getData() {
return mData;
}
public String getTarget() {
return mTarget;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return PROCESSING_INSTRUCTION;
}
public boolean isProcessingInstruction() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write("");
w.write(mTarget);
if (mData != null && mData.length() > 0) {
w.write(mData);
}
w.write("?>");
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
if (mData != null && mData.length() > 0) {
w.writeProcessingInstruction(mTarget, mData);
} else {
w.writeProcessingInstruction(mTarget);
}
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof ProcessingInstruction)) return false;
ProcessingInstruction other = (ProcessingInstruction) o;
return mTarget.equals(other.getTarget())
&& stringsWithNullsEqual(mData, other.getData());
}
public int hashCode()
{
int hash = mTarget.hashCode();
if (mData != null) {
hash ^= mData.hashCode();
}
return hash;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/StartDocumentEventImpl.java 100644 0 0 12121 11520453235 23547 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.*;
import javax.xml.stream.events.StartDocument;
import org.codehaus.stax2.XMLStreamWriter2;
public class StartDocumentEventImpl
extends BaseEventImpl
implements StartDocument
{
private final boolean mStandaloneSet;
private final boolean mIsStandalone;
private final String mVersion;
private final boolean mEncodingSet;
private final String mEncodingScheme;
private final String mSystemId;
public StartDocumentEventImpl(Location loc, XMLStreamReader r)
{
super(loc);
mStandaloneSet = r.standaloneSet();
mIsStandalone = r.isStandalone();
/* 06-Aug-2006, TSa: Specs (class javadoc) actually specify that
* the default should be "1.0", as opposed to stream reader that
* should return null if no declaration exists. So, let's do
* defaulting here if needed
*/
{
String version = r.getVersion();
if (version == null || version.length() == 0) {
version = "1.0";
}
mVersion = version;
}
mEncodingScheme = r.getCharacterEncodingScheme();
mEncodingSet = (mEncodingScheme != null && mEncodingScheme.length() > 0);
mSystemId = (loc != null) ? loc.getSystemId() : "";
}
/**
* Method called by event factory, when constructing start document
* event.
*/
public StartDocumentEventImpl(Location loc)
{
this(loc, (String) null);
}
public StartDocumentEventImpl(Location loc, String encoding)
{
this(loc, encoding, null);
}
public StartDocumentEventImpl(Location loc, String encoding, String version)
{
this(loc, encoding, version, false, false);
}
public StartDocumentEventImpl(Location loc, String encoding, String version,
boolean standaloneSet, boolean isStandalone)
{
super(loc);
mEncodingScheme = encoding;
mEncodingSet = (encoding != null && encoding.length() > 0);
mVersion = version;
mStandaloneSet = standaloneSet;
mIsStandalone = isStandalone;
mSystemId = "";
}
public boolean encodingSet() {
return mEncodingSet;
}
public String getCharacterEncodingScheme() {
return mEncodingScheme;
}
public String getSystemId() {
return mSystemId;
}
public String getVersion() {
return mVersion;
}
public boolean isStandalone() {
return mIsStandalone;
}
public boolean standaloneSet() {
return mStandaloneSet;
}
/*
///////////////////////////////////////////
// Implementation of abstract base methods
///////////////////////////////////////////
*/
public int getEventType() {
return START_DOCUMENT;
}
public boolean isStartDocument() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
// Need to output the XML declaration?
try {
w.write("");
} catch (IOException ie) {
throwFromIOE(ie);
}
}
public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException
{
w.writeStartDocument();
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof StartDocument)) return false;
StartDocument other = (StartDocument) o;
return (encodingSet() == other.encodingSet())
&& (isStandalone() == other.isStandalone())
&& (standaloneSet() == other.standaloneSet())
&& stringsWithNullsEqual(getCharacterEncodingScheme(), other.getCharacterEncodingScheme())
&& stringsWithNullsEqual(getSystemId(), other.getSystemId())
&& stringsWithNullsEqual(getVersion(), other.getVersion())
;
}
public int hashCode()
{
int hash = 0;
if (encodingSet()) ++hash;
if (isStandalone()) --hash;
if (standaloneSet()) hash ^= 1;
if (mVersion != null) hash ^= mVersion.hashCode();
if (mEncodingScheme != null) hash ^= mEncodingScheme.hashCode();
if (mSystemId != null) hash ^= mSystemId.hashCode();
return hash;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/StartElementEventImpl.java 100644 0 0 21567 11520453235 23400 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.io.IOException;
import java.io.Writer;
import java.util.*;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import org.codehaus.stax2.XMLStreamWriter2;
import org.codehaus.stax2.ri.EmptyIterator;
import org.codehaus.stax2.ri.EmptyNamespaceContext;
/**
* Wstx {@link StartElement} implementation used when event is constructed
* from already objectified data, for example when constructed by the event
* factory.
*/
public class StartElementEventImpl
extends BaseEventImpl
implements StartElement
{
// // // Basic configuration
protected final QName mName;
protected final ArrayList mAttrs;
protected final ArrayList mNsDecls;
/**
* Enclosing namespace context
*/
protected NamespaceContext mParentNsCtxt;
// // // Lazily constructed components
NamespaceContext mActualNsCtxt = null;
/*
/////////////////////////////////////////////
// Life cycle
/////////////////////////////////////////////
*/
protected StartElementEventImpl(Location loc, QName name,
ArrayList attrs, ArrayList nsDecls,
NamespaceContext parentNsCtxt)
{
super(loc);
mName = name;
mAttrs = attrs;
mNsDecls = nsDecls;
mParentNsCtxt = (parentNsCtxt == null) ?
EmptyNamespaceContext.getInstance() : parentNsCtxt;
}
public static StartElementEventImpl construct(Location loc, QName name,
Iterator attrIt, Iterator nsDeclIt,
NamespaceContext nsCtxt)
{
ArrayList attrs;
if (attrIt == null || !attrIt.hasNext()) {
attrs = null;
} else {
attrs = new ArrayList();
do {
// Cast is only done for early catching of incorrect types
attrs.add((Attribute) attrIt.next());
} while (attrIt.hasNext());
}
ArrayList nsDecls;
if (nsDeclIt == null || !nsDeclIt.hasNext()) {
nsDecls = null;
} else {
nsDecls = new ArrayList();
do {
nsDecls.add((Namespace) nsDeclIt.next()); // cast to catch type problems early
} while (nsDeclIt.hasNext());
}
return new StartElementEventImpl(loc, name, attrs, nsDecls, nsCtxt);
}
/*
/////////////////////////////////////////////////////
// Implementation of abstract base methods, overrides
/////////////////////////////////////////////////////
*/
public StartElement asStartElement() { // overriden to save a cast
return this;
}
public int getEventType() {
return START_ELEMENT;
}
public boolean isStartElement() {
return true;
}
public void writeAsEncodedUnicode(Writer w)
throws XMLStreamException
{
try {
w.write('<');
String prefix = mName.getPrefix();
if (prefix != null && prefix.length() > 0) {
w.write(prefix);
w.write(':');
}
w.write(mName.getLocalPart());
// Any namespaces?
if (mNsDecls != null) {
for (int i = 0, len = mNsDecls.size(); i < len; ++i) {
w.write(' ');
((Namespace) mNsDecls.get(i)).writeAsEncodedUnicode(w);
}
}
// How about attrs?
if (mAttrs != null) {
for (int i = 0, len = mAttrs.size(); i < len; ++i) {
Attribute attr = (Attribute) mAttrs.get(i);
// No point in adding default attributes?
if (attr.isSpecified()) {
w.write(' ');
attr.writeAsEncodedUnicode(w);
}
}
}
w.write('>');
} catch (IOException ie) {
throw new XMLStreamException(ie);
}
}
public void writeUsing(XMLStreamWriter2 sw) throws XMLStreamException
{
QName n = mName;
sw.writeStartElement(n.getPrefix(), n.getLocalPart(),
n.getNamespaceURI());
// Any namespaces?
if (mNsDecls != null) {
for (int i = 0, len = mNsDecls.size(); i < len; ++i) {
Namespace ns = (Namespace) mNsDecls.get(i);
String prefix = ns.getPrefix();
String uri = ns.getNamespaceURI();
if (prefix == null || prefix.length() == 0) {
sw.writeDefaultNamespace(uri);
} else {
sw.writeNamespace(prefix, uri);
}
}
}
// How about attrs?
if (mAttrs != null) {
for (int i = 0, len = mAttrs.size(); i < len; ++i) {
Attribute attr = (Attribute) mAttrs.get(i);
// No point in adding default attributes?
if (attr.isSpecified()) {
QName name = attr.getName();
sw.writeAttribute(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), attr.getValue());
}
}
}
}
/*
/////////////////////////////////////////////
// Public API
/////////////////////////////////////////////
*/
public final QName getName() {
return mName;
}
public Iterator getNamespaces()
{
return (mNsDecls == null) ?
EmptyIterator.getInstance() : mNsDecls.iterator();
}
public NamespaceContext getNamespaceContext()
{
if (mActualNsCtxt == null) {
if (mNsDecls == null) {
mActualNsCtxt = mParentNsCtxt;
} else {
mActualNsCtxt = MergedNsContext.construct(mParentNsCtxt, mNsDecls);
}
}
return mActualNsCtxt;
}
public String getNamespaceURI(String prefix)
{
if (mNsDecls != null) {
if (prefix == null) {
prefix = "";
}
for (int i = 0, len = mNsDecls.size(); i < len; ++i) {
Namespace ns = (Namespace) mNsDecls.get(i);
String thisPrefix = ns.getPrefix();
if (thisPrefix == null) {
thisPrefix = "";
}
if (prefix.equals(thisPrefix)) {
return ns.getNamespaceURI();
}
}
}
return null;
}
public Attribute getAttributeByName(QName nameIn)
{
if (mAttrs == null) {
return null;
}
String ln = nameIn.getLocalPart();
String uri = nameIn.getNamespaceURI();
int len = mAttrs.size();
boolean notInNs = (uri == null || uri.length() == 0);
for (int i = 0; i < len; ++i) {
Attribute attr = (Attribute) mAttrs.get(i);
QName name = attr.getName();
if (name.getLocalPart().equals(ln)) {
String thisUri = name.getNamespaceURI();
if (notInNs) {
if (thisUri == null || thisUri.length() == 0) {
return attr;
}
} else {
if (uri.equals(thisUri)) {
return attr;
}
}
}
}
return null;
}
public Iterator getAttributes()
{
if (mAttrs == null) {
return EmptyIterator.getInstance();
}
return mAttrs.iterator();
}
/*
///////////////////////////////////////////
// Standard method impl
///////////////////////////////////////////
*/
public boolean equals(Object o)
{
if (o == this) return true;
if (o == null) return false;
if (!(o instanceof StartElement)) return false;
StartElement other = (StartElement) o;
// First things first: names must match
if (mName.equals(other.getName())) {
/* Rest is much trickier. I guess the easiest way is to
* just blindly iterate through ns decls and attributes.
* The main issue is whether ordering should matter; it will,
* if just iterating. Would need to sort to get canonical
* comparison.
*/
if (iteratedEquals(getNamespaces(), other.getNamespaces())) {
return iteratedEquals(getAttributes(), other.getAttributes());
}
}
return false;
}
public int hashCode()
{
int hash = mName.hashCode();
hash = addHash(getNamespaces(), hash);
hash = addHash(getAttributes(), hash);
return hash;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/Stax2EventAllocatorImpl.java 100644 0 0 14747 11520453235 23635 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import java.util.*;
import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.*;
import javax.xml.stream.events.DTD;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.XMLEventAllocator;
import javax.xml.stream.util.XMLEventConsumer;
import org.codehaus.stax2.*;
import org.codehaus.stax2.ri.EmptyIterator;
/**
* Base implementation of {@link XMLEventAllocator}, to be
* used either as is, or as a base for more specialized Stax2
* event allocator implementation.
*/
public class Stax2EventAllocatorImpl
implements XMLEventAllocator, XMLStreamConstants
{
public Stax2EventAllocatorImpl() { }
/*
//////////////////////////////////////////////////////////
// XMLEventAllocator implementation
//////////////////////////////////////////////////////////
*/
public XMLEvent allocate(XMLStreamReader r)
throws XMLStreamException
{
Location loc = getLocation(r);
switch (r.getEventType()) {
case CDATA:
return new CharactersEventImpl(loc, r.getText(), true);
case CHARACTERS:
return new CharactersEventImpl(loc, r.getText(), false);
case COMMENT:
return new CommentEventImpl(loc, r.getText());
case DTD:
return createDTD(r, loc);
case END_DOCUMENT:
return new EndDocumentEventImpl(loc);
case END_ELEMENT:
return new EndElementEventImpl(loc, r);
case PROCESSING_INSTRUCTION:
return new ProcInstrEventImpl(loc, r.getPITarget(), r.getPIData());
case SPACE:
{
CharactersEventImpl ch = new CharactersEventImpl(loc, r.getText(), false);
ch.setWhitespaceStatus(true);
return ch;
}
case START_DOCUMENT:
return new StartDocumentEventImpl(loc, r);
case START_ELEMENT:
return createStartElement(r, loc);
case ENTITY_REFERENCE:
return createEntityReference(r, loc);
/* Following 2 types should never get in here; they are directly
* handled by DTDReader, and can only be accessed via DTD event
* element.
*/
case ENTITY_DECLARATION:
case NOTATION_DECLARATION:
/* Following 2 types should never get in here; they are directly
* handled by the reader, and can only be accessed via start
* element.
*/
case NAMESPACE:
case ATTRIBUTE:
default:
throw new XMLStreamException("Unrecognized event type "+r.getEventType()+".");
}
}
public void allocate(XMLStreamReader r, XMLEventConsumer consumer)
throws XMLStreamException
{
consumer.add(allocate(r));
}
public XMLEventAllocator newInstance() {
return new Stax2EventAllocatorImpl();
}
/*
//////////////////////////////////////////////////////////
// Overridable methods
//////////////////////////////////////////////////////////
*/
/**
* Method used to get the {@link Location} object to use for
* an event to create. Base implementation just calls stream
* reader's accessors, but sub-classes may choose to use other
* methods (esp. when not in "preserve location" mode).
*/
protected Location getLocation(XMLStreamReader r)
{
return r.getLocation();
}
protected EntityReference createEntityReference(XMLStreamReader r, Location loc)
throws XMLStreamException
{
/* !!! 28-Jan-2007, TSA: One major problem here: there is no way
* to access actual entity declaration via Stax 1.0 or Stax2
* stream reader, at not least not after DTD subset has been
* processed. But let's do our best, which means we only know
* the name.
*/
return new EntityReferenceEventImpl(loc, r.getLocalName());
}
protected DTD createDTD(XMLStreamReader r, Location loc)
throws XMLStreamException
{
// Not sure if we really need this defensive coding but...
if (r instanceof XMLStreamReader2) {
XMLStreamReader2 sr2 = (XMLStreamReader2) r;
DTDInfo dtd = sr2.getDTDInfo();
return new DTDEventImpl
(loc,
dtd.getDTDRootName(),
dtd.getDTDSystemId(), dtd.getDTDPublicId(),
dtd.getDTDInternalSubset(),
dtd.getProcessedDTD());
}
/* No way to get all information... the real big problem is
* that of how to access root name: it's obligatory for
* DOCTYPE construct. :-/
*/
return new DTDEventImpl(loc, null, r.getText());
}
protected StartElement createStartElement(XMLStreamReader r, Location loc)
throws XMLStreamException
{
NamespaceContext nsCtxt = null;
/* Note: there's no way to get non-transient namespace context via
* Stax 1.0 interface -- the context you can access from reader
* remains stable only during current event.
*/
if (r instanceof XMLStreamReader2) {
nsCtxt = ((XMLStreamReader2) r).getNonTransientNamespaceContext();
}
List attrs;
{
int attrCount = r.getAttributeCount();
if (attrCount < 1) {
attrs = null;
} else {
attrs = new ArrayList(attrCount);
for (int i = 0; i < attrCount; ++i) {
QName aname = r.getAttributeName(i);
attrs.add(new AttributeEventImpl(loc, aname, r.getAttributeValue(i), r.isAttributeSpecified(i)));
}
}
}
List ns;
{
int nsCount = r.getNamespaceCount();
if (nsCount < 1) {
ns = null;
} else {
ns = new ArrayList(nsCount);
for (int i = 0; i < nsCount; ++i) {
ns.add(NamespaceEventImpl.constructNamespace(loc, r.getNamespacePrefix(i), r.getNamespaceURI(i)));
}
}
}
return StartElementEventImpl.construct
(loc, r.getName(),
((attrs == null) ? EmptyIterator.getInstance() : attrs.iterator()),
((ns == null) ? EmptyIterator.getInstance() : ns.iterator()),
nsCtxt);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/Stax2EventReaderAdapter.java 100644 0 0 7110 11520453235 23540 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import org.codehaus.stax2.XMLEventReader2;
/**
* This adapter implements parts of {@link XMLEventReader2}, the
* extended stream reader defined by Stax2 extension, by wrapping
* a vanilla Stax 1.0 {@link XMLEventReader} implementation.
*
*
*
* @author Tatu Saloranta
*/
public class Stax2EventReaderAdapter
implements XMLEventReader2
{
final XMLEventReader mReader;
/*
////////////////////////////////////////////////////
// Life-cycle methods
////////////////////////////////////////////////////
*/
protected Stax2EventReaderAdapter(XMLEventReader er)
{
mReader = er;
}
/**
* Method that should be used to add dynamic support for
* {@link XMLEventReader2}. Method will check whether the
* stream reader passed happens to be a {@link XMLEventReader2};
* and if it is, return it properly cast. If not, it will create
* necessary wrapper.
*/
public static XMLEventReader2 wrapIfNecessary(XMLEventReader er)
{
if (er instanceof XMLEventReader2) {
return (XMLEventReader2) er;
}
return new Stax2EventReaderAdapter(er);
}
/*
////////////////////////////////////////////////////
// XMLEventReader pass-through methods
////////////////////////////////////////////////////
*/
public void close() throws XMLStreamException {
mReader.close();
}
public String getElementText() throws XMLStreamException {
return mReader.getElementText();
}
public Object getProperty(String name) {
return mReader.getProperty(name);
}
public boolean hasNext() {
return mReader.hasNext();
}
public XMLEvent nextEvent() throws XMLStreamException
{
return mReader.nextEvent();
}
public Object next() {
return mReader.next();
}
public XMLEvent nextTag() throws XMLStreamException {
return mReader.nextTag();
}
public XMLEvent peek() throws XMLStreamException {
return mReader.peek();
}
/**
* Note: only here because we implement Iterator interface.
*/
public void remove() {
mReader.remove();
}
/*
////////////////////////////////////////////////////
// XMLEventReader2 implementation
////////////////////////////////////////////////////
*/
public boolean hasNextEvent() throws XMLStreamException
{
return (peek() != null);
}
public boolean isPropertySupported(String name)
{
/* No way to support properly via Stax1 interface... but
* let's approximate: we can be sure it is supported, if
* we can access value without IllegalArgumentException
*/
try {
/*Object x =*/ mReader.getProperty(name);
} catch (IllegalArgumentException iae) {
return false;
}
return true;
}
public boolean setProperty(String name, Object value)
{
// No way to support via Stax1 interface
return false;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/evt/Stax2FilteredEventReader.java 100644 0 0 6402 11520453235 23721 0 ustar 0 0 package org.codehaus.stax2.ri.evt;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import org.codehaus.stax2.XMLEventReader2;
/**
*
*
*/
public class Stax2FilteredEventReader
implements XMLEventReader2,
XMLStreamConstants
{
final XMLEventReader2 mReader;
final EventFilter mFilter;
public Stax2FilteredEventReader(XMLEventReader2 r, EventFilter f)
{
mReader = r;
mFilter = f;
}
/*
////////////////////////////////////////////////////
// XMLEventReader implementation
////////////////////////////////////////////////////
*/
public void close()
throws XMLStreamException
{
mReader.close();
}
public String getElementText()
throws XMLStreamException
{
// Is this enough?
return mReader.getElementText();
}
public Object getProperty(String name) {
return mReader.getProperty(name);
}
public boolean hasNext()
{
try {
return (peek() != null);
} catch (XMLStreamException sex) { // shouldn't happen, but...
throw new RuntimeException(sex);
}
}
public XMLEvent nextEvent()
throws XMLStreamException
{
while (true) {
XMLEvent evt = mReader.nextEvent();
if (evt == null || mFilter.accept(evt)) {
// should never get null, actually, but...
return evt;
}
}
}
public Object next()
{
try {
return nextEvent();
} catch (XMLStreamException sex) {
throw new RuntimeException(sex);
}
}
public XMLEvent nextTag()
throws XMLStreamException
{
// This can be implemented very similar to next()...
while (true) {
XMLEvent evt = mReader.nextTag();
if (evt == null || mFilter.accept(evt)) {
return evt;
}
}
}
/**
* This is bit tricky to implement, but it should filter out
* events just as nextEvent() would.
*/
public XMLEvent peek()
throws XMLStreamException
{
while (true) {
XMLEvent evt = mReader.peek();
if (evt == null || mFilter.accept(evt)) {
return evt;
}
// Need to discard as long as we have events:
mReader.nextEvent();
}
}
/**
* Note: only here because we implement Iterator interface
*/
public void remove() { // let's let underlying impl fail on it
mReader.remove();
}
/*
////////////////////////////////////////////////////
// XMLEventReader2 implementation
////////////////////////////////////////////////////
*/
public boolean hasNextEvent()
throws XMLStreamException
{
return (peek() != null);
}
public boolean isPropertySupported(String name)
{
return mReader.isPropertySupported(name);
}
public boolean setProperty(String name, Object value)
{
return mReader.setProperty(name, value);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/AsciiValueEncoder.java 100644 0 0 12562 11520453235 23014 0 ustar 0 0 /* Reference Implementation of
* Stax2 extension API (for basic Stax API, JSR-173)
*
* Copyright (c) 2008- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
/**
* This base class defines interface used for efficient encoding
* of typed values, by stream writers. The abstraction is necessary
* to reduce amount of duplicated code while avoiding significant
* additional overhead. The idea is that the low-level stream
* writer backend supplies encoder with the result buffer, while
* encoder itself knows the data and state. Together these allow
* for efficient serialization with light coupling.
*
*
*MIN_CHARS_WITHOUT_FLUSH)
*
*
*/
public final int endOfContent()
{
// If we are in a state where we don't have partial triplet, we are good to go
if ((_state == STATE_INITIAL) || (_state == STATE_OUTPUT_3)
|| (_state == STATE_OUTPUT_2) || (_state == STATE_OUTPUT_1)) {
return 0;
}
// Otherwise, only ok if no padding is used
if (_variant.usesPadding()) {
return -1;
}
// We do have 2 possible valid incomplete states
if (_state == STATE_VALID_2) { // 2 chars -> 1 output byte
// Got 12 bits, only need 8, need to shift
_state = STATE_OUTPUT_1;
_decodedData >>= 4;
return 1;
} else if (_state == STATE_VALID_3) { // 3 chars -> 2 output bytes
// Got 18 bits, of which 16 data
_decodedData >>= 2;
_state = STATE_OUTPUT_2;
return 2;
} else { // other states either handled, or can not be valid terminal states (STATE_VALID1)
return -1;
}
}
/*
//////////////////////////////////////////////////////////////
// Convenience accessors
//////////////////////////////////////////////////////////////
*/
/**
* Method that can be called to completely decode content that this
* decoder has been initialized with.
*/
public byte[] decodeCompletely()
{
Stax2Util.ByteAggregator aggr = getByteAggregator();
byte[] buffer = aggr.startAggregation();
while (true) {
// Ok let's read full buffers each round
int offset = 0;
int len = buffer.length;
do {
int readCount = decode(buffer, offset, len);
// note: can return 0; converted to -1 by front-end
if (readCount < 1) { // all done!
// but we must be in a valid state too:
/* Just need to verify we don't have partial stuff
* (missing one to three characters of a full quartet
* that encodes 1 - 3 bytes). Also: non-padding
* variants can be in incomplete state, from which
* data may need to be flushed...
*/
int left = endOfContent();
if (left < 0) { // incomplete, error
throw new IllegalArgumentException("Incomplete base64 triplet at the end of decoded content");
} else if (left > 0) { // 1 or 2 more bytes of data to add
continue;
}
return aggr.aggregateAll(buffer, offset);
}
offset += readCount;
len -= readCount;
} while (len > 0);
// and if we got it, hand out results, get a new buffer
buffer = aggr.addFullBlock(buffer);
}
}
public Stax2Util.ByteAggregator getByteAggregator()
{
if (_byteAggr == null) {
_byteAggr = new Stax2Util.ByteAggregator();
}
return _byteAggr;
}
/*
//////////////////////////////////////////////////////////////
// Internal helper methods error reporting
//////////////////////////////////////////////////////////////
*/
protected IllegalArgumentException reportInvalidChar(char ch, int bindex)
throws IllegalArgumentException
{
return reportInvalidChar(ch, bindex, null);
}
/**
* @param bindex Relative index within base64 character unit; between 0
* and 3 (as unit has exactly 4 characters)
*/
protected IllegalArgumentException reportInvalidChar(char ch, int bindex, String msg)
throws IllegalArgumentException
{
String base;
if (ch <= INT_SPACE) {
base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units";
} else if (_variant.usesPaddingChar(ch)) {
base = "Unexpected padding character ('"+_variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character";
} else if (!Character.isDefined(ch) || Character.isISOControl(ch)) {
// Not sure if we can really get here... ? (most illegal xml chars are caught at lower level)
base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content";
} else {
base = "Illegal character '"+((char)ch)+"' (code 0x"+Integer.toHexString(ch)+") in base64 content";
}
if (msg != null) {
base = base + ": " + msg;
}
return new IllegalArgumentException(base);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/CharArrayBase64Decoder.java 100644 0 0 23710 11520453235 23573 0 ustar 0 0 /* StAX2 extension for StAX API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
import java.util.*;
import org.codehaus.stax2.typed.Base64Variant;
/**
* Base64 decoder that can be used to decode base64 encoded content that
* is passed as char arrays.
*/
public final class CharArrayBase64Decoder
extends Base64DecoderBase
{
// // // Input buffer information
/**
* Text segment being currently processed.
*/
char[] _currSegment;
int _currSegmentPtr;
int _currSegmentEnd;
final ArrayList _nextSegments = new ArrayList();
int _lastSegmentOffset;
int _lastSegmentEnd;
/**
* Pointer of the next segment to process (after current one stored
* in {@link #_currSegment}) within {@link #mOtherSegments}.
*/
int _nextSegmentIndex;
public CharArrayBase64Decoder() { super(); }
public void init(Base64Variant variant, boolean firstChunk,
char[] lastSegment, int lastOffset, int lastLen,
List segments)
{
_variant = variant;
/* Leftovers only cleared if it is the first chunk (i.e.
* right after START_ELEMENT)
*/
if (firstChunk) {
_state = STATE_INITIAL;
}
_nextSegments.clear();
if (segments == null || segments.isEmpty()) { // no segments, simple
_currSegment = lastSegment;
_currSegmentPtr = lastOffset;
_currSegmentEnd = lastOffset+lastLen;
} else {
if (lastSegment == null) { // sanity check
throw new IllegalArgumentException();
}
Iterator it = segments.iterator();
_currSegment = (char[]) it.next();
_currSegmentPtr = 0;
_currSegmentEnd = _currSegment.length;
while (it.hasNext()) {
_nextSegments.add(it.next());
}
_nextSegmentIndex = 0;
// Plus, still need to add the last segment
_nextSegments.add(lastSegment);
_lastSegmentOffset = lastOffset;
_lastSegmentEnd = lastOffset+lastLen;
}
}
/**
* @param resultBuffer Buffer in which decoded bytes are returned
* @param resultOffset Offset that points to position to put the
* first decoded byte in maxLength Maximum number of bytes that can be returned
* in given buffer
*
* @return Number of bytes decoded and returned in the result buffer
*/
public int decode(byte[] resultBuffer, int resultOffset, int maxLength)
throws IllegalArgumentException
{
final int origResultOffset = resultOffset;
final int resultBufferEnd = resultOffset + maxLength;
main_loop:
while (true) {
switch (_state) {
case STATE_INITIAL:
// first, we'll skip preceding white space, if any
{
char ch;
do {
if (_currSegmentPtr >= _currSegmentEnd) {
if (!nextSegment()) {
break main_loop;
}
}
ch = _currSegment[_currSegmentPtr++];
} while (ch <= INT_SPACE);
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
throw reportInvalidChar(ch, 0);
}
_decodedData = bits;
}
// fall through, "fast" path
case STATE_VALID_1:
// then second base64 char; can't get padding yet, nor ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
if (!nextSegment()) {
_state = STATE_VALID_1; // to cover fall-through case
break main_loop;
}
}
char ch = _currSegment[_currSegmentPtr++];
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
throw reportInvalidChar(ch, 1);
}
_decodedData = (_decodedData << 6) | bits;
}
// fall through, "fast path"
case STATE_VALID_2:
// third base64 char; can be padding, but not ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
if (!nextSegment()) {
_state = STATE_VALID_2; // to cover fall-through case
break main_loop;
}
}
char ch = _currSegment[_currSegmentPtr++];
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
throw reportInvalidChar(ch, 2);
}
// Padding is off the "fast path", so:
_state = STATE_VALID_2_AND_PADDING;
continue main_loop;
}
_decodedData = (_decodedData << 6) | bits;
}
// fall through, "fast path"
case STATE_VALID_3:
// fourth and last base64 char; can be padding, but not ws
{
if (_currSegmentPtr >= _currSegmentEnd) {
if (!nextSegment()) {
_state = STATE_VALID_3; // to cover fall-through case
break main_loop;
}
}
char ch = _currSegment[_currSegmentPtr++];
int bits = _variant.decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
throw reportInvalidChar(ch, 3);
}
/* With padding we only get 2 bytes; but we have
* to shift it a bit so it is identical to triplet
* case with partial output.
* 3 chars gives 3x6 == 18 bits, of which 2 are
* dummies, need to discard:
*/
_decodedData >>= 2;
_state = STATE_OUTPUT_2;
continue main_loop;
}
// otherwise, our triple is now complete
_decodedData = (_decodedData << 6) | bits;
}
// still along fast path
case STATE_OUTPUT_3:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_3;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) (_decodedData >> 16);
// fall through
case STATE_OUTPUT_2:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_2;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) (_decodedData >> 8);
// fall through
case STATE_OUTPUT_1:
if (resultOffset >= resultBufferEnd) { // no room
_state = STATE_OUTPUT_1;
break main_loop;
}
resultBuffer[resultOffset++] = (byte) _decodedData;
_state = STATE_INITIAL;
continue main_loop;
case STATE_VALID_2_AND_PADDING:
{
if (_currSegmentPtr >= _currSegmentEnd) {
if (!nextSegment()) {
// must have valid state already (can't get in via fall-through)
break main_loop;
}
}
char ch = _currSegment[_currSegmentPtr++];
if (!_variant.usesPaddingChar(ch)) {
throw reportInvalidChar(ch, 3, "expected padding character '"+_variant.getPaddingChar()+"'");
}
// Got 12 bits, only need 8, need to shift
_state = STATE_OUTPUT_1;
_decodedData >>= 4;
}
continue main_loop;
default:
// sanity check: should never happen
throw new IllegalStateException("Illegal internal state "+_state);
}
}
return resultOffset - origResultOffset;
}
/*
//////////////////////////////////////////////////////////////
// Internal helper methods for input access:
//////////////////////////////////////////////////////////////
*/
private boolean nextSegment()
{
if (_nextSegmentIndex < _nextSegments.size()) {
_currSegment = (char[]) _nextSegments.get(_nextSegmentIndex++);
// last segment may have non-zero ptr, slack at end
if (_nextSegmentIndex == _nextSegments.size()) {
_currSegmentPtr = _lastSegmentOffset;
_currSegmentEnd = _lastSegmentEnd;
} else {
_currSegmentPtr = 0;
_currSegmentEnd = _currSegment.length;
}
return true;
}
return false;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/ri/typed/NumberUtil.java 100644 0 0 35300 11520453235 21550 0 ustar 0 0 /* StAX2 extension for StAX API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.ri.typed;
/**
* Helper class that contains method for converting numeric
* values to and from String representations.
*/
public final class NumberUtil
{
/**
* Maximum number of characters in a serialized integer is
* 11; one for (minus) sign, and then up to 10 digits
*/
public final static int MAX_INT_CLEN = 11;
/**
* Maximum number of characters in a serialized long is
* 21; one for (minus) sign, and then up to 20 digits
*/
public final static int MAX_LONG_CLEN = 21;
/**
* Maximum number of characters in a serialized double is
* 26 (at least for Sun JDK; 19 digits for mantissa, 3 for exponent,
* signs for mantissa and exponent, decimal point, 'E'):
* but let's pad it up a little bit just to play it safe.
*/
public final static int MAX_DOUBLE_CLEN = 32;
/**
* JDK serializes floats same way as doubles, so let's
* reserve as much space
*/
public final static int MAX_FLOAT_CLEN = MAX_DOUBLE_CLEN;
private final static char NULL_CHAR = (char) 0;
private final static int MILLION = 1000000;
private final static int BILLION = 1000000000;
private final static long TEN_BILLION_L = 10000000000L;
private final static long THOUSAND_L = 1000L;
private final static byte BYTE_HYPHEN = (byte) '-';
private final static byte BYTE_1 = (byte) '1';
private final static byte BYTE_2 = (byte) '2';
/**
*
*
*
* @author Tatu Saloranta
*
* @since 3.0.0
*/
public final class Base64Variant
{
/**
* Placeholder used by "no padding" variant, to be used when a character
* value is needed.
*/
final static char PADDING_CHAR_NONE = '\0';
/**
* Marker used to denote ascii characters that do not correspond
* to a 6-bit value (in this variant), and is not used as a padding
* character.
*/
public final static int BASE64_VALUE_INVALID = -1;
/**
* Marker used to denote ascii character (in decoding table) that
* is the padding character using this variant (if any).
*/
public final static int BASE64_VALUE_PADDING = -2;
/*
////////////////////////////////////////////////////
// Encoding/decoding tables
////////////////////////////////////////////////////
*/
/**
* Decoding table used for base 64 decoding.
*/
private final int[] _asciiToBase64 = new int[128];
/**
* Encoding table used for base 64 decoding when output is done
* as characters.
*/
private final char[] _base64ToAsciiC = new char[64];
/**
* Alternative encoding table used for base 64 decoding when output is done
* as ascii bytes.
*/
private final byte[] _base64ToAsciiB = new byte[64];
/*
////////////////////////////////////////////////////
// Other configuration
////////////////////////////////////////////////////
*/
/**
* Symbolic name of variant; used for diagnostics/debugging.
*/
final String _name;
/**
* Whether this variant uses padding or not.
*/
final boolean _usesPadding;
/**
* Characted used for padding, if any ({@link #PADDING_CHAR_NONE} if not).
*/
final char _paddingChar;
/**
* Maximum number of encoded base64 characters to output during encoding
* before adding a linefeed, if line length is to be limited
* ({@link java.lang.Integer#MAX_VALUE} if not limited).
*null
* if a processor is unable to provide it. Lexical representation
* should preferably be as close to the original input String
* as possible (as opposed to being normalized which often
* is done before actual parsing).
*/
protected String mLexical;
/**
* Construct an exception with the associated message.
*
* @param msg The message to report.
*/
public TypedXMLStreamException(String lexical, String msg)
{
super(msg);
mLexical = lexical;
}
/**
* Constructor used to wrap an underlying data conversion
* error message.
*
* @param rootCause Underlying conversion problem
*/
public TypedXMLStreamException(String lexical, IllegalArgumentException rootCause)
{
super(rootCause);
mLexical = lexical;
}
/**
* Construct an exception with the associated message and exception
*
* @param msg The message to report.
* @param rootCause Underlying conversion problem
*/
public TypedXMLStreamException(String lexical, String msg, IllegalArgumentException rootCause)
{
super(msg, rootCause);
mLexical = lexical;
}
/**
* Construct an exception with the associated message, exception and
* location.
*
* @param msg The message to report.
* @param location The location of the error.
* @param rootCause Underlying conversion problem
*/
public TypedXMLStreamException(String lexical, String msg,
Location location,
IllegalArgumentException rootCause)
{
super(msg, location, rootCause);
mLexical = lexical;
}
/**
* Construct an exception with the associated message, exception and
* location.
*
* @param msg The message to report.
* @param location The location of the error.
*/
public TypedXMLStreamException(String lexical, String msg,
Location location)
{
super(msg, location);
mLexical = lexical;
}
/**
* Return the lexical representation of the attribute or element
* content that could not be converted as requested.
*
* @return Lexical representation of unconverted content or
* null
if unavailable.
*/
public String getLexical() {
return mLexical;
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/TypedXMLStreamReader.java 100644 0 0 65401 11520453235 23022 0 ustar 0 0 /* Stax2 extension for basic Stax API (JSR-173).
*
* Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi
*
* Licensed under the License specified in file LICENSE, included with
* the source code.
* You may not use this file except in compliance with the License.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.stax2.typed;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.xml.namespace.QName;
// !!! 30-Jan-2008, TSa: JDK 1.5 only, can't add yet
//import javax.xml.datatype.XMLGregorianCalendar;
/**
* This interface provides a typed extension to
* {@link javax.xml.stream.XMLStreamReader}. It defines methods for
* reading XML data and converting it into Java types.
*
* @author Santiago.PericasGeertsen@sun.com
* @author Tatu Saloranta
*
* @since 3.0
*/
public interface TypedXMLStreamReader
extends XMLStreamReader
{
/*
//////////////////////////////////////////////////////////
// First, typed element accessors for scalar values
//////////////////////////////////////////////////////////
*/
/**
*
*
*
Read an element content as a 32-bit integer. The lexical * representation of a integer is defined by the * XML Schema integer data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the XML Schema integer data type. * An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema integer data type. *
* These are the pre and post conditions of calling this method: *
Read an element content as a 64-bit integer. The lexical * representation of a integer is defined by the * XML Schema integer data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the XML Schema integer data type. * An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema integer data type. *
* These are the pre and post conditions of calling this method: *
Read an element content as a 32-bit floating point value.
* The lexical representation is defined by the
* XML Schema float data type. Whitespace MUST be
* collapsed
* according to the whiteSpace facet for the XML Schema float data type.
* An exception is thrown if, after whitespace is
* collapsed, the resulting sequence of characters is not in
* the lexical space defined by the XML Schema integer data type.
*
* Note that valid representations include basic Java textual
* representations, as well as 3 special tokens: "INF", "-INF"
* and "NaN"
*
* These are the pre and post conditions of calling this method: *
Read an element content as a 64-bit floating point value.
* The lexical representation is defined by the
* XML Schema double data type. Whitespace MUST be
* collapsed
* according to the whiteSpace facet for the XML Schema double data type.
* An exception is thrown if, after whitespace is
* collapsed, the resulting sequence of characters is not in
* the lexical space defined by the XML Schema integer data type.
*
* Note that valid representations include basic Java textual
* representations, as well as 3 special tokens: "INF", "-INF"
* and "NaN"
*
* These are the pre and post conditions of calling this method: *
* Note: base64 variant defaults to {@link Base64Variants#MIME}. * * @see #readElementAsBinary */ public byte[] getElementAsBinary() throws XMLStreamException; /** * Convenience method that can be used similar to read binary content * instead of * {@link #readElementAsBinary}, in cases where neither performance nor * memory usage is a big concern. * * @param variant Base64 variant content is in; needed to decode * alternative variants ("modified base64") * * @see #readElementAsBinary */ public byte[] getElementAsBinary(Base64Variant variant) throws XMLStreamException; /** * Generic decoding method that can be used for efficient * decoding of additional types not support natively * by the typed stream reader. When method is called, * stream reader will collect all textual content of * the current element (effectively doing something * similar to a call to {@link #getElementText}, * and then call one of decode methods defined in * {@link TypedValueDecoder}. The only difference is that * passed value will be trimmed: that is, any leading or * trailing white space will be removed prior to calling * decode method. * After the call, passed * decoder object will have decoded and stored value * (if succesful) or thrown an exception (if not). *
* The main benefit of using this method (over just getting * all content by calling {@link #getElementText} * is efficiency: the stream reader can efficiently gather all textual * content necessary and pass it to the decoder, often avoiding * construction of intemediate Strings. *
* These are the pre- and post-conditions of calling this method: *
* Note that caller has to know more specific type of decoder, * since the base interface does not specify methods * for accessing actual decoded value. */ public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException; /* ////////////////////////////////////////////////////////// // Then streaming/chunked typed element accessors // for non-scalar (array, binary data) values ////////////////////////////////////////////////////////// */ /** * Read element content as decoded byte sequence; possibly only * reading a fragment of all element content. * The lexical representation of a byte array is defined by the * XML Schema base64Binary data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the XML Schema base64Binary * data type. An exception is thrown if content is not in * the lexical space defined by the XML Schema base64Binary data type. *
* Each call will read at least one decoded byte (and no more than * the specified maximum length), if there is any content remaining. * If none is available and END_ELEMENT is encountered, -1 is * returned. *
* These are the pre and post conditions of calling this method: *
* Additionally, caller MUST start decoding at START_ELEMENT; * if the first decode calls is at CHARACTERS or CDATA event, results * are not defined: result may be an exception, or invalid data being * returned. Implementations are encouraged to throw an exception * if possible, to make it easier to figure out the problem. *
* This method can be called multiple times until the cursor * is positioned at the corresponding END_ELEMENT event. Stated * differently, after the method is called for the first time, * the cursor will move and remain in the CHARACTERS position while there * are potentially more bytes available for reading. *
* * @param resultBuffer Array in which to copy decoded bytes. * @param offset Starting offset of the first decoded byte * within result buffer * @param maxLength Maximun number of bytes to decode with this call * * @return The number of bytes actually decoded and returned, * if any were available; -1 if there is no more content. * If any content was copied, value must be less or equal than *maxLength
* Note that this value is not guaranteed to equal maxLength
* even if enough content was available; that is, implementations
* can return shorter sections if they choose to, down to and including
* returning zero (0) if it was not possible to decode a full base64
* triplet (3 output bytes from 4 input characters).
*
* @throws IllegalArgumentException If resultBuffer
is
* null or offset is less than 0.
*/
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength,
Base64Variant variant)
throws XMLStreamException;
public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength)
throws XMLStreamException;
/**
* Read an element content as an int array. The lexical
* representation of a int array is defined by the following
* XML schema type:
* * <xs:simpleType name="intArray"> * <xs:list itemType="xs:int"/> * </xs:simpleType>* whose lexical space is a list of space-separated ints. * Whitespace MUST be * collapsed * according to the whiteSpace facet for the
intArray
* type shown above. An exception is thrown if, after whitespace is
* collapsed, the resulting sequence of characters is not in
* the lexical space defined by the intArray
data
* type.
*
**These are the pre and post conditions of calling this * method: *
length
, but
* at least one if any ints found. If not, -1 is returned
* to signal end of ints to parse.
*
* @throws IllegalStateException If called on event other than
* START_ELEMENT, END_ELEMENT, or CHARACTERS (which resulted from
* an earlier call)
*/
public int readElementAsIntArray(int[] resultBuffer, int offset, int length) throws XMLStreamException;
public int readElementAsLongArray(long[] resultBuffer, int offset, int length) throws XMLStreamException;
public int readElementAsFloatArray(float[] resultBuffer, int offset, int length) throws XMLStreamException;
public int readElementAsDoubleArray(double[] resultBuffer, int offset, int length) throws XMLStreamException;
/**
* Read an element content as an array of tokens. This is done by
* reader tokenizing textual content by white space, and sending
* each token to specified decoder for decoding. This is repeated
* as long as element content has more tokens and decoder can
* accept more values.
**These are the pre- and post-conditions of calling this * method: *
* Note: passed decoder must accept at least one value, reader will
* not verify capacity before calling it with the first token.
*
* @return Number of elements decoded, or -1 to indicate that there
* was no more element content tokens to decode.
*
* @throws IllegalStateException If called on event other than
* START_ELEMENT, END_ELEMENT, or CHARACTERS (which resulted from
* an earlier call)
*/
public int readElementAsArray(TypedArrayDecoder tad) throws XMLStreamException;
/*
//////////////////////////////////////////////////////////
// Then, typed attribute accessors
//////////////////////////////////////////////////////////
*/
/**
* Returns the index of the attribute whose local name is
* localName
and URI is namespaceURI
* or -1
if no such attribute exists.
*
* @param namespaceURI The attribute's namespace URI. Values of
* null and "" are considered the same, i.e. "no namespace"
* (or "empty" namespace)
* @param localName The attribute's local name.
* @return The attribute's index or -1
if no
* such attribute exists.
* @throws java.lang.IllegalStateException If this is not
* a START_ELEMENT event
* @throws XMLStreamException If unable to convert the resulting
* character sequence into an XML Schema boolean value.
*/
public int getAttributeIndex(String namespaceURI, String localName);
/**
*
Read an attribute value as a boolean. The lexical * representation of a boolean is defined by the * XML Schema boolean * data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the XML Schema boolean * data type. * An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema boolean data type.
* * @param index The attribute's index as returned by {@link #getAttributeIndex(String, String)} * @throws java.lang.IllegalStateException If this is not * a START_ELEMENT event. * @throws XMLStreamException If unable to convert the resulting * character sequence into an XML Schema boolean value. */ public boolean getAttributeAsBoolean(int index) throws XMLStreamException; /** *Read an attribute value as a boolean. The lexical * representation of a boolean is defined by the * XML Schema integer * data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the type. * An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema integer data type.
* * @param index The attribute's index as returned by {@link #getAttributeIndex(String, String)} * @throws java.lang.IllegalStateException If this is not a START_ELEMENT event. * @throws XMLStreamException If unable to convert the resulting * character sequence into an XML Schema boolean value. */ public int getAttributeAsInt(int index) throws XMLStreamException; /** *Read an attribute value as a boolean. The lexical * representation of a boolean is defined by the * XML Schema long * data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the type. * An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema long data type. *
* @param index The attribute's index as returned by {@link #getAttributeIndex(String, String)} * @throws java.lang.IllegalStateException If this is not a START_ELEMENT event. * @throws XMLStreamException If unable to convert the resulting * character sequence into an XML Schema boolean value. */ public long getAttributeAsLong(int index) throws XMLStreamException; public float getAttributeAsFloat(int index) throws XMLStreamException; public double getAttributeAsDouble(int index) throws XMLStreamException; public BigInteger getAttributeAsInteger(int index) throws XMLStreamException; public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException; public QName getAttributeAsQName(int index) throws XMLStreamException; // !!! 30-Jan-2008, TSa: JDK 1.5 only -- is that ok? //XMLGregorianCalendar getAttributeAsCalendar(int index) throws XMLStreamException; /** * Generic access method that can be used for efficient * decoding of additional types not support natively * by the typed stream reader. The main benefit of using * this method is that the stream reader can efficient * gather all textual content necessary and pass it * to the decoder, often avoiding construction of intemediate * Strings. ** As with {@link #getElementAs}, value passed to a decode * method will be trimmed of any leading or trailing white space. */ public void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException; /** *Read an attribute value as a byte array. The lexical * representation of a byte array is defined by the * XML Schema base64Binary data type. Whitespace MUST be * collapsed * according to the whiteSpace facet for the XML Schema base64Binary * data type. An exception is thrown if, after whitespace is * collapsed, the resulting sequence of characters is not in * the lexical space defined by the XML Schema base64Binary data type.
* * @param index The attribute's index as returned by {@link * #getAttributeIndex(String, String)}. * @return An array of bytes with the content. * @throws java.lang.IllegalStateException If this is not * a START_ELEMENT or ATTRIBUTE event. * @throws XMLStreamException If unable to convert the resulting * character sequence into an XML Schema boolean value. */ public byte[] getAttributeAsBinary(int index) throws XMLStreamException; public byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException; /** *Read an attribute content as an int array. The lexical * representation of a int array is defined by the following * XML schema type: *
* <xs:simpleType name="intArray"> * <xs:list itemType="xs:int"/> * </xs:simpleType>* whose lexical space is a list of space-separated ints. * Whitespace MUST be * collapsed * according to the whiteSpace facet for the
intArray
* type shown above. An exception is thrown if, after whitespace is
* collapsed, the resulting sequence of characters is not in
* the lexical space defined by the intArray
data
* type.
*
* @param index The attribute's index as returned by {@link
* #getAttributeIndex(String, String)}.
* @return An array of ints with the content.
* @throws java.lang.IllegalStateException If this is not
* a START_ELEMENT or ATTRIBUTE event.
* @throws XMLStreamException If unable to convert the resulting
* character sequence into an XML Schema boolean value.
*/
public int[] getAttributeAsIntArray(int index) throws XMLStreamException;
public long[] getAttributeAsLongArray(int index) throws XMLStreamException;
public float[] getAttributeAsFloatArray(int index) throws XMLStreamException;
public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException;
/**
* Method that allows reading contents of an attribute as an array
* of whitespace-separate tokens, decoded using specified decoder.
*
* @return Number of tokens decoded, 0 if none found
*/
public int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException;
}
stax2-3.1.1/src/java/org/codehaus/stax2/typed/TypedXMLStreamWriter.java 100644 0 0 24444 11520453235 23076 0 ustar 0 0 package org.codehaus.stax2.typed;
import java.math.BigDecimal;
import java.math.BigInteger;
// !!! 30-Jan-2008, TSa: JDK 1.5 only, can't add yet
//import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
/**
* This interface provides a typed extension to
* {@link javax.xml.stream.XMLStreamWriter}. It defines methods for
* writing XML data from Java types.
** Exceptions to throw are declared to be basic {@link XMLStreamException}s, * because in addition to specific {@link TypedXMLStreamException}s * (which are more specific subclasses) * that are thrown if conversion itself fails, methods also need to * access underlying textual content which may throw other subtypes * of stream exception. * * @author Santiago.PericasGeertsen@sun.com * @author Tatu Saloranta * * @since 3.0 */ public interface TypedXMLStreamWriter extends XMLStreamWriter { /* ////////////////////////////////////////////////////////// // First, typed element write methods for scalar values ////////////////////////////////////////////////////////// */ /** * Write a boolean value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema boolean data type. * * @param value The boolean value to write. */ void writeBoolean(boolean value) throws XMLStreamException; /** * Write an int value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema integer data type. */ void writeInt(int value) throws XMLStreamException; /** * Write a long value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema long data type. */ void writeLong(long value) throws XMLStreamException; /** * Write a float value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema float data type. */ void writeFloat(float value) throws XMLStreamException; /** * Write a double value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema double data type. */ void writeDouble(double value) throws XMLStreamException; void writeInteger(BigInteger value) throws XMLStreamException; /** * Write a decimal value to the output as textual element content. * The lexical representation of content is defined by the * XML Schema decimal data type. */ void writeDecimal(BigDecimal value) throws XMLStreamException; void writeQName(QName value) throws XMLStreamException; // !!! 30-Jan-2008, TSa: JDK 1.5 only, can't add yet //void writeCalendar(XMLGregorianCalendar value) throws XMLStreamException; /* ////////////////////////////////////////////////////////// // Then streaming/chunked typed element write methods // for non-scalar (array, binary data) values ////////////////////////////////////////////////////////// */ /** *
* Write binary content as base64 encoded characters to the output. * The lexical representation of a byte array is defined by the * XML Schema base64Binary data type. This method can be called * multiple times to write the array in chunks; but if so, * callers should write output in chunks divisible by 3 (natural * atomic unit of base64 output, which avoids padding) to * maximize interoperability. *
** Note: base64 variant defaults to {@link Base64Variants#MIME}. * * @param value The array from which to write the bytes. * @param from The index in the array from which writing starts. * @param length The number of bytes to write. */ void writeBinary(byte[] value, int from, int length) throws XMLStreamException; void writeBinary(Base64Variant variant, byte[] value, int from, int length) throws XMLStreamException; /** *
Write int array to the output. The lexical * representation of a int array is defined by the following * XML schema type: *
* <xs:simpleType name="intArray"> * <xs:list itemType="xs:int"/> * </xs:simpleType>* whose lexical space is a list of space-separated ints. * This method can be called multiple times to write the * array in chunks. * * @param value The array from which to write the ints. * @param from The index in the array from which writing starts. * @param length The number of ints to write. */ void writeIntArray(int[] value, int from, int length) throws XMLStreamException; void writeLongArray(long[] value, int from, int length) throws XMLStreamException; void writeFloatArray(float[] value, int from, int length) throws XMLStreamException; void writeDoubleArray(double[] value, int from, int length) throws XMLStreamException; // -- Attributes -- /** * Write a boolean value to the output as attribute value. * The lexical representation of content is defined by the * XML Schema boolean data type. * * @param prefix The attribute's prefix. Null or "" if no prefix is to be used * @param namespaceURI The attribute's URI (can be either null or empty String for "no namespace") * @param localName The attribute's local name * @param value The boolean value to write. */ void writeBooleanAttribute(String prefix, String namespaceURI, String localName, boolean value) throws XMLStreamException; /** * Write an integer value to the output as attribute value. * The lexical representation of content is defined by the * XML Schema integer data type. * * @param prefix The attribute's prefix. Null or "" if no prefix is to be used * @param namespaceURI The attribute's URI (can be either null or empty String for "no namespace") * @param localName The attribute's local name * @param value The integer value to write. */ void writeIntAttribute(String prefix, String namespaceURI, String localName, int value) throws XMLStreamException; /** * Write an long value to the output as attribute value. * The lexical representation of content is defined by the * XML Schema long data type. * * @param prefix The attribute's prefix. Null or "" if no prefix is to be used * @param namespaceURI The attribute's URI (can be either null or empty String for "no namespace") * @param localName The attribute's local name * @param value The long value to write. */ void writeLongAttribute(String prefix, String namespaceURI, String localName, long value) throws XMLStreamException; void writeFloatAttribute(String prefix, String namespaceURI, String localName, float value) throws XMLStreamException; void writeDoubleAttribute(String prefix, String namespaceURI, String localName, double value) throws XMLStreamException; void writeIntegerAttribute(String prefix, String namespaceURI, String localName, BigInteger value) throws XMLStreamException; void writeDecimalAttribute(String prefix, String namespaceURI, String localName, BigDecimal value) throws XMLStreamException; void writeQNameAttribute(String prefix, String namespaceURI, String localName, QName value) throws XMLStreamException; // !!! 30-Jan-2008, TSa: JDK 1.5 only -- is that ok? //void writeCalendarAttribute(String prefix, String namespaceURI, String localName, XMLGregorianCalendar value) throws XMLStreamException; /* 25-Apr-2008, tatus: Do we even want to deal with structured * or binary typed access with attributes? */ /** *
Write a byte array attribute. The lexical * representation of a byte array is defined by the * XML Schema base64Binary data type.
** Note: base64 variant defaults to {@link Base64Variants#MIME}. * * @param prefix The attribute's prefix. * @param namespaceURI The attribute's URI. * @param localName The attribute's local name. * @param value The array from which to write the bytes. */ void writeBinaryAttribute(String prefix, String namespaceURI, String localName, byte[] value) throws XMLStreamException; void writeBinaryAttribute(Base64Variant variant, String prefix, String namespaceURI, String localName, byte[] value) throws XMLStreamException; /** *
Write int array attribute. The lexical * representation of a int array is defined by the following * XML schema type: *
* <xs:simpleType name="intArray"> * <xs:list itemType="xs:int"/> * </xs:simpleType>* whose lexical space is a list of space-separated ints. * * @param prefix The attribute's prefix. * @param namespaceURI The attribute's URI. * @param localName The attribute's local name. * @param value The array from which to write the ints. */ void writeIntArrayAttribute(String prefix, String namespaceURI, String localName, int[] value) throws XMLStreamException; void writeLongArrayAttribute(String prefix, String namespaceURI, String localName, long[] value) throws XMLStreamException; void writeFloatArrayAttribute(String prefix, String namespaceURI, String localName, float[] value) throws XMLStreamException; void writeDoubleArrayAttribute(String prefix, String namespaceURI, String localName, double[] value) throws XMLStreamException; } stax2-3.1.1/src/java/org/codehaus/stax2/util/StreamReader2Delegate.java 100644 0 0 22250 11520453235 22773 0 ustar 0 0 package org.codehaus.stax2.util; import java.io.IOException; import java.io.Writer; import java.math.BigDecimal; import java.math.BigInteger; import javax.xml.namespace.NamespaceContext; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.util.StreamReaderDelegate; import org.codehaus.stax2.AttributeInfo; import org.codehaus.stax2.DTDInfo; import org.codehaus.stax2.LocationInfo; import org.codehaus.stax2.XMLStreamReader2; import org.codehaus.stax2.typed.Base64Variant; import org.codehaus.stax2.typed.TypedArrayDecoder; import org.codehaus.stax2.typed.TypedValueDecoder; import org.codehaus.stax2.validation.ValidationProblemHandler; import org.codehaus.stax2.validation.XMLValidationSchema; import org.codehaus.stax2.validation.XMLValidator; public class StreamReader2Delegate extends StreamReaderDelegate implements XMLStreamReader2 { protected XMLStreamReader2 mDelegate2; /* ////////////////////////////////////////////// // Life-cycle ////////////////////////////////////////////// */ public StreamReader2Delegate(XMLStreamReader2 sr) { super(sr); mDelegate2 = sr; } // @Override public void setParent(XMLStreamReader pr) { super.setParent(pr); mDelegate2 = (XMLStreamReader2) pr; } /* ////////////////////////////////////////////// // XMLStreamReader2 implementation ////////////////////////////////////////////// */ public void closeCompletely() throws XMLStreamException { mDelegate2.closeCompletely(); } public AttributeInfo getAttributeInfo() throws XMLStreamException { return mDelegate2.getAttributeInfo(); } public DTDInfo getDTDInfo() throws XMLStreamException { return mDelegate2.getDTDInfo(); } public int getDepth() { return mDelegate2.getDepth(); } public Object getFeature(String name) { return mDelegate2.getFeature(name); } public LocationInfo getLocationInfo() { return mDelegate2.getLocationInfo(); } public NamespaceContext getNonTransientNamespaceContext() { return mDelegate2.getNonTransientNamespaceContext(); } public String getPrefixedName() { return mDelegate2.getPrefixedName(); } public int getText(Writer w, boolean preserveContents) throws IOException, XMLStreamException { return mDelegate2.getText(w, preserveContents); } public boolean isEmptyElement() throws XMLStreamException { return mDelegate2.isEmptyElement(); } public boolean isPropertySupported(String name) { return mDelegate2.isPropertySupported(name); } public void setFeature(String name, Object value) { mDelegate2.setFeature(name, value); } public boolean setProperty(String name, Object value) { return mDelegate2.setProperty(name, value); } public void skipElement() throws XMLStreamException { mDelegate2.skipElement(); } /* ////////////////////////////////////////////// // XMLStreamReader2, Validatable ////////////////////////////////////////////// */ public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h) { return mDelegate2.setValidationProblemHandler(h); } public XMLValidator stopValidatingAgainst(XMLValidationSchema schema) throws XMLStreamException { return mDelegate2.stopValidatingAgainst(schema); } public XMLValidator stopValidatingAgainst(XMLValidator validator) throws XMLStreamException { return mDelegate2.stopValidatingAgainst(validator); } public XMLValidator validateAgainst(XMLValidationSchema schema) throws XMLStreamException { return mDelegate2.validateAgainst(schema); } /* ////////////////////////////////////////////// // TypedXMLStreamReader implementation ////////////////////////////////////////////// */ public int getAttributeIndex(String namespaceURI, String localName) { return mDelegate2.getAttributeIndex(namespaceURI, localName); } public boolean getAttributeAsBoolean(int index) throws XMLStreamException { return mDelegate2.getAttributeAsBoolean(index); } public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException { return mDelegate2.getAttributeAsDecimal(index); } public double getAttributeAsDouble(int index) throws XMLStreamException { return mDelegate2.getAttributeAsDouble(index); } public float getAttributeAsFloat(int index) throws XMLStreamException { return mDelegate2.getAttributeAsFloat(index); } public int getAttributeAsInt(int index) throws XMLStreamException { return mDelegate2.getAttributeAsInt(index); } public BigInteger getAttributeAsInteger(int index) throws XMLStreamException { return mDelegate2.getAttributeAsInteger(index); } public long getAttributeAsLong(int index) throws XMLStreamException { return mDelegate2.getAttributeAsLong(index); } public QName getAttributeAsQName(int index) throws XMLStreamException { return mDelegate2.getAttributeAsQName(index); } public int[] getAttributeAsIntArray(int index) throws XMLStreamException { return mDelegate2.getAttributeAsIntArray(index); } public long[] getAttributeAsLongArray(int index) throws XMLStreamException { return mDelegate2.getAttributeAsLongArray(index); } public float[] getAttributeAsFloatArray(int index) throws XMLStreamException { return mDelegate2.getAttributeAsFloatArray(index); } public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException { return mDelegate2.getAttributeAsDoubleArray(index); } public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException { mDelegate2.getElementAs(tvd); } public boolean getElementAsBoolean() throws XMLStreamException { return mDelegate2.getElementAsBoolean(); } public BigDecimal getElementAsDecimal() throws XMLStreamException { return mDelegate2.getElementAsDecimal(); } public double getElementAsDouble() throws XMLStreamException { return mDelegate2.getElementAsDouble(); } public float getElementAsFloat() throws XMLStreamException { return mDelegate2.getElementAsFloat(); } public int getElementAsInt() throws XMLStreamException { return mDelegate2.getElementAsInt(); } public BigInteger getElementAsInteger() throws XMLStreamException { return mDelegate2.getElementAsInteger(); } public long getElementAsLong() throws XMLStreamException { return mDelegate2.getElementAsLong(); } public QName getElementAsQName() throws XMLStreamException { return mDelegate2.getElementAsQName(); } public byte[] getElementAsBinary() throws XMLStreamException { return mDelegate2.getElementAsBinary(); } public byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException { return mDelegate2.getElementAsBinary(v); } public void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException { mDelegate2.getAttributeAs(index, tvd); } public int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException { return mDelegate2.getAttributeAsArray(index, tad); } public byte[] getAttributeAsBinary(int index) throws XMLStreamException { return mDelegate2.getAttributeAsBinary(index); } public byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException { return mDelegate2.getAttributeAsBinary(index, v); } public int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException { return mDelegate2.readElementAsDoubleArray(value, from, length); } public int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException { return mDelegate2.readElementAsFloatArray(value, from, length); } public int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException { return mDelegate2.readElementAsIntArray(value, from, length); } public int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException { return mDelegate2.readElementAsLongArray(value, from, length); } public int readElementAsArray(TypedArrayDecoder tad) throws XMLStreamException { return mDelegate2.readElementAsArray(tad); } public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength) throws XMLStreamException { return mDelegate2.readElementAsBinary(resultBuffer, offset, maxLength); } public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength, Base64Variant v) throws XMLStreamException { return mDelegate2.readElementAsBinary(resultBuffer, offset, maxLength, v); } } stax2-3.1.1/src/java/org/codehaus/stax2/util/StreamWriter2Delegate.java 100644 0 0 22711 11520453235 23047 0 ustar 0 0 package org.codehaus.stax2.util; import java.math.BigDecimal; import java.math.BigInteger; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import org.codehaus.stax2.XMLStreamLocation2; import org.codehaus.stax2.XMLStreamReader2; import org.codehaus.stax2.XMLStreamWriter2; import org.codehaus.stax2.typed.Base64Variant; import org.codehaus.stax2.validation.ValidationProblemHandler; import org.codehaus.stax2.validation.XMLValidationSchema; import org.codehaus.stax2.validation.XMLValidator; public class StreamWriter2Delegate extends StreamWriterDelegate implements XMLStreamWriter2 { protected XMLStreamWriter2 mDelegate2; /* ////////////////////////////////////////////// // Life-cycle ////////////////////////////////////////////// */ public StreamWriter2Delegate(XMLStreamWriter2 parent) { super(parent); } // @Override public void setParent(XMLStreamWriter w) { super.setParent(w); mDelegate2 = (XMLStreamWriter2) w; } /* ////////////////////////////////////////////// // XMLStreamWriter2 implementation ////////////////////////////////////////////// */ public void closeCompletely() throws XMLStreamException { mDelegate2.closeCompletely(); } public void copyEventFromReader(XMLStreamReader2 r, boolean preserveEventData) throws XMLStreamException { mDelegate2.copyEventFromReader(r, preserveEventData); } public String getEncoding() { return mDelegate2.getEncoding(); } public XMLStreamLocation2 getLocation() { return mDelegate2.getLocation(); } public boolean isPropertySupported(String name) { return mDelegate2.isPropertySupported(name); } public boolean setProperty(String name, Object value) { return mDelegate2.setProperty(name, value); } public void writeCData(char[] text, int start, int len) throws XMLStreamException { mDelegate2.writeCData(text, start, len); } public void writeDTD(String rootName, String systemId, String publicId, String internalSubset) throws XMLStreamException { mDelegate2.writeDTD(rootName, systemId, publicId, internalSubset); } public void writeFullEndElement() throws XMLStreamException { mDelegate2.writeFullEndElement(); } public void writeRaw(String text) throws XMLStreamException { mDelegate2.writeRaw(text); } public void writeRaw(String text, int offset, int length) throws XMLStreamException { mDelegate2.writeRaw(text, offset, length); } public void writeRaw(char[] text, int offset, int length) throws XMLStreamException { mDelegate2.writeRaw(text, offset, length); } public void writeSpace(String text) throws XMLStreamException { mDelegate2.writeSpace( text); } public void writeSpace(char[] text, int offset, int length) throws XMLStreamException { mDelegate2.writeSpace(text, offset, length); } public void writeStartDocument(String version, String encoding, boolean standAlone) throws XMLStreamException { mDelegate2.writeStartDocument(version, encoding, standAlone); } public void writeBinary(byte[] value, int from, int length) throws XMLStreamException { mDelegate2.writeBinary(value, from, length); } public void writeBinary(Base64Variant v, byte[] value, int from, int length) throws XMLStreamException { mDelegate2.writeBinary(v, value, from, length); } public void writeBinaryAttribute(String prefix, String namespaceURI, String localName, byte[] value) throws XMLStreamException { mDelegate2.writeBinaryAttribute(prefix, namespaceURI, localName, value); } public void writeBinaryAttribute(Base64Variant v, String prefix, String namespaceURI, String localName, byte[] value) throws XMLStreamException { mDelegate2.writeBinaryAttribute(v, prefix, namespaceURI, localName, value); } public void writeBoolean(boolean value) throws XMLStreamException { mDelegate2.writeBoolean(value); } public void writeBooleanAttribute(String prefix, String namespaceURI, String localName, boolean value) throws XMLStreamException { mDelegate2.writeBooleanAttribute(prefix, namespaceURI, localName, value); } public void writeDecimal(BigDecimal value) throws XMLStreamException { mDelegate2.writeDecimal(value); } public void writeDecimalAttribute(String prefix, String namespaceURI, String localName, BigDecimal value) throws XMLStreamException { mDelegate2.writeDecimalAttribute(prefix, namespaceURI, localName, value); } public void writeDouble(double value) throws XMLStreamException { mDelegate2.writeDouble(value); } public void writeDoubleArray(double[] value, int from, int length) throws XMLStreamException { mDelegate2.writeDoubleArray(value, from, length); } public void writeDoubleArrayAttribute(String prefix, String namespaceURI, String localName, double[] value) throws XMLStreamException { mDelegate2.writeDoubleArrayAttribute(prefix, namespaceURI, localName, value); } public void writeDoubleAttribute(String prefix, String namespaceURI, String localName, double value) throws XMLStreamException { mDelegate2.writeDoubleAttribute(prefix, namespaceURI, localName, value); } public void writeFloat(float value) throws XMLStreamException { mDelegate2.writeFloat(value); } public void writeFloatArray(float[] value, int from, int length) throws XMLStreamException { mDelegate2.writeFloatArray(value, from, length); } public void writeFloatArrayAttribute(String prefix, String namespaceURI, String localName, float[] value) throws XMLStreamException { mDelegate2.writeFloatArrayAttribute(prefix, namespaceURI, localName, value); } public void writeFloatAttribute(String prefix, String namespaceURI, String localName, float value) throws XMLStreamException { mDelegate2.writeFloatAttribute( prefix, namespaceURI, localName, value); } public void writeInt(int value) throws XMLStreamException { mDelegate2.writeInt(value); } public void writeIntArray(int[] value, int from, int length) throws XMLStreamException { mDelegate2.writeIntArray(value, from, length); } public void writeIntArrayAttribute(String prefix, String namespaceURI, String localName, int[] value) throws XMLStreamException { mDelegate2.writeIntArrayAttribute( prefix, namespaceURI, localName, value); } public void writeIntAttribute(String prefix, String namespaceURI, String localName, int value) throws XMLStreamException { mDelegate2.writeIntAttribute( prefix, namespaceURI, localName, value); } public void writeInteger(BigInteger value) throws XMLStreamException { mDelegate2.writeInteger(value); } public void writeIntegerAttribute(String prefix, String namespaceURI, String localName, BigInteger value) throws XMLStreamException { mDelegate2.writeIntegerAttribute( prefix, namespaceURI, localName, value); } public void writeLong(long value) throws XMLStreamException { mDelegate2.writeLong(value); } public void writeLongArray(long[] value, int from, int length) throws XMLStreamException { mDelegate2.writeLongArray(value, from, length); } public void writeLongArrayAttribute(String prefix, String namespaceURI, String localName, long[] value) throws XMLStreamException { mDelegate2.writeLongArrayAttribute( prefix, namespaceURI, localName, value); } public void writeLongAttribute(String prefix, String namespaceURI, String localName, long value) throws XMLStreamException { mDelegate2.writeLongAttribute(prefix, namespaceURI, localName, value); } public void writeQName(QName value) throws XMLStreamException { mDelegate2.writeQName(value); } public void writeQNameAttribute(String prefix, String namespaceURI, String localName, QName value) throws XMLStreamException { mDelegate2.writeQNameAttribute(prefix, namespaceURI, localName, value); } public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h) { return mDelegate2.setValidationProblemHandler(h); } public XMLValidator stopValidatingAgainst(XMLValidationSchema schema) throws XMLStreamException { return mDelegate2.stopValidatingAgainst(schema); } public XMLValidator stopValidatingAgainst(XMLValidator validator) throws XMLStreamException { return mDelegate2.stopValidatingAgainst(validator); } public XMLValidator validateAgainst(XMLValidationSchema schema) throws XMLStreamException { return mDelegate2.validateAgainst(schema); } } stax2-3.1.1/src/java/org/codehaus/stax2/util/StreamWriterDelegate.java 100644 0 0 13777 11520453235 23001 0 ustar 0 0 /* StAX2 extension for StAX API (JSR-173). * * Copyright (c) 2005- Tatu Saloranta, tatu.saloranta@iki.fi * * Licensed under the License specified in file LICENSE, included with * the source code. * You may not use this file except in compliance with the License. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.stax2.util; import javax.xml.namespace.NamespaceContext; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; /** * Similar to {@link javax.xml.stream.util.StreamReaderDelegate}, * but implements a proxy for {@link XMLStreamWriter}. * The only additional methods are ones for setting and accessing * the delegate to forward requests to. *
* Note: such class really should exist in core Stax API
* (in package javax.xml.stream.util
), but since
* it does not, it is implemented within Stax2 extension API
*
* @since 3.0
*/
public class StreamWriterDelegate
implements XMLStreamWriter
{
protected XMLStreamWriter mDelegate;
/*
//////////////////////////////////////////////
// Life-cycle
//////////////////////////////////////////////
*/
public StreamWriterDelegate(XMLStreamWriter parentWriter)
{
mDelegate = parentWriter;
}
public void setParent(XMLStreamWriter parentWriter)
{
mDelegate = parentWriter;
}
public XMLStreamWriter getParent()
{
return mDelegate;
}
/*
//////////////////////////////////////////////
// XMLStreamWriter implementation
//////////////////////////////////////////////
*/
public void close() throws XMLStreamException {
mDelegate.close();
}
public void flush() throws XMLStreamException {
mDelegate.flush();
}
public NamespaceContext getNamespaceContext() {
return mDelegate.getNamespaceContext();
}
public String getPrefix(String ns) throws XMLStreamException {
return mDelegate.getPrefix(ns);
}
public Object getProperty(String pname) throws IllegalArgumentException {
return mDelegate.getProperty(pname);
}
public void setDefaultNamespace(String ns) throws XMLStreamException {
mDelegate.setDefaultNamespace(ns);
}
public void setNamespaceContext(NamespaceContext nc)
throws XMLStreamException
{
mDelegate.setNamespaceContext(nc);
}
public void setPrefix(String prefix, String uri) throws XMLStreamException {
mDelegate.setPrefix(prefix, uri);
}
public void writeAttribute(String arg0, String arg1) throws XMLStreamException {
mDelegate.writeAttribute(arg0, arg1);
}
public void writeAttribute(String arg0, String arg1, String arg2) throws XMLStreamException {
mDelegate.writeAttribute(arg0, arg1, arg2);
}
public void writeAttribute(String arg0, String arg1, String arg2, String arg3) throws XMLStreamException {
mDelegate.writeAttribute(arg0, arg1, arg2, arg3);
}
public void writeCData(String arg0) throws XMLStreamException {
mDelegate.writeCData(arg0);
}
public void writeCharacters(String arg0) throws XMLStreamException {
mDelegate.writeCharacters(arg0);
}
public void writeCharacters(char[] arg0, int arg1, int arg2)
throws XMLStreamException {
mDelegate.writeCharacters(arg0, arg1, arg2);
}
public void writeComment(String arg0) throws XMLStreamException {
mDelegate.writeComment(arg0);
}
public void writeDTD(String arg0) throws XMLStreamException {
mDelegate.writeDTD(arg0);
}
public void writeDefaultNamespace(String arg0) throws XMLStreamException {
mDelegate.writeDefaultNamespace(arg0);
}
public void writeEmptyElement(String arg0) throws XMLStreamException {
mDelegate.writeEmptyElement(arg0);
}
public void writeEmptyElement(String arg0, String arg1) throws XMLStreamException {
mDelegate.writeEmptyElement(arg0, arg1);
}
public void writeEmptyElement(String arg0, String arg1, String arg2)
throws XMLStreamException {
mDelegate.writeEmptyElement(arg0, arg1, arg2);
}
public void writeEndDocument() throws XMLStreamException {
mDelegate.writeEndDocument();
}
public void writeEndElement() throws XMLStreamException {
mDelegate.writeEndElement();
}
public void writeEntityRef(String arg0) throws XMLStreamException {
mDelegate.writeEntityRef(arg0);
}
public void writeNamespace(String arg0, String arg1)
throws XMLStreamException {
mDelegate.writeNamespace(arg0, arg1);
}
public void writeProcessingInstruction(String arg0)
throws XMLStreamException {
mDelegate.writeProcessingInstruction(arg0);
}
public void writeProcessingInstruction(String arg0, String arg1)
throws XMLStreamException {
mDelegate.writeProcessingInstruction(arg0, arg1);
}
public void writeStartDocument() throws XMLStreamException {
mDelegate.writeStartDocument();
}
public void writeStartDocument(String arg0) throws XMLStreamException {
mDelegate.writeStartDocument(arg0);
}
public void writeStartDocument(String arg0, String arg1)
throws XMLStreamException {
mDelegate.writeStartDocument(arg0, arg1);
}
public void writeStartElement(String arg0) throws XMLStreamException {
mDelegate.writeStartElement(arg0);
}
public void writeStartElement(String arg0, String arg1)
throws XMLStreamException {
mDelegate.writeStartElement(arg0, arg1);
}
public void writeStartElement(String arg0, String arg1, String arg2)
throws XMLStreamException {
mDelegate.writeStartElement(arg0, arg1, arg2);
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/AttributeContainer.java 100644 0 0 2362 11520453235 23645 0 ustar 0 0 package org.codehaus.stax2.validation;
/**
* Interface that is used to allow validators to do attribute defaulting.
* That is, to allow specific post-processing for elements, such that after
* all attribute values that an xml element has have been processed, it
* is possible to add new attribute/value pairs in cases where attribute
* only has a default value in DTD or W3C Schema.
*/
public interface AttributeContainer
{
/**
* @return Number of atributes container contains currently. Can be used
* to determine the index number for the next attribute to be added.
*/
public int getAttributeCount();
/**
* Method that can be used to add a new attribute value for an attribute
* that was not yet contained by the container, as part of using attribute
* default value mechanism.
*
* Note: caller has to ensure that the addition would not introduce a
* duplicate; attribute container implementation is not required to do
* any validation on attribute name (local name, prefix, uri) or value.
*
* @return Index of the newly added attribute.
*/
public int addDefaultAttribute(String localName, String uri, String prefix,
String value);
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/DTDValidationSchema.java 100644 0 0 4222 11520453235 23603 0 ustar 0 0 package org.codehaus.stax2.validation;
/**
* Specialized interface that covers schema features unique to DTDs.
* Necessary to have basic level of support for entities and notations.
*/
public interface DTDValidationSchema
extends XMLValidationSchema
{
/*
//////////////////////////////////////////////////////////
// Entity support
//////////////////////////////////////////////////////////
*/
/**
* @return Number of general (non-parameter) entities (of all types)
* declared in this DTD
* schema (in subsets [internal, external] included)
*/
public int getEntityCount();
/**
* @return True if a general entity with the specified name was
* defined in this dtd
*/
//public boolean isEntityDefined(String name);
/**
* @return Index of the entity with given name (between 0 and
* getEntityCount()-1
)
* if such general entity
* was defined in this dtd; -1 if not.
*/
//public int findEntity(String name);
//public String getEntityName(int index);
//public boolean isEntityParsed(int index);
//public boolean isEntityExternal(int index);
//public String getEntityPublicId(int index);
//public String getEntitySystemId(int index);
//public String getNotationIdOfEntity(int entityIndex);
//public String getEntityExpansionText(int index);
/*
//////////////////////////////////////////////////////////
// Notation support
//////////////////////////////////////////////////////////
*/
/**
* @return Number of notations declared in this DTD
* schema (in subsets [internal, external] included)
*/
public int getNotationCount();
//public boolean isNotationDefined(String name);
/**
* @return Index of the notation with given name (between 0 and
* getNotationtyCount()-1
)
* if such notation was defined in this dtd; -1 if not.
*/
//public int findNotation(String name);
//public String getNotationName(int index);
//public String getNotationPublicId(int index);
//public String getNotationSystemId(int index);
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/Validatable.java 100644 0 0 5701 11520453235 22247 0 ustar 0 0 package org.codehaus.stax2.validation;
import javax.xml.stream.XMLStreamException;
/**
* Interface that defines API that Stax2 validation system exposes to the
* applications. It is implemented by stream readers and writers.
*
* Interface defines methods for starting and stopping * validation against specific schemas, or validator instances, as well * as method(s) for adding an optional custom problem handler. */ public interface Validatable { /** * Method that will construct a {@link XMLValidator} instance from the * given schema (unless a validator for that schema has already been * added), * initialize it if necessary, and make validatable object (reader, * writer) * call appropriate validation methods from this point on until the * end of the document (that is, it's not scoped with sub-trees), or until * validator is removed by an explicit call to * {@link #stopValidatingAgainst}. *
* Note that while this method can be called at any point in output * processing, validator instances are not required to be able to handle * addition at other points than right before outputting the root element. * * @return Validator instance constructed, if validator was added, or null * if a validator for the schema has already been constructed. */ public XMLValidator validateAgainst(XMLValidationSchema schema) throws XMLStreamException; /** * Method that can be called by application to stop validating * output against a schema, for which {@link #validateAgainst} * was called earlier. * * @return Validator instance created from the schema that was removed, * if one was in use; null if no such schema in use. */ public XMLValidator stopValidatingAgainst(XMLValidationSchema schema) throws XMLStreamException; /** * Method that can be called by application to stop validating * output using specified validator. The validator passed should be * an earlier return value for a call to {@link #validateAgainst}. *
* Note: the specified validator is compared for identity with validators
* in use, not for equality.
*
* @return Validator instance found (ie. argument validator
)
* if it was being used for validating current document; null if not.
*/
public XMLValidator stopValidatingAgainst(XMLValidator validator)
throws XMLStreamException;
/**
* Method that application can call to define a custom handler for
* validation problems encountered during validation process.
*
* @param h Handler to install, if non null; if null, indicates that
* the default (implementation-specific) handling should be used
*
* @return Previously set validation problem handler, if any; null
* if none was set
*/
public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h);
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/ValidationContext.java 100644 0 0 16327 11520453235 23524 0 ustar 0 0 package org.codehaus.stax2.validation;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
/**
* Interface that defines functionality exposed by the "owner" of the
* content to validate (usually a stream reader or stream writer) to
* validators, needed in addition to actually validatable content, for
* succesful validation. It also defines methods needed for infoset
* augmentation some validators do, such as adding default values
* to attributes.
* Some of functionality is optional (for example, writer
* may not have any useful location information).
*
* The functionality included is close to the minimal subset of * functionality needed to support 3 main streamable schema languages * (DTD, W3C Schema, Relax NG). */ public interface ValidationContext { /* /////////////////////////////////////////////////////////////////////// // Basic configuration /////////////////////////////////////////////////////////////////////// */ /** * Method that validator can call to figure out which xml version * document being validated declared (if none, "1.0" is assumed as * per xml specifications 1.0 and 1.1). * * @return Xml version of the document: currently has to be either * "1.0" or "1.1". */ public String getXmlVersion(); /* /////////////////////////////////////////////////////////////////////// // Input element stack access /////////////////////////////////////////////////////////////////////// */ /** * Method that can be used to access name information of the * innermost (top) element in the element stack. * * @return Name of the element at the top of the current element * stack, if any. During validation calls it refers to the * element being processed (start or end tag), or its parent * (when processing text nodes), or null (in document prolog * and epilog). */ public QName getCurrentElementName(); /** * Method that can be called by the validator to resolve a namespace * prefix of the currently active top-level element. This may be * necessary for things like DTD validators (which may need to * heuristically guess proper namespace URI of attributes, esp. * ones with default values). */ public String getNamespaceURI(String prefix); /** * This method returns number of attributes accessible from within * currently active start element. *
* Note: this method is only guaranteed to be callable during execution * of {@link XMLValidator} methods * {@link XMLValidator#validateElementStart}, * {@link XMLValidator#validateAttribute} and * {@link XMLValidator#validateElementAndAttributes}. At other times * implementations may choose to allow it to be called (for example, * with information regarding last start element processed), to throw * a {@link IllegalArgumentException}, or to return 0 to indicate no * attribute information is available. *
* Also note that whether defaulted attributes (attributes for which * values are only available via attribute defaulting) are accessible * depends on exact time when this method is called, and in general * can not be assumed to function reliably. * * @return Number of attributes accessible for the currently active * start element. */ public int getAttributeCount(); public String getAttributeLocalName(int index); public String getAttributeNamespace(int index); public String getAttributePrefix(int index); public String getAttributeValue(int index); public String getAttributeValue(String nsURI, String localName); public String getAttributeType(int index); /** * @return Index of the specified attribute, if one present; * -1 otherwise. */ public int findAttributeIndex(String nsURI, String localName); /* /////////////////////////////////////////////////////////////////////// // Access to notation and unparsed entity information /////////////////////////////////////////////////////////////////////// */ /** * @return True, if a notation with specified name has been declared * in the document being validated; false if not. */ public boolean isNotationDeclared(String name); /** * @return True, if an unparsed entity with specified name has * been declared * in the document being validated; false if not. */ public boolean isUnparsedEntityDeclared(String name); /* /////////////////////////////////////////////////////////////////////// // Location information, error reporting ////////////////////////////////////////////////////// */ /** * @return Base URI active in the current location of the document * being validated, if known; null to indicate no base URI known. */ public String getBaseUri(); /** * Method that will return the location that best represents current * location within document to be validated, if such information * is available. *
* Note: it is likely that even when a location is known, it may not * be very accurate; for example, when attributes are validated, it * is possible that they all would point to a single location that * may point to the start of the element that contains attributes. */ public Location getValidationLocation(); /** * Method called by the validator, upon encountering a validation * problem. Implementations are encouraged to allow an optional * {@link ValidationProblemHandler} be set by the application, * to define handling. *
* Note: Stax2 version 2 only allowed throwing instances * of {@link XMLValidationProblem}; version 3 allows generic * base class to be thrown, to support other interfaces such * as basic Stax interface {@link javax.xml.stream.XMLReporter}. */ public void reportProblem(XMLValidationProblem problem) throws XMLStreamException; /* /////////////////////////////////////////////////////////////////////// // Infoset modifiers /////////////////////////////////////////////////////////////////////// */ /** * An optional method that can be used to add a new attribute value for * an attribute * that was not yet contained by the container, as part of using attribute * default value mechanism. Optional here means that it is possible that * no operation is actually done by the context object. This would be * the case, for example, when validation is done on the writer side: * since default attributes are implied by a DTD, they should not be * added to the output. *
* Note: caller has to ensure that the addition would not introduce a * duplicate; attribute container implementation is not required to do * any validation on attribute name (local name, prefix, uri) or value. * * @return Index of the newly added attribute, if operation was * succesful; -1 if not. */ public int addDefaultAttribute(String localName, String uri, String prefix, String value); } stax2-3.1.1/src/java/org/codehaus/stax2/validation/ValidationProblemHandler.java 100644 0 0 1555 11520453235 24753 0 ustar 0 0 package org.codehaus.stax2.validation; /** * This interface defines method(s) needed to implement a custom validation * problem (warning, error, fatal error) handler. Such handlers can be used, * for example, to collect validation problems without automatically * throwing exceptions. It can also be used to throw exception for problems * that by default would only be reported as warnings. */ public interface ValidationProblemHandler { /** * Method called by validator, when a validation problem is encountered. * Impementations can choose to ignore the problem, log something about * the problem, store it for later processing, or throw * a {@link XMLValidationException}. * * @param problem Validation problem encountered. */ public void reportProblem(XMLValidationProblem problem) throws XMLValidationException; } stax2-3.1.1/src/java/org/codehaus/stax2/validation/ValidatorPair.java 100644 0 0 21461 11520453235 22621 0 ustar 0 0 package org.codehaus.stax2.validation; import javax.xml.stream.XMLStreamException; /** * Simple utility class that allows chaining of {@link XMLValidator} * instances. Since the class itself implements {@link XMLValidator}, * multiple validators can be added by chaining these pairs; ordering * of validator calls depends on ordering of the pairs. *
* Default semantics are quite simple: first validator of the pair is * always called first, and results as/if modified by that validator * are passed on to the second validator. *
* It is expected that this class is mostly used by actual stream reader * and writer implementations; not so much by validator implementations. */ public class ValidatorPair extends XMLValidator { public final static String ATTR_TYPE_DEFAULT = "CDATA"; protected XMLValidator mFirst, mSecond; /* //////////////////////////////////////////////////// // Life-cycle //////////////////////////////////////////////////// */ public ValidatorPair(XMLValidator first, XMLValidator second) { mFirst = first; mSecond = second; } /* //////////////////////////////////////////////////// // XMLValidator implementation //////////////////////////////////////////////////// */ /** * Two choices here; could either return schema of the first child, * or return null. Let's do latter, do avoid accidental matches. */ public XMLValidationSchema getSchema() { return null; } public void validateElementStart(String localName, String uri, String prefix) throws XMLStreamException { mFirst.validateElementStart(localName, uri, prefix); mSecond.validateElementStart(localName, uri, prefix); } public String validateAttribute(String localName, String uri, String prefix, String value) throws XMLStreamException { String retVal = mFirst.validateAttribute(localName, uri, prefix, value); if (retVal != null) { value = retVal; } return mSecond.validateAttribute(localName, uri, prefix, value); } public String validateAttribute(String localName, String uri, String prefix, char[] valueChars, int valueStart, int valueEnd) throws XMLStreamException { String retVal = mFirst.validateAttribute(localName, uri, prefix, valueChars, valueStart, valueEnd); /* If it got normalized, let's pass normalized value to the second * validator */ if (retVal != null) { return mSecond.validateAttribute(localName, uri, prefix, retVal); } // Otherwise the original return mSecond.validateAttribute(localName, uri, prefix, valueChars, valueStart, valueEnd); } public int validateElementAndAttributes() throws XMLStreamException { int textType1 = mFirst.validateElementAndAttributes(); int textType2 = mSecond.validateElementAndAttributes(); /* Here, let's choose the stricter (more restrictive) of the two. * Since constants are order from strictest to most lenient, * we'll just take smaller of values */ return (textType1 < textType2) ? textType1 : textType2; } public int validateElementEnd(String localName, String uri, String prefix) throws XMLStreamException { int textType1 = mFirst.validateElementEnd(localName, uri, prefix); int textType2 = mSecond.validateElementEnd(localName, uri, prefix); // As with earlier, let's return stricter of the two return (textType1 < textType2) ? textType1 : textType2; } public void validateText(String text, boolean lastTextSegment) throws XMLStreamException { mFirst.validateText(text, lastTextSegment); mSecond.validateText(text, lastTextSegment); } public void validateText(char[] cbuf, int textStart, int textEnd, boolean lastTextSegment) throws XMLStreamException { mFirst.validateText(cbuf, textStart, textEnd, lastTextSegment); mSecond.validateText(cbuf, textStart, textEnd, lastTextSegment); } public void validationCompleted(boolean eod) throws XMLStreamException { mFirst.validationCompleted(eod); mSecond.validationCompleted(eod); } /* /////////////////////////////////////////////////// // Access to post-validation data (type info) /////////////////////////////////////////////////// */ public String getAttributeType(int index) { String type = mFirst.getAttributeType(index); /* Hmmh. Which heuristic to use here: obviously no answer (null or * empty) is not useful. But what about the default type (CDATA)? * We can probably find a more explicit type? */ if (type == null || type.length() == 0 || type.equals(ATTR_TYPE_DEFAULT)) { String type2 = mSecond.getAttributeType(index); if (type2 != null && type2.length() > 0) { return type2; } } return type; } public int getIdAttrIndex() { int index = mFirst.getIdAttrIndex(); if (index < 0) { return mSecond.getIdAttrIndex(); } return index; } public int getNotationAttrIndex() { int index = mFirst.getNotationAttrIndex(); if (index < 0) { return mSecond.getNotationAttrIndex(); } return index; } /* //////////////////////////////////////////////////// // Additional API used by Woodstox core //////////////////////////////////////////////////// */ public static boolean removeValidator(XMLValidator root, XMLValidationSchema schema, XMLValidator[] results) { if (root instanceof ValidatorPair) { return ((ValidatorPair) root).doRemoveValidator(schema, results); } else { if (root.getSchema() == schema) { results[0] = root; results[1] = null; return true; } } return false; } public static boolean removeValidator(XMLValidator root, XMLValidator vld, XMLValidator[] results) { if (root == vld) { // single validator? results[0] = root; results[1] = null; return true; } else if (root instanceof ValidatorPair) { return ((ValidatorPair) root).doRemoveValidator(vld, results); } return false; } private boolean doRemoveValidator(XMLValidationSchema schema, XMLValidator[] results) { if (removeValidator(mFirst, schema, results)) { XMLValidator newFirst = results[1]; if (newFirst == null) { // removed first (was leaf) -> remove this pair results[1] = mSecond; } else { mFirst = newFirst; // two may be the same, need not be results[1] = this; } return true; } if (removeValidator(mSecond, schema, results)) { XMLValidator newSecond = results[1]; if (newSecond == null) { // removed second (was leaf) -> remove this pair results[1] = mFirst; } else { mSecond = newSecond; // two may be the same, need not be results[1] = this; // will still have this pair } return true; } return false; } private boolean doRemoveValidator(XMLValidator vld, XMLValidator[] results) { if (removeValidator(mFirst, vld, results)) { XMLValidator newFirst = results[1]; if (newFirst == null) { // removed first (was leaf) -> remove this pair results[1] = mSecond; } else { mFirst = newFirst; // two may be the same, need not be results[1] = this; } return true; } if (removeValidator(mSecond, vld, results)) { XMLValidator newSecond = results[1]; if (newSecond == null) { // removed second (was leaf) -> remove this pair results[1] = mFirst; } else { mSecond = newSecond; // two may be the same, need not be results[1] = this; // will still have this pair } return true; } return false; } /* //////////////////////////////////////////////////// // Internal methods //////////////////////////////////////////////////// */ } stax2-3.1.1/src/java/org/codehaus/stax2/validation/XMLValidationException.java 100644 0 0 4646 11520453235 24400 0 ustar 0 0 package org.codehaus.stax2.validation; import javax.xml.stream.Location; import javax.xml.stream.XMLStreamException; /** * Specialized sub-class of {@link XMLStreamException}, to be used for * indicating fatal validation problems (when in mode in which exceptions * are to be thrown). *
* Note: constructors are protected, since direct instantiation should * be done using factory methods. Reason for this is that the base * {@link XMLStreamException} has less than robust handling of optional * arguments, and thus factory methods of this class can take care to * choose appropriate constructors to call, to make sure super-class does * not barf (NPE or such). */ public class XMLValidationException extends XMLStreamException { private static final long serialVersionUID = 1L; protected XMLValidationProblem mCause; // // Constructors are protected; sub-classes need to know what // // they are doing protected XMLValidationException(XMLValidationProblem cause) { super(); if (cause == null) { throwMissing(); } mCause = cause; } protected XMLValidationException(XMLValidationProblem cause, String msg) { super(msg); if (cause == null) { throwMissing(); } mCause = cause; } protected XMLValidationException(XMLValidationProblem cause, String msg, Location loc) { super(msg, loc); if (cause == null) { throwMissing(); } mCause = cause; } // // // Factory methods public static XMLValidationException createException(XMLValidationProblem cause) { String msg = cause.getMessage(); if (msg == null) { return new XMLValidationException(cause); } Location loc = cause.getLocation(); if (loc == null) { return new XMLValidationException(cause, msg); } return new XMLValidationException(cause, msg, loc); } // // // Accessors /** * @return Object that has all information about details of the * validation problem */ public XMLValidationProblem getValidationProblem() { return mCause; } // // // Internal protected static void throwMissing() throws RuntimeException { throw new IllegalArgumentException("Validation problem argument can not be null"); } } stax2-3.1.1/src/java/org/codehaus/stax2/validation/XMLValidationProblem.java 100644 0 0 6060 11520453235 24032 0 ustar 0 0 package org.codehaus.stax2.validation; import javax.xml.stream.Location; /** * Simple container class used to store a non-fatal problem * either to be returned as is, or to use for creating and throwing * a validation exception. */ public class XMLValidationProblem { public final static int SEVERITY_WARNING = 1; public final static int SEVERITY_ERROR = 2; public final static int SEVERITY_FATAL = 3; /** * Location within validated xml stream where the problem occured. */ protected Location mLocation; protected final String mMessage; protected final int mSeverity; /** * Type of the problem, available types implementation specified. * * @since 3.0 */ protected String mType; /** * Validator instance that reported the problem, if any (may be * null if stream reader or writer itself reported the problem) * * @since 3.0 */ protected XMLValidator mReporter; public XMLValidationProblem(Location loc, String msg) { this(loc, msg, SEVERITY_ERROR); } public XMLValidationProblem(Location loc, String msg, int severity) { this(loc, msg, severity, null); } public XMLValidationProblem(Location loc, String msg, int severity, String type) { mLocation = loc; mMessage = msg; mSeverity = severity; mType = type; } /** * Convenience method for constructing a {@link XMLValidationException} * to throw based on information contained in this object. * Base implementation is equivalent to: *
* return XMLValidationException.createException(this); ** * @since 3.0 */ public XMLValidationException toException() { return XMLValidationException.createException(this); } /** * @since 3.0 */ public void setType(String t) { mType = t; } /** * @since 3.0 */ public void setLocation(Location l) { mLocation = l; } /** * Set the validator object that reported this problem, if known. * * @since 3.0 */ public void setReporter(XMLValidator v) { mReporter = v; } /** * @return Reference to location where problem was encountered. */ public Location getLocation() { return mLocation; } /** * @return Human-readable message describing the problem */ public String getMessage() { return mMessage; } /** * @return One of
SEVERITY_
constants
* (such as {@link #SEVERITY_WARNING}
*/
public int getSeverity() { return mSeverity; }
/**
* @return Generic type (class) of the problem; may be null
* if validator does not provide such details
*
* @since 3.0
*/
public String getType() { return mType; }
/**
* Returns the validator that reported the problem if known.
*
* @return Validator that reported the problem; null if unknown or N/A.
*
* @since 3.0
*/
public XMLValidator getReporter() { return mReporter; }
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/XMLValidationSchema.java 100644 0 0 4062 11520453235 23632 0 ustar 0 0 package org.codehaus.stax2.validation;
import javax.xml.stream.XMLStreamException;
/**
* Defines the API that validator schema instances have to implement. Schema
* objects are results of parsing of input that defines validation rules;
* things like DTD files, W3c Schema input documents and so on. Schema
* instances can not be directly used for validation; they are blueprints
* for constructing such validator Objects. Because of this, they are
* also guaranteed to be thread-safe and reusable. One way to think of this
* is that schemas are actual validator factories instead of
* {@link XMLValidationSchemaFactory} instances.
** One note about creation of validator instances: since the validation * may be invoked from wide variety of contexts (from parser, from serializer, * from processing pipeline etc), the validation context is abstracted * as {@link ValidationContext}. Instances may make use of additional * knowledge about actual implementing classes if they can safely determine * the type runtime, but should gracefully handle the cases where * the context is created by a caller that is not part of the same * StAX implementation as the validator. */ public interface XMLValidationSchema { // // // Constants defining standard Schema types: public final static String SCHEMA_ID_DTD = "http://www.w3.org/XML/1998/namespace"; public final static String SCHEMA_ID_RELAXNG = "http://relaxng.org/ns/structure/0.9"; public final static String SCHEMA_ID_W3C_SCHEMA = "http://www.w3.org/2001/XMLSchema"; public final static String SCHEMA_ID_TREX = "http://www.thaiopensource.com/trex"; public XMLValidator createValidator(ValidationContext ctxt) throws XMLStreamException; /* /////////////////////////////////////////////////// // Configuration, properties /////////////////////////////////////////////////// */ /** * Returns type of this schema. * * @return One of external schema identifier values (such as * {@link #SCHEMA_ID_DTD}). */ public String getSchemaType(); } stax2-3.1.1/src/java/org/codehaus/stax2/validation/XMLValidationSchemaFactory.java 100644 0 0 27124 11520453235 25206 0 ustar 0 0 package org.codehaus.stax2.validation; import java.io.*; import java.net.URL; import java.util.*; import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.XMLStreamException; /** * Defines an abstract factory for constructing {@link XMLValidationSchema} * instances. This abstract base class has methods for instantiating the * actual implementation (similar to the way * {@link javax.xml.stream.XMLInputFactory} works, and defines the API to * use for configuring these instances, as well as factory methods concrete * classes implement for actually creating {@link XMLValidationSchema} * instances. *
* Note: this class is part of the second major revision of StAX 2 API * (StAX2, v2), and is optional for StAX2 implementations to support. * * @see javax.xml.stream.XMLInputFactory * @see org.codehaus.stax2.validation.XMLValidationSchema * @see org.codehaus.stax2.XMLInputFactory2 */ public abstract class XMLValidationSchemaFactory { // // // Internal ids matching SCHEMA_ID_ constants from XMLValidationSchema public final static String INTERNAL_ID_SCHEMA_DTD = "dtd"; public final static String INTERNAL_ID_SCHEMA_RELAXNG = "relaxng"; public final static String INTERNAL_ID_SCHEMA_W3C = "w3c"; public final static String INTERNAL_ID_SCHEMA_TREX = "trex"; final static HashMap sSchemaIds = new HashMap(); static { sSchemaIds.put(XMLValidationSchema.SCHEMA_ID_DTD, INTERNAL_ID_SCHEMA_DTD); sSchemaIds.put(XMLValidationSchema.SCHEMA_ID_RELAXNG, INTERNAL_ID_SCHEMA_RELAXNG); sSchemaIds.put(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA, INTERNAL_ID_SCHEMA_W3C); sSchemaIds.put(XMLValidationSchema.SCHEMA_ID_TREX, INTERNAL_ID_SCHEMA_TREX); } // // // Properties for locating implementations /** * Name of resource file that contains JAXP properties. */ final static String JAXP_PROP_FILENAME = "jaxp.properties"; /** * Defines the system property that can be set to explicitly specify * which implementation to use (in case there are multiple StAX2 * implementations; or the one used does not specify other mechanisms * for the loader to find the implementation class). */ public final static String SYSTEM_PROPERTY_FOR_IMPL = "org.codehaus.stax2.validation.XMLValidationSchemaFactory."; /** * Path to resource that should contain implementation class definition. */ public final static String SERVICE_DEFINITION_PATH = "META-INF/services/" + SYSTEM_PROPERTY_FOR_IMPL; // // // Names of standard configuration properties /** * Property that determines whether schemas constructed are namespace-aware, * in cases where schema supports both namespace-aware and non-namespace * aware modes. In general this only applies to DTDs, since namespace * support for DTDs is both optional, and not well specified. *
* Default value is TRUE. For schema types for which only one value
* (usually TRUE) is allowed, this property will be ignored.
*/
public static final String P_IS_NAMESPACE_AWARE = "org.codehaus2.stax2.validation.isNamespaceAware";
/**
* Property that determines whether schema instances created by this
* factory instance can be cached by the factory; if false, no caching
* is allowed to be doe; if true, factory can do caching if it wants to.
* The exact rules used to determine unique id of schema instances is
* factory dependant; it is expected that the implementations use
* implementation based on unified system ids (serialized URLs or such).
*/
public static final String P_ENABLE_CACHING = "org.codehaus2.stax2.validation.enableCaching";
/**
* Schema type this factory instance supports.
*/
protected final String mSchemaType;
/**
* @param st Schema type this factory supports; one of
* SCHEMA_ID_xxx
constants.
*/
protected XMLValidationSchemaFactory(String st)
{
mSchemaType = st;
}
/*
////////////////////////////////////////////////////////
// Factory methods
////////////////////////////////////////////////////////
*/
// // // First creating the factory instances:
/**
* Creates a new XMLValidationFactory instance, using the default
* instance configuration mechanism.
*/
public static XMLValidationSchemaFactory newInstance(String schemaType)
throws FactoryConfigurationError
{
return newInstance(schemaType,
Thread.currentThread().getContextClassLoader());
}
public static XMLValidationSchemaFactory newInstance(String schemaType, ClassLoader classLoader)
throws FactoryConfigurationError
{
/* First, let's check and map schema type to the shorter internal
* id:
*/
String internalId = (String) sSchemaIds.get(schemaType);
if (internalId == null) {
throw new FactoryConfigurationError("Unrecognized schema type (id '"+schemaType+"')");
}
String propertyId = SYSTEM_PROPERTY_FOR_IMPL + internalId;
SecurityException secEx = null;
/* First, let's see if there's a system property (overrides other
* settings)
*/
try {
String clsName = System.getProperty(propertyId);
if (clsName != null && clsName.length() > 0) {
return createNewInstance(classLoader, clsName);
}
} catch (SecurityException se) {
// May happen on sandbox envs, like applets?
secEx = se;
}
/* try to read from $java.home/lib/xml.properties (simulating
* the way XMLInputFactory does this... not sure if this should
* be done, as this is not [yet?] really jaxp specified)
*/
try {
String home = System.getProperty("java.home");
File f = new File(home);
// Let's not hard-code separators...
f = new File(f, "lib");
f = new File(f, JAXP_PROP_FILENAME);
if (f.exists()) {
try {
Properties props = new Properties();
props.load(new FileInputStream(f));
String clsName = props.getProperty(propertyId);
if (clsName != null && clsName.length() > 0) {
return createNewInstance(classLoader, clsName);
}
} catch (IOException ioe) {
// can also happen quite easily...
}
}
} catch (SecurityException se) {
// Fine, as above
secEx = se;
}
/* Ok, no match; how about a service def from the impl jar?
*/
// try to find services in CLASSPATH
String path = SERVICE_DEFINITION_PATH + internalId;
try {
Enumeration en;
if (classLoader == null) {
en = ClassLoader.getSystemResources(path);
} else {
en = classLoader.getResources(path);
}
if (en != null) {
while (en.hasMoreElements()) {
URL url = (URL) en.nextElement();
InputStream is = url.openStream();
BufferedReader rd =
new BufferedReader(new InputStreamReader(is, "ISO-8859-1"));
String clsName = null;
String line;
try {
while ((line = rd.readLine()) != null) {
line = line.trim();
if (line.length() > 0 && line.charAt(0) != '#') {
clsName = line;
break;
}
}
} finally {
rd.close();
}
if (clsName != null && clsName.length() > 0) {
return createNewInstance(classLoader, clsName);
}
}
}
} catch (SecurityException se) {
secEx = se;
} catch (IOException ex) {
/* Let's assume these are mostly ok, too (missing jar ie.)
*/
}
String msg = "No XMLValidationSchemaFactory implementation class specified or accessible (via system property '"
+propertyId+"', or service definition under '"+path+"')";
if (secEx != null) {
throw new FactoryConfigurationError(msg + " (possibly caused by: "+secEx+")", secEx);
}
throw new FactoryConfigurationError(msg);
}
// // // And then actual per-instance factory methods
public XMLValidationSchema createSchema(InputStream in)
throws XMLStreamException
{
return createSchema(in, null);
}
public XMLValidationSchema createSchema(InputStream in, String encoding)
throws XMLStreamException
{
return createSchema(in, encoding, null, null);
}
public abstract XMLValidationSchema createSchema(InputStream in, String encoding,
String publicId, String systemId)
throws XMLStreamException;
public XMLValidationSchema createSchema(Reader r)
throws XMLStreamException
{
return createSchema(r, null, null);
}
public abstract XMLValidationSchema createSchema(Reader r, String publicId,
String systemId)
throws XMLStreamException;
public abstract XMLValidationSchema createSchema(URL url)
throws XMLStreamException;
public abstract XMLValidationSchema createSchema(File f)
throws XMLStreamException;
/*
////////////////////////////////////////////////////////
// Configuration
////////////////////////////////////////////////////////
*/
public abstract boolean isPropertySupported(String propName);
/**
* @param propName Name of property to set
* @param value Value to set property to
*
* @return True if setting succeeded; false if property was recognized
* but could not be changed to specified value, or if it was not
* recognized but the implementation did not throw an exception.
*/
public abstract boolean setProperty(String propName, Object value);
public abstract Object getProperty(String propName);
/**
* @return Name of schema type (one of SCHEMA_ID_xxx
* constants) that this factory supports.
*/
public final String getSchemaType() { return mSchemaType; }
/*
///////////////////////////////////////////////////////
// Internal methods
///////////////////////////////////////////////////////
*/
private static XMLValidationSchemaFactory createNewInstance(ClassLoader cloader, String clsName)
throws FactoryConfigurationError
{
try {
Class factoryClass;
if (cloader == null) {
factoryClass = Class.forName(clsName);
} else {
factoryClass = cloader.loadClass(clsName);
}
return (XMLValidationSchemaFactory) factoryClass.newInstance();
} catch (ClassNotFoundException x) {
throw new FactoryConfigurationError
("XMLValidationSchemaFactory implementation '"+clsName+"' not found (missing jar in classpath?)", x);
} catch (Exception x) {
throw new FactoryConfigurationError
("XMLValidationSchemaFactory implementation '"+clsName+"' could not be instantiated: "+x, x);
}
}
}
stax2-3.1.1/src/java/org/codehaus/stax2/validation/XMLValidator.java 100644 0 0 27346 11520453235 22376 0 ustar 0 0 package org.codehaus.stax2.validation;
import javax.xml.stream.XMLStreamException;
/**
* Class that defines interface that individual (possibly) stateful validator
* instances have to implement, and that both
* {@link javax.xml.stream.XMLStreamReader} and
* {@link javax.xml.stream.XMLStreamWriter} instances can call to validate
* xml documents.
*
* Validator instances are created from and by non-stateful * {@link XMLValidationSchema} instances. A new validator instance has to * be created for each document read or written, ie. can not be shared * or reused, unlike schema instances which can be. */ public abstract class XMLValidator { // // // Shared constants /* First, constants used by validators to indicate kind of pre-validation * (with respect to text, and in some cases, other non-element events) * caller needs to take, before calling the validator. The idea is to * allow stream readers and writers to do parts of validity checks they * are in best position to do, while leaving the real structural and * content-based validation to validators. */ /** * This value indicates that no content whatsoever * is legal within current context, that is, where the only legal content * to follow is the closing end tag -- not even comments or processing * instructions are allowed. This is the case for example for * elements that DTD defines to have EMPTY content model. *
*/ public final static int CONTENT_ALLOW_NONE = 0; /** * This value indicates that only white space text content is allowed, * not other kinds of text. Other non-text events may be allowed; * validator will deal with element validation. * Value also indicates that if non-white space text content is * encountered, a validation problem is reported */ public final static int CONTENT_ALLOW_WS = 1; /** * This value is similar to {@link #CONTENT_ALLOW_WS_NONSTRICT}, * but only used for content typing purposes, not for validation. * This means that if non-white space text content is encountered, * no problem is reported. *
* This value is currently only used with DTD processors, when in
* typing (non-validating) mode.
*
* @since 3.0
*/
public final static int CONTENT_ALLOW_WS_NONSTRICT = 2;
/**
* This value indicates that textual content is allowed, but that
* the validator needs to be called to let it do actual content-based
* validation. Other event types are ok, and elements will need to be
* validated by the validator as well.
*/
public final static int CONTENT_ALLOW_VALIDATABLE_TEXT = 3;
/**
* This value indicates that any textual content (plain PCTEXT) is
* allowed, and that validator is not going to do any validation
* for it. It will, however, need to be called with respect
* to element events.
*/
public final static int CONTENT_ALLOW_ANY_TEXT = 4;
/**
* This value is a placeholder that should never be returned by
* validators, but that can be used internally as an uninitialized
* value.
*/
public final static int CONTENT_ALLOW_UNDEFINED = 5;
/*
///////////////////////////////////////////////////
// Life-cycle
///////////////////////////////////////////////////
*/
protected XMLValidator() { }
/*
///////////////////////////////////////////////////
// Configuration, properties
///////////////////////////////////////////////////
*/
/**
* Returns type of schema that was used to construct this
* validator instance.
*
* @return One of external schema identifier values (such as
* {@link XMLValidationSchema#SCHEMA_ID_DTD}).
*/
public String getSchemaType() {
XMLValidationSchema sch = getSchema();
return (sch == null) ? null : sch.getSchemaType();
}
/**
* Returns the schema instance that created this validator
* object, if known (and applicable). May return null for
* some instances: specifically, {@link ValidatorPair}
* will return null since it 'contains' multiple validators
* and generally does not have just one parent or owner schema.
*/
public abstract XMLValidationSchema getSchema();
/*
///////////////////////////////////////////////////
// Actual validation interface
///////////////////////////////////////////////////
*/
public abstract void validateElementStart(String localName, String uri,
String prefix)
throws XMLStreamException;
/**
* Callback method called on validator to give it a chance to validate
* the value of an attribute, as well as to normalize its value if
* appropriate (remove leading/trailing/intervening white space for
* certain token types etc.).
*
* @return Null, if the passed value is fine as is; or a String, if
* it needs to be replaced. In latter case, caller will replace the
* value before passing it to other validators. Also, if the attribute
* value is accessible via caller (as is the case for stream readers),
* caller should return this value, instead of the original one.
*/
public abstract String validateAttribute(String localName, String uri,
String prefix, String value)
throws XMLStreamException;
/**
* Callback method called on validator to give it a chance to validate
* the value of an attribute, as well as to normalize its value if
* appropriate (remove leading/trailing/intervening white space for
* certain token types etc.).
*
* @param valueChars Character array that contains value (possibly
* along with some other text)
* @param valueStart Index of the first character of the value in
* in valueChars
array
* @param valueEnd Index of the character AFTER the last character;
* so that the length of the value String is
* valueEnd - valueStart
*
* @return Null, if the passed value is fine as is; or a String, if
* it needs to be replaced. In latter case, caller will replace the
* value before passing it to other validators. Also, if the attribute
* value is accessible via caller (as is the case for stream readers),
* caller should return this value, instead of the original one.
*/
public abstract String validateAttribute(String localName, String uri,
String prefix,
char[] valueChars, int valueStart,
int valueEnd)
throws XMLStreamException;
/**
* Method called after calling {@link #validateAttribute} on all
* attributes (if any), but before starting to handle element
* content.
*
* @return One of CONTENT_ALLOW_
constants, to indicate
* what kind of textual content is allowed at the scope returned
* to after the element has closed.
*/
public abstract int validateElementAndAttributes()
throws XMLStreamException;
/**
* Method called right after encountering an element close tag.
*
* @return One of CONTENT_ALLOW_
constants, to indicate
* what kind of textual content is allowed at the scope returned
* to after the element has closed.
*/
public abstract int validateElementEnd(String localName, String uri,
String prefix)
throws XMLStreamException;
/**
* Method called to validate textual content.
*
* Note: this method is only guaranteed to be called when * {@link #validateElementAndAttributes()} for the currently open * element returned {@link #CONTENT_ALLOW_VALIDATABLE_TEXT} (or, * in case of mixed content, {@link #validateElementEnd}, for the * last enclosed element). Otherwise, validator context may choose * not to call the method as an optimization. * * @param text Text content to validate * @param lastTextSegment Whether this text content is the last text * segment before a close element; true if it is, false if it is not, * or no determination can be made. Can be used for optimizing * validation -- if this is true, no text needs to be buffered since * no more will be sent before the current element closes. */ public abstract void validateText(String text, boolean lastTextSegment) throws XMLStreamException; /** * Method called to validate textual content. *
* Note: this method is only guaranteed to be called when
* {@link #validateElementAndAttributes()} for the currently open
* element returned {@link #CONTENT_ALLOW_VALIDATABLE_TEXT} (or,
* in case of mixed content, {@link #validateElementEnd}, for the
* last enclosed element). Otherwise, validator context may choose
* not to call the method as an optimization.
*
* @param cbuf Character array that contains text content to validate
* @param textStart Index of the first character of the content to
* validate
* @param textEnd Character following the last character of the
* content to validate (that is, length of content to validate is
* textEnd - textStart
).
* @param lastTextSegment Whether this text content is the last text
* segment before a close element; true if it is, false if it is not,
* or no determination can be made. Can be used for optimizing
* validation -- if this is true, no text needs to be buffered since
* no more will be sent before the current element closes.
*/
public abstract void validateText(char[] cbuf, int textStart, int textEnd,
boolean lastTextSegment)
throws XMLStreamException;
/**
* Method called when the validation is completed; either due to the
* input stream ending, or due to an explicit 'stop validation' request
* by the application (via context object).
*
* @param eod Flag that indicates whether this method was called by the
* context due to the end of the stream (true); or by an application
* requesting end of validation (false).
*/
public abstract void validationCompleted(boolean eod)
throws XMLStreamException;
/*
///////////////////////////////////////////////////
// Access to post-validation data (type info)
///////////////////////////////////////////////////
*/
/**
* Method for getting schema-specified type of an attribute, if
* information is available. If not, validators can return
* null to explicitly indicate no information was available.
*/
public abstract String getAttributeType(int index);
/**
* Method for finding out the index of the attribute that
* is of type ID; derived from DTD, W4C Schema, or some other validation
* source. Usually schemas explicitly specifies that at most one
* attribute can have this type for any element.
*
* @return Index of the attribute with type ID, in the current
* element, if one exists: -1 otherwise
*/
public abstract int getIdAttrIndex();
/**
* Method for finding out the index of the attribute (collected using
* the attribute collector; having DTD/Schema-derived info in same order)
* that is of type NOTATION. DTD explicitly specifies that at most one
* attribute can have this type for any element.
*
* @return Index of the attribute with type NOTATION, in the current
* element, if one exists: -1 otherwise
*/
public abstract int getNotationAttrIndex();
}