pax_global_header00006660000000000000000000000064132566072030014516gustar00rootroot0000000000000052 comment=8a7068e75ac27db2a9072a09fab8d0dfd2711fcf stax2-api-stax2-api-4.1/000077500000000000000000000000001325660720300150005ustar00rootroot00000000000000stax2-api-stax2-api-4.1/.gitignore000066400000000000000000000002351325660720300167700ustar00rootroot00000000000000# use glob syntax. syntax: glob *.class *~ *.bak *.off *.old .DS_Store # building target # Eclipse .classpath .project .settings # IDEA *.iml *.ipr *.iws stax2-api-stax2-api-4.1/.travis.yml000066400000000000000000000000441325660720300171070ustar00rootroot00000000000000language: java jdk: - oraclejdk7 stax2-api-stax2-api-4.1/README.md000066400000000000000000000027001325660720300162560ustar00rootroot00000000000000# Overview Stax2 API is an extension to standard [Stax](http://en.wikipedia.org/wiki/StAX) API ("STandard Api for Xml procesing"), pull-parser API of JDK, added in JDK 6. ## Status [![Build Status](https://travis-ci.org/FasterXML/stax2-api.svg)](https://travis-ci.org/FasterXML/stax2-api) ## Support Stax2 API is implemented natively by following Stax XML implementations: * [Aalto](../../../aalto-xml) (performance-oriented, also non-blocking/async) * [Woodstox](../../../woodstox) (full-featured, most compliant XML package on Java platform) In addition, Stax2 API contains wrapper implementations that can be used to support most of API on regular Stax implementations like Sun SJSXP (default Stax implementation bundled with JDK 1.6 and 1.7). ## License API is licensed under standard BSD license, which is compatible with all Free and Open Software (OSS) licenses. ## Java package API classes are in package `org.codehaus.stax2`. Stax2 API also contains partial Reference Implementation of many of API classes, under `org.codehaus.stax2.ri`: intention is to make it as painless as possible for Java Stax parser to implement full Stax2 support. ## Usage Maven dependency is defined as: org.codehaus.woodstox stax2-api 3.1.4 Jars can be found from [Central Maven repo](http://repo1.maven.org/maven2/org/codehaus/woodstox/stax2-api/). stax2-api-stax2-api-4.1/pom.xml000066400000000000000000000115201325660720300163140ustar00rootroot00000000000000 4.0.0 com.fasterxml oss-parent 32 org.codehaus.woodstox stax2-api Stax2 API 4.1 bundle tax2 API is an extension to basic Stax 1.0 API that adds significant new functionality, such as full-featured bi-direction validation interface and high-performance Typed Access API. http://github.com/FasterXML/stax2-api fasterxml.com http://fasterxml.com tatu Tatu Saloranta tatu@fasterxml.com The BSD License http://www.opensource.org/licenses/bsd-license.php repo scm:git:git@github.com:FasterXML/stax2-api.git scm:git:git@github.com:FasterXML/stax2-api.git http://github.com/FasterXML/stax2-api stax2-api-4.1 org.codehaus.stax2 maven-compiler-plugin 1.6 1.6 true true true true lines,source org.apache.maven.plugins maven-release-plugin forked-path org.apache.maven.plugins maven-javadoc-plugin 1.6 1.6 UTF-8 https://docs.oracle.com/javase/8/docs/api/ attach-javadocs verify jar org.apache.felix maven-bundle-plugin true ${jdk.module.name} ${project.artifactId} fasterml.com javax.xml.namespace ,javax.xml.stream ,javax.xml.stream.events ,javax.xml.stream.util ,javax.xml.transform ,javax.xml.transform.dom ,org.w3c.dom org.codehaus.stax2 ,org.codehaus.stax2.evt ,org.codehaus.stax2.io ,org.codehaus.stax2.osgi ,org.codehaus.stax2.ri ,org.codehaus.stax2.ri.dom ,org.codehaus.stax2.ri.evt ,org.codehaus.stax2.ri.typed ,org.codehaus.stax2.typed ,org.codehaus.stax2.util ,org.codehaus.stax2.validation stax2-api-stax2-api-4.1/release-notes/000077500000000000000000000000001325660720300175465ustar00rootroot00000000000000stax2-api-stax2-api-4.1/release-notes/VERSION000066400000000000000000000012441325660720300206170ustar00rootroot00000000000000Project: Stax2 API ------------------------------------------------------------------------ = Releases ------------------------------------------------------------------------ 4.1 (not yet released) - Add `Automatic-Module-Name` for Java 9 - Upgrade JDK baseline requirement Java 6 (from Java 5); remove `stax-api` dependency (since bundled on Java 6) 4.0.0: (01-Feb-2015) - Update codebase to Java5 (add generics); minor related cleanup. #3: Add LICENSE file that indicates BSD (2-clause) as the license 3.1.4 (28-Feb-2014) The first version released from github. #2: Stax2EventFactoryImpl.createEndElement() not passing namespace prefix (reported by Jimmy Praet) stax2-api-stax2-api-4.1/src/000077500000000000000000000000001325660720300155675ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/000077500000000000000000000000001325660720300165135ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/000077500000000000000000000000001325660720300174345ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/000077500000000000000000000000001325660720300202235ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/000077500000000000000000000000001325660720300220165ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/000077500000000000000000000000001325660720300230575ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/AttributeInfo.java000066400000000000000000000040601325660720300265010ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/DTDInfo.java000066400000000000000000000034601325660720300251540ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/LocationInfo.java000066400000000000000000000166621325660720300263210ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLEventReader2.java000066400000000000000000000046341325660720300266000ustar00rootroot00000000000000package 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 IllegalArgumentException if the property is not supported * (or recognized) by the stream reader implementation * * @since 3.0 */ public boolean setProperty(String name, Object value); } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLInputFactory2.java000066400000000000000000000352211325660720300270170ustar00rootroot00000000000000package 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: *

* All the other standard settings should be left as is. *

* 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: *

* All the other standard settings should be left as is. *

* 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: *

* All the other standard settings should be left as is. *

* 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: *

* All the other standard settings should be left as is. *

* 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: *

* All the other standard settings should be left as is. *

* In addition, implementations should set implementation-dependant * settings appropriately as well. */ public abstract void configureForRoundTripping(); } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLOutputFactory2.java000066400000000000000000000175161325660720300272270ustar00rootroot00000000000000package 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: *

* * @version 3.0 01/21/2007 * @author Tatu Saloranta (tatu.saloranta@iki.fi) */ public abstract class XMLOutputFactory2 extends XMLOutputFactory 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_NAMESPACE_AWARE //public final static String XSP_PROBLEM_REPORTER /* /////////////////////////////////////////////////////////// // Additional standard configuration properties /////////////////////////////////////////////////////////// */ // // General output options: /** * Whether stream writers are allowed to automatically output empty * elements, when a start element is immediately followed by matching * end element. * If true, will output empty elements; if false, will always create * separate end element (unless a specific method that produces empty * elements is called). *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLReporter2.java000066400000000000000000000026771325660720300262030ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLStreamLocation2.java000066400000000000000000000027411325660720300273150ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLStreamProperties.java000066400000000000000000000124241325660720300276160ustar00rootroot00000000000000package 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 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. *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLStreamReader2.java000066400000000000000000000320341325660720300267450ustar00rootroot00000000000000/* 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: *

*
FEATURE_DTD_OVERRIDE: (write-only)
*
Feature used to specify the source for DTD external subset to use * instead of DTD specified by the XML document itself (if any). * Setting the feature for a reader that supports DTD validation * essentially allows for injecting an alternate DOCTYPE declaration. * Note that setting this value to null is both legal, and sometimes * useful: it is equivalent of removing the DOCTYPE declaration. *
Feature is write-only, since storing it after loading the DTD * in question does not have much use. *
*
*

* 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. */ @Deprecated 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 IllegalArgumentException 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 */ @Deprecated 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. */ @Deprecated 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 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. *

* 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 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#close}, * 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/XMLStreamWriter2.java000066400000000000000000000226171325660720300270250ustar00rootroot00000000000000package 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). *

* 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 IllegalArgumentException 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): *

*/ 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). *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/evt/000077500000000000000000000000001325660720300236555ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/evt/DTD2.java000066400000000000000000000006471325660720300252240ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/evt/NotationDeclaration2.java000066400000000000000000000005341325660720300305450ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/evt/XMLEvent2.java000066400000000000000000000012121325660720300262400ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/evt/XMLEventFactory2.java000066400000000000000000000012211325660720300275700ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/000077500000000000000000000000001325660720300234665ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/EscapingWriterFactory.java000066400000000000000000000044361325660720300306160ustar00rootroot00000000000000package 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 * 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2BlockResult.java000066400000000000000000000017251325660720300275110ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override public abstract Writer constructWriter() throws IOException; @Override public abstract OutputStream constructOutputStream() throws IOException; } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2BlockSource.java000066400000000000000000000024021325660720300274640ustar00rootroot00000000000000package 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. */ @Override public URL getReference() { return null; } @Override public abstract Reader constructReader() throws IOException; @Override public abstract InputStream constructInputStream() throws IOException; } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2ByteArraySource.java000066400000000000000000000041701325660720300303400ustar00rootroot00000000000000package org.codehaus.stax2.io; import java.io.*; /** * Simple implementation of {@link Stax2BlockSource} that encapsulates * a byte 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 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. */ @Override 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); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2CharArraySource.java000066400000000000000000000032321325660720300303100ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override public Reader constructReader() throws IOException { return new CharArrayReader(mBuffer, mStart, mLength); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2FileResult.java000066400000000000000000000022101325660720300273240ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override 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); } @Override public OutputStream constructOutputStream() throws IOException { return new FileOutputStream(mFile); } /* ///////////////////////////////////////// // Additional API for this Result ///////////////////////////////////////// */ public File getFile() { return mFile; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2FileSource.java000066400000000000000000000041701325660720300273150ustar00rootroot00000000000000package 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 _file; public Stax2FileSource(File f) { _file = 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. */ @Override 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 _file.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 '"+_file.getPath()+"' to URL: "+e); } } @Override 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(_file); } @Override public InputStream constructInputStream() throws IOException { return new FileInputStream(_file); } /* /********************************************************************** /* Additional API for this source /********************************************************************** */ public File getFile() { return _file; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2ReferentialResult.java000066400000000000000000000012651325660720300307160ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override public abstract Writer constructWriter() throws IOException; @Override public abstract OutputStream constructOutputStream() throws IOException; } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2ReferentialSource.java000066400000000000000000000030111325660720300306670ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override public abstract URL getReference(); @Override public abstract Reader constructReader() throws IOException; @Override public abstract InputStream constructInputStream() throws IOException; /* ///////////////////////////////////////// // Overrides ///////////////////////////////////////// */ /** * Since we can determine a system id from the base URL */ @Override public String getSystemId() { String sysId = super.getSystemId(); if (sysId == null) { sysId = getReference().toExternalForm(); } return sysId; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2Result.java000066400000000000000000000057421325660720300265410ustar00rootroot00000000000000package 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: *

*/ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2Source.java000066400000000000000000000063731325660720300265240ustar00rootroot00000000000000package 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. *

* 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: *

*/ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2StringSource.java000066400000000000000000000020321325660720300276770ustar00rootroot00000000000000package 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 ///////////////////////////////////////// */ @Override public Reader constructReader() throws IOException { return new StringReader(mText); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/io/Stax2URLSource.java000066400000000000000000000026771325660720300271120ustar00rootroot00000000000000package 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. */ @Override public URL getReference() { return mURL; } @Override 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()); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/osgi/000077500000000000000000000000001325660720300240205ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/osgi/Stax2InputFactoryProvider.java000066400000000000000000000037461325660720300317610ustar00rootroot00000000000000package 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. *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/osgi/Stax2OutputFactoryProvider.java000066400000000000000000000037561325660720300321630ustar00rootroot00000000000000package 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(); } Stax2ValidationSchemaFactoryProvider.java000066400000000000000000000062261325660720300340120ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/osgipackage 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/000077500000000000000000000000001325660720300234715ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/EmptyIterator.java000066400000000000000000000014231325660720300271440ustar00rootroot00000000000000package 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 Iterator sInstance = new EmptyIterator(); private EmptyIterator() { } @SuppressWarnings("unchecked") public static Iterator getInstance() { return (Iterator) 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/EmptyNamespaceContext.java000066400000000000000000000052201325660720300306130ustar00rootroot00000000000000package 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 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 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 SingletonIterator.create(XMLConstants.XML_NS_PREFIX); } if (nsURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) { return SingletonIterator.create(XMLConstants.XMLNS_ATTRIBUTE); } return EmptyIterator.getInstance(); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/SingletonIterator.java000066400000000000000000000016411325660720300300120ustar00rootroot00000000000000package 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 T _value; private boolean _done = false; @Deprecated // since 4.0; use SingletonIterator.create() instead public SingletonIterator(T value) { _value = value; } public static SingletonIterator create(T value) { return new SingletonIterator(value); } public boolean hasNext() { return !_done; } public T next() { if (_done) { throw new java.util.NoSuchElementException(); } _done = true; return _value; } public void remove() { throw new UnsupportedOperationException("Can not remove item from SingletonIterator."); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2EventFactoryImpl.java000066400000000000000000000170101325660720300305100ustar00rootroot00000000000000package 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 createQName * methods. *

* Note that due to underlying Stax factory being non-generic (it was specified * for JDK 1.4, pre-generic), no generic typing can be added to various * {@link java.util.Iterator}s in signatures. * * @author Tatu Saloranta * * @since 3.0 */ public abstract class Stax2EventFactoryImpl extends XMLEventFactory2 { protected Location mLocation; public Stax2EventFactoryImpl() { } /* /********************************************************************** /* XMLEventFactory API /********************************************************************** */ @Override public Attribute createAttribute(QName name, String value) { return new AttributeEventImpl(mLocation, name, value, true); } @Override public Attribute createAttribute(String localName, String value) { return new AttributeEventImpl(mLocation, localName, null, null, value, true); } @Override public Attribute createAttribute(String prefix, String nsURI, String localName, String value) { return new AttributeEventImpl(mLocation, localName, nsURI, prefix, value, true); } @Override public Characters createCData(String content) { return new CharactersEventImpl(mLocation, content, true); } @Override public Characters createCharacters(String content) { return new CharactersEventImpl(mLocation, content, false); } @Override 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. */ @Override public DTD createDTD(String dtd) { return new DTDEventImpl(mLocation, dtd); } @Override public EndDocument createEndDocument() { return new EndDocumentEventImpl(mLocation); } @SuppressWarnings({ "rawtypes", "unchecked" }) // due to Stax's non-generic-ness @Override public EndElement createEndElement(QName name, Iterator namespaces) { return new EndElementEventImpl(mLocation, name, (Iterator) namespaces); } @Override public EndElement createEndElement(String prefix, String nsURI, String localName) { return createEndElement(createQName(nsURI, localName, prefix), null); } @SuppressWarnings("rawtypes") // due to Stax's non-generic-ness @Override public EndElement createEndElement(String prefix, String nsURI, String localName, Iterator ns) { return createEndElement(createQName(nsURI, localName, prefix), ns); } @Override public EntityReference createEntityReference(String name, EntityDeclaration decl) { return new EntityReferenceEventImpl(mLocation, decl); } @Override public Characters createIgnorableSpace(String content) { return CharactersEventImpl.createIgnorableWS(mLocation, content); } @Override public Namespace createNamespace(String nsURI) { return NamespaceEventImpl.constructDefaultNamespace(mLocation, nsURI); } @Override public Namespace createNamespace(String prefix, String nsURI) { return NamespaceEventImpl.constructNamespace(mLocation, prefix, nsURI); } @Override public ProcessingInstruction createProcessingInstruction(String target, String data) { return new ProcInstrEventImpl(mLocation, target, data); } @Override public Characters createSpace(String content) { return CharactersEventImpl.createNonIgnorableWS(mLocation, content); } @Override public StartDocument createStartDocument() { return new StartDocumentEventImpl(mLocation); } @Override public StartDocument createStartDocument(String encoding) { return new StartDocumentEventImpl(mLocation, encoding); } @Override public StartDocument createStartDocument(String encoding, String version) { return new StartDocumentEventImpl(mLocation, encoding, version); } @Override public StartDocument createStartDocument(String encoding, String version, boolean standalone) { return new StartDocumentEventImpl(mLocation, encoding, version, true, standalone); } @SuppressWarnings("rawtypes") // due to Stax's non-generic-ness @Override public StartElement createStartElement(QName name, Iterator attr, Iterator ns) { return createStartElement(name, attr, ns, null); } @Override public StartElement createStartElement(String prefix, String nsURI, String localName) { return createStartElement(createQName(nsURI, localName, prefix), null, null, null); } @SuppressWarnings("rawtypes") // due to Stax's non-generic-ness @Override public StartElement createStartElement(String prefix, String nsURI, String localName, Iterator attr, Iterator ns) { return createStartElement(createQName(nsURI, localName, prefix), attr, ns, null); } @SuppressWarnings("rawtypes") // due to Stax's non-generic-ness @Override public StartElement createStartElement(String prefix, String nsURI, String localName, Iterator attr, Iterator ns, NamespaceContext nsCtxt) { return createStartElement(createQName(nsURI, localName, prefix), attr, ns, nsCtxt); } @Override public void setLocation(Location loc) { mLocation = loc; } /* /********************************************************************** /* XMLEventFactory2 methods /********************************************************************** */ @Override public DTD2 createDTD(String rootName, String sysId, String pubId, String intSubset) { return new DTDEventImpl(mLocation, rootName, sysId, pubId, intSubset, null); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2EventReaderImpl.java000066400000000000000000000411551325660720300303120ustar00rootroot00000000000000/* 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. *

* 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: *

    *
  • Peek() functionality! Geez, why did that have to be part of StAX * specs???! *
  • *
  • Adding START_DOCUMENT event that cursor API does not return * explicitly. *
  • *
*/ 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 ////////////////////////////////////////////////////// */ /** *

* 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 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2EventWriterImpl.java000066400000000000000000000145571325660720300303720ustar00rootroot00000000000000package 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 protected XMLStreamWriter2 _writer; /* /********************************************************************** /* Construction, init /********************************************************************** */ public Stax2EventWriterImpl(XMLStreamWriter2 sw) { _writer = sw; } /* /********************************************************************** /* XMLEventWriter API /********************************************************************** */ /** * Basic implementation of the method which will use event implementations * available as part of the reference implementation. *

* 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(); _writer.writeAttribute(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), attr.getValue()); } break; case END_DOCUMENT: _writer.writeEndDocument(); break; case END_ELEMENT: _writer.writeEndElement(); break; case NAMESPACE: { Namespace ns = (Namespace) event; _writer.writeNamespace(ns.getPrefix(), ns.getNamespaceURI()); } break; case START_DOCUMENT: { StartDocument sd = (StartDocument) event; if (!sd.encodingSet()) { // encoding defined? _writer.writeStartDocument(sd.getVersion()); } else { _writer.writeStartDocument(sd.getCharacterEncodingScheme(), sd.getVersion()); } } break; case START_ELEMENT: { StartElement se = event.asStartElement(); QName n = se.getName(); _writer.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()) { _writer.writeCData(text); } else { _writer.writeCharacters(text); } } break; case CDATA: _writer.writeCData(event.asCharacters().getData()); break; case COMMENT: _writer.writeComment(((Comment) event).getText()); break; case DTD: _writer.writeDTD(((DTD) event).getDocumentTypeDeclaration()); break; case ENTITY_REFERENCE: _writer.writeEntityRef(((EntityReference) event).getName()); break; case PROCESSING_INSTRUCTION: // let's just write directly { ProcessingInstruction pi = (ProcessingInstruction) event; _writer.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(_writer); } 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 { _writer.close(); } public void flush() throws XMLStreamException { _writer.flush(); } public NamespaceContext getNamespaceContext() { return _writer.getNamespaceContext(); } public String getPrefix(String uri) throws XMLStreamException { return _writer.getPrefix(uri); } public void setDefaultNamespace(String uri) throws XMLStreamException { _writer.setDefaultNamespace(uri); } public void setNamespaceContext(NamespaceContext ctxt) throws XMLStreamException { _writer.setNamespaceContext(ctxt); } public void setPrefix(String prefix, String uri) throws XMLStreamException { _writer.setPrefix(prefix, uri); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2FilteredStreamReader.java000066400000000000000000000025631325660720300313210ustar00rootroot00000000000000package 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 ////////////////////////////////////////////////////// */ @Override public int next() throws XMLStreamException { int type; do { type = _delegate2.next(); if (mFilter.accept(this)) { break; } } while (type != END_DOCUMENT); return type; } @Override public int nextTag() throws XMLStreamException { int type; // Can be implemented very much like next() while (true) { type = _delegate2.nextTag(); if (mFilter.accept(this)) { break; } } return type; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2LocationAdapter.java000066400000000000000000000030111325660720300303220ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2ReaderAdapter.java000066400000000000000000001033211325660720300277610ustar00rootroot00000000000000package 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: *

    *
  • Serve as convenient base class for a complete implementation, * which can use native accessors provided by the wrapped Stax * implementation *
  • *
  • To be used for tasks that make limited use of Stax2 API, such * that missing parts are not needed *
  • *
* * @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 /////////////////////////////////////////////////////////////////////// */ @Override 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; } @Override 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 @Deprecated public Object getFeature(String name) { // No features defined return null; } @Deprecated 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2ReaderImpl.java000066400000000000000000000440321325660720300273050ustar00rootroot00000000000000/* 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 @Deprecated public Object getFeature(String name) { // No features defined return null; } @Deprecated 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. *

* !!! 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2Util.java000066400000000000000000000207321325660720300261770ustar00rootroot00000000000000/* 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 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); } /** *

* 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 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2WriterAdapter.java000066400000000000000000000526231325660720300300430ustar00rootroot00000000000000/* 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. *

* 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: *

    *
  • Serve as convenient base class for a complete implementation, * which can use native accessors provided by the wrapped Stax * implementation *
  • *
  • To be used for tasks that make limited use of Stax2 API, such * that missing parts are not needed *
  • *
*/ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/Stax2WriterImpl.java000066400000000000000000000257471325660720300273730ustar00rootroot00000000000000/* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/dom/000077500000000000000000000000001325660720300242505ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/dom/DOMWrappingReader.java000066400000000000000000002305361325660720300303760ustar00rootroot00000000000000/* 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. *

* Note that the implementation is only to be used for use with * 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. *

* Some notes regarding missing/incomplete functionality: *

    *
  • DOM does not seem to have access to information from the XML * declaration (although Document node can be viewed as representing * it). Consequently, all accessors return no information (version, * encoding, standalone). *
  • *
  • No location info is provided, since (you guessed it!) DOM * does not provide that info. *
  • *
*/ 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. *

*/ 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: *

* 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. *
Precondition: the current event is START_ELEMENT. *
Postcondition: the current event is the corresponding END_ELEMENT. *
*/ 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."); } } /** *

* 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); */ Node n = _currNode; boolean defaultNs = (prefix == null) || (prefix.length() == 0); while (n != null) { NamedNodeMap attrs = n.getAttributes(); if (attrs != null){ for (int i = 0, len = attrs.getLength(); i < len; ++i) { Node attr = attrs.item(i); String thisPrefix = attr.getPrefix(); if (thisPrefix == null || thisPrefix.length() == 0) { // nope if (defaultNs && "xmlns".equals(attr.getLocalName())) { return attr.getNodeValue(); } } else if (!defaultNs && "xmlns".equals(thisPrefix)) { if (prefix.equals(attr.getLocalName())) { return attr.getNodeValue(); } } } } n = n.getParentNode(); } 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; */ Node n = _currNode; if (namespaceURI == null) { // not sure if this is even legal but... namespaceURI = ""; } while (n != null) { NamedNodeMap attrs = n.getAttributes(); for (int i = 0, len = attrs.getLength(); i < len; ++i) { Node attr = attrs.item(i); String thisPrefix = attr.getPrefix(); if (thisPrefix == null || thisPrefix.length() == 0) { if ("xmlns".equals(attr.getLocalName()) && namespaceURI.equals(attr.getNodeValue())) { return ""; } } else if ("xmlns".equals(thisPrefix)) { if (namespaceURI.equals(attr.getNodeValue())) { return attr.getLocalName(); } } } n = n.getParentNode(); } return null; } public Iterator getPrefixes(String namespaceURI) { String prefix = getPrefix(namespaceURI); if (prefix == null) { return EmptyIterator.getInstance(); } return SingletonIterator.create(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 @Deprecated public Object getFeature(String name) { // No readable features supported yet throw new IllegalArgumentException("Unrecognized feature \""+name+"\""); } @Deprecated 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 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. *

* 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 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 {@code '/>'}); * 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 = Collections.emptyList(); _nsDeclList = Collections.emptyList(); return; } if (!_cfgNsAware) { _attrList = new ArrayList(len); for (int i = 0; i < len; ++i) { _attrList.add(attrsIn.item(i)); } _nsDeclList = Collections.emptyList(); 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.emptyList() : attrsOut; _nsDeclList = (nsOut == null) ? Collections.emptyList() : 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/dom/DOMWrappingWriter.java000066400000000000000000000514701325660720300304460ustar00rootroot00000000000000/* 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. *

* Note that the implementation is only to be used with * 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. *

* 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.createComment(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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/000077500000000000000000000000001325660720300242675ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/AttributeEventImpl.java000066400000000000000000000121411325660720300307200ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return ATTRIBUTE; } @Override public boolean isAttribute() { return true; } @Override 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); } } @Override 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 /////////////////////////////////////////// */ @Override 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; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/BaseEventImpl.java000066400000000000000000000110051325660720300276250ustar00rootroot00000000000000package 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. *

* TODO: remove direct dependencies to this by sub-classes; rename * * @deprecated Call {@link #getLocation()} instead. */ @Deprecated // 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 */ @Override public abstract boolean equals(Object o); /** * Declared abstract to force redefinition by sub-classes */ @Override public abstract int hashCode(); @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/CharactersEventImpl.java000066400000000000000000000134361325660720300310440ustar00rootroot00000000000000package 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 ///////////////////////////////////////////////////// */ @Override public Characters asCharacters() { // overriden to save a cast return this; } @Override public int getEventType() { return mIsCData ? CDATA : CHARACTERS; } @Override public boolean isCharacters() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { if (mIsCData) { w.write(""); } else { writeEscapedXMLText(w, mContent); } } catch (IOException ie) { throwFromIOE(ie); } } @Override 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 /////////////////////////////////////////// */ @Override 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; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/CommentEventImpl.java000066400000000000000000000031531325660720300303620ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return COMMENT; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write(""); } catch (IOException ie) { throwFromIOE(ie); } } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { w.writeComment(mContent); } /* /////////////////////////////////////////// // Standard method impl /////////////////////////////////////////// */ @Override 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()); } @Override public int hashCode() { return mContent.hashCode(); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/DTDEventImpl.java000066400000000000000000000164241325660720300274000ustar00rootroot00000000000000package 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 javax.xml.stream.events.EntityDeclaration; import javax.xml.stream.events.NotationDeclaration; 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 protected String mRootName; final protected String mSystemId; final protected String mPublicId; final protected String mInternalSubset; final protected 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. */ protected String mFullText = null; /* /********************************************************************** /* Constructors /********************************************************************** */ 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 /********************************************************************** */ @Override public int getEventType() { return DTD; } @Override 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); } } @Override 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 /********************************************************************** */ @Override 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()); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/EndDocumentEventImpl.java000066400000000000000000000024631325660720300311700ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return END_DOCUMENT; } @Override public boolean isEndDocument() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { // Nothing to output } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { w.writeEndDocument(); } /* /////////////////////////////////////////// // Standard method impl /////////////////////////////////////////// */ @Override public boolean equals(Object o) { if (o == this) return true; if (o == null) return false; return (o instanceof EndDocument); } @Override public int hashCode() { return END_DOCUMENT; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/EndElementEventImpl.java000066400000000000000000000107461325660720300310060ustar00rootroot00000000000000package 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 protected QName mName; final protected 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() { if (mNamespaces == null) { return EmptyIterator.getInstance(); } return mNamespaces.iterator(); } /* /********************************************************************** /* Implementation of abstract base methods, overrides /********************************************************************** */ @Override public EndElement asEndElement() { // overriden to save a cast return this; } @Override public int getEventType() { return END_ELEMENT; } @Override public boolean isEndElement() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write(" 0) { w.write(prefix); w.write(':'); } w.write(mName.getLocalPart()); w.write('>'); } catch (IOException ie) { throwFromIOE(ie); } } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { w.writeEndElement(); } /* /********************************************************************** /* Standard method impl /********************************************************************** */ @Override 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; } @Override public int hashCode() { return getName().hashCode(); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/EntityDeclarationEventImpl.java000066400000000000000000000062301325660720300324010ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return ENTITY_DECLARATION; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write(""); } catch (IOException ie) { throwFromIOE(ie); } } @Override 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 /////////////////////////////////////////// */ @Override 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()) ; } @Override public int hashCode() { // Since we don't have much data, this is easy... return mName.hashCode(); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/EntityReferenceEventImpl.java000066400000000000000000000041651325660720300320570ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return ENTITY_REFERENCE; } @Override public boolean isEntityReference() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write('&'); w.write(getName()); w.write(';'); } catch (IOException ie) { throwFromIOE(ie); } } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { w.writeEntityRef(getName()); } /* /////////////////////////////////////////// // Standard method impl /////////////////////////////////////////// */ @Override 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()); } @Override public int hashCode() { return getName().hashCode(); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/MergedNsContext.java000066400000000000000000000130461325660720300302070ustar00rootroot00000000000000package 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 _parentCtxt; /** * List of {@link Namespace} instances. */ final List _namespaces; protected MergedNsContext(NamespaceContext parentCtxt, List localNs) { _parentCtxt = parentCtxt; _namespaces = (localNs == null) ? Collections.emptyList() : 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 = _namespaces.size(); i < len; ++i) { Namespace ns = _namespaces.get(i); if (prefix.equals(ns.getPrefix())) { return ns.getNamespaceURI(); } } // Not found; how about from parent? if (_parentCtxt != null) { String uri = _parentCtxt.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 = _namespaces.size(); i < len; ++i) { Namespace ns = _namespaces.get(i); if (nsURI.equals(ns.getNamespaceURI())) { return ns.getPrefix(); } } // If not, let's first try the easy way: if (_parentCtxt != null) { String prefix = _parentCtxt.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 = _parentCtxt.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 = _namespaces.size(); i < len; ++i) { Namespace ns = _namespaces.get(i); if (nsURI.equals(ns.getNamespaceURI())) { l = addToList(l, ns.getPrefix()); } } // How about parent? if (_parentCtxt != null) { Iterator it = _parentCtxt.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, T value) { if (l == null) { l = new ArrayList(); } l.add(value); return l; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/NamespaceEventImpl.java000066400000000000000000000050701325660720300306540ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return NAMESPACE; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/NotationDeclarationEventImpl.java000066400000000000000000000070731325660720300327260ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return NOTATION_DECLARATION; } @Override 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. */ @Override 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 /////////////////////////////////////////// */ @Override 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()) ; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/ProcInstrEventImpl.java000066400000000000000000000044501325660720300307040ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return PROCESSING_INSTRUCTION; } @Override public boolean isProcessingInstruction() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write(" 0) { w.write(mData); } w.write("?>"); } catch (IOException ie) { throwFromIOE(ie); } } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { if (mData != null && mData.length() > 0) { w.writeProcessingInstruction(mTarget, mData); } else { w.writeProcessingInstruction(mTarget); } } /* /////////////////////////////////////////// // Standard method impl /////////////////////////////////////////// */ @Override 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()); } @Override public int hashCode() { int hash = mTarget.hashCode(); if (mData != null) { hash ^= mData.hashCode(); } return hash; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/StartDocumentEventImpl.java000066400000000000000000000122441325660720300315550ustar00rootroot00000000000000package 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 /////////////////////////////////////////// */ @Override public int getEventType() { return START_DOCUMENT; } @Override public boolean isStartDocument() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { // Need to output the XML declaration? try { w.write(""); } catch (IOException ie) { throwFromIOE(ie); } } @Override public void writeUsing(XMLStreamWriter2 w) throws XMLStreamException { w.writeStartDocument(); } /* /////////////////////////////////////////// // Standard method impl /////////////////////////////////////////// */ @Override 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()) ; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/StartElementEventImpl.java000066400000000000000000000224541325660720300313740ustar00rootroot00000000000000package 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 _name; protected final ArrayList _attrs; protected final ArrayList _nsDecls; /** * Enclosing namespace context */ protected NamespaceContext _parentNsCtxt; // // // Lazily constructed components NamespaceContext _actualNsCtxt = null; /* /********************************************************************** /* Life cycle /********************************************************************** */ protected StartElementEventImpl(Location loc, QName name, ArrayList attrs, ArrayList nsDecls, NamespaceContext parentNsCtxt) { super(loc); _name = name; _attrs = attrs; _nsDecls = nsDecls; _parentNsCtxt = (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 /********************************************************************** */ @Override public StartElement asStartElement() { // overriden to save a cast return this; } @Override public int getEventType() { return START_ELEMENT; } @Override public boolean isStartElement() { return true; } @Override public void writeAsEncodedUnicode(Writer w) throws XMLStreamException { try { w.write('<'); String prefix = _name.getPrefix(); if (prefix != null && prefix.length() > 0) { w.write(prefix); w.write(':'); } w.write(_name.getLocalPart()); // Any namespaces? if (_nsDecls != null) { for (int i = 0, len = _nsDecls.size(); i < len; ++i) { w.write(' '); ((Namespace) _nsDecls.get(i)).writeAsEncodedUnicode(w); } } // How about attrs? if (_attrs != null) { for (int i = 0, len = _attrs.size(); i < len; ++i) { Attribute attr = (Attribute) _attrs.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); } } @Override public void writeUsing(XMLStreamWriter2 sw) throws XMLStreamException { QName n = _name; sw.writeStartElement(n.getPrefix(), n.getLocalPart(), n.getNamespaceURI()); // Any namespaces? if (_nsDecls != null) { for (int i = 0, len = _nsDecls.size(); i < len; ++i) { Namespace ns = (Namespace) _nsDecls.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 (_attrs != null) { for (int i = 0, len = _attrs.size(); i < len; ++i) { Attribute attr = (Attribute) _attrs.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 _name; } public Iterator getNamespaces() { if (_nsDecls == null) { return EmptyIterator.getInstance(); } return _nsDecls.iterator(); } public NamespaceContext getNamespaceContext() { if (_actualNsCtxt == null) { if (_nsDecls == null) { _actualNsCtxt = _parentNsCtxt; } else { _actualNsCtxt = MergedNsContext.construct(_parentNsCtxt, _nsDecls); } } return _actualNsCtxt; } public String getNamespaceURI(String prefix) { if (_nsDecls != null) { if (prefix == null) { prefix = ""; } for (int i = 0, len = _nsDecls.size(); i < len; ++i) { Namespace ns = (Namespace) _nsDecls.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 (_attrs == null) { return null; } String ln = nameIn.getLocalPart(); String uri = nameIn.getNamespaceURI(); int len = _attrs.size(); boolean notInNs = (uri == null || uri.length() == 0); for (int i = 0; i < len; ++i) { Attribute attr = (Attribute) _attrs.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 (_attrs == null) { return EmptyIterator.getInstance(); } return _attrs.iterator(); } /* /********************************************************************** /* Standard method impl /********************************************************************** */ @Override 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 (_name.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; } @Override public int hashCode() { int hash = _name.hashCode(); hash = addHash(getNamespaces(), hash); hash = addHash(getAttributes(), hash); return hash; } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/Stax2EventAllocatorImpl.java000066400000000000000000000151471325660720300316300ustar00rootroot00000000000000package 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.Attribute; import javax.xml.stream.events.DTD; import javax.xml.stream.events.EntityReference; import javax.xml.stream.events.Namespace; 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/Stax2EventReaderAdapter.java000066400000000000000000000071101325660720300315600ustar00rootroot00000000000000package 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. *

* 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: *

    *
  • Serve as convenient base class for a complete implementation, * which can use native accessors provided by the wrapped Stax * implementation *
  • *
  • To be used for tasks that make limited use of Stax2 API, such * that missing parts are not needed *
  • *
* * @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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/evt/Stax2FilteredEventReader.java000066400000000000000000000064021325660720300317410ustar00rootroot00000000000000package org.codehaus.stax2.ri.evt; import javax.xml.stream.*; import javax.xml.stream.events.*; import org.codehaus.stax2.XMLEventReader2; /** *

* Some notes about implemention: *

    *
  • There is no way to filter out values of peek(), so we'll just straight * dispatch the call to underlying reader *
  • *
*/ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/package.html000066400000000000000000000002421325660720300257500ustar00rootroot00000000000000 Package that contains a skeletal reference implementation of Stax2 API, as well as some utility/helper classes that can be useful in building one. stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/000077500000000000000000000000001325660720300246165ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/AsciiValueEncoder.java000066400000000000000000000125711325660720300310140ustar00rootroot00000000000000/* 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. *

* General contract for encoding is that caller must call things * in following sequence: *

    *
  1. First, {@link #bufferNeedsFlush} is called once; and * if indicated by return value of true, caller must flush * its buffer so it is completely empty (buffer also must have * size of at at least MIN_CHARS_WITHOUT_FLUSH) *
  2. *
  3. Then, one of {@link #encodeMore} methods is to be called *
  4. *
  5. After this call, {@link #isCompleted} should be called * to determine if encoding was complete: if it was, there is * nothing more to do. *
  6. *
  7. Otherwise caller should flush its buffer (since encoder * has encoded as much as it can without flushing), and * repeat cycle of calls to {@link #encodeMore} followed * by a call to {@link #isCompleted} and flushing, as long * as necessary to complete encoding. *
  8. *
*

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/Base64DecoderBase.java000066400000000000000000000231241325660720300305700ustar00rootroot00000000000000/* 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: *

    *
  • We are waiting for start of a new segment; no data to decode, * ok to quit (returns 0) *
  • *
  • We are half-way through decoding for padding variant (or, * non-padding with just partial byte [single char]); error case. * (returns -1) *
  • We are half-way through decoding for non-padding variant, and * thereby have 1 or 2 bytes of data (which was not earlier recognized * because of missing padding characters) * (returns 1 or 2, number of bytes made available) *
  • *
*/ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/CharArrayBase64Decoder.java000066400000000000000000000241011325660720300315660ustar00rootroot00000000000000/* 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 class CharArrayBase64Decoder extends Base64DecoderBase { // // // Input buffer information /** * Text segment being currently processed. */ protected char[] _currSegment; protected int _currSegmentPtr; protected int _currSegmentEnd; protected final ArrayList _nextSegments = new ArrayList(); protected int _lastSegmentOffset; protected int _lastSegmentEnd; /** * Pointer of the next segment to process (after current one stored * in {@link #_currSegment}) within {@link #_nextSegments}. */ protected 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 = 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 */ @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/NumberUtil.java000066400000000000000000000353001325660720300275500ustar00rootroot00000000000000/* 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'; /** *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/SimpleValueEncoder.java000066400000000000000000000042571325660720300312170ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/StringBase64Decoder.java000066400000000000000000000170321325660720300311650ustar00rootroot00000000000000/* 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 */ @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/ValueDecoderFactory.java000066400000000000000000001376421325660720300313700ustar00rootroot00000000000000/* 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). */ @Override 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() { } @Override public String getType() { return "boolean"; } public boolean getValue() { return mValue; } @Override 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); } @Override 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() { } @Override public String getType() { return "int"; } public int getValue() { return mValue; } @Override 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."); } @Override 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() { } @Override public String getType() { return "long"; } public long getValue() { return mValue; } @Override 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); } @Override 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() { } @Override public String getType() { return "float"; } public float getValue() { return mValue; } @Override 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); } } @Override 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() { } @Override public String getType() { return "double"; } public double getValue() { return mValue; } @Override 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); } } @Override 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() { } @Override public String getType() { return "integer"; } public BigInteger getValue() { return mValue; } @Override public void decode(String lexical) throws IllegalArgumentException { try { mValue = new BigInteger(lexical); } catch (NumberFormatException nex) { throw constructInvalidValue(lexical); } } @Override 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() { } @Override public String getType() { return "decimal"; } public BigDecimal getValue() { return mValue; } @Override public void decode(String lexical) throws IllegalArgumentException { try { mValue = new BigDecimal(lexical); } catch (NumberFormatException nex) { throw constructInvalidValue(lexical); } } @Override 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; } @Override public String getType() { return "QName"; } public QName getValue() { return mValue; } @Override 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); } } @Override 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; } @Override public final int getCount() { return mCount; } @Override 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; } @Override 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; } @Override public boolean decodeValue(String input) throws IllegalArgumentException { mDecoder.decode(input); mResult[mStart+mCount] = mDecoder.getValue(); return (++mCount >= mEnd); } @Override 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; } @Override 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; } @Override public boolean decodeValue(String input) throws IllegalArgumentException { mDecoder.decode(input); mResult[mStart+mCount] = mDecoder.getValue(); return (++mCount >= mEnd); } @Override 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; } @Override 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; } @Override public boolean decodeValue(String input) throws IllegalArgumentException { mDecoder.decode(input); mResult[mStart+mCount] = mDecoder.getValue(); return (++mCount >= mEnd); } @Override 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; } @Override 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; } @Override public boolean decodeValue(String input) throws IllegalArgumentException { mDecoder.decode(input); mResult[mStart+mCount] = mDecoder.getValue(); return (++mCount >= mEnd); } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/ri/typed/ValueEncoderFactory.java000066400000000000000000000461141325660720300313730ustar00rootroot00000000000000/* 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; } @Override public boolean isCompleted() { return (_value == null); } @Override 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; } @Override 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; } @Override public boolean isCompleted() { return (_value == null); } @Override 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; } @Override 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./ */ @Override public final boolean isCompleted() { return true; } } final static class IntEncoder extends TypedScalarEncoder { int _value; protected IntEncoder() { super(); } protected void reset(int value) { _value = value; } @Override public int encodeMore(char[] buffer, int ptr, int end) { return NumberUtil.writeInt(_value, buffer, ptr); } @Override 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; } @Override public int encodeMore(char[] buffer, int ptr, int end) { return NumberUtil.writeLong(_value, buffer, ptr); } @Override 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; } @Override public int encodeMore(char[] buffer, int ptr, int end) { return NumberUtil.writeFloat(_value, buffer, ptr); } @Override 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; } @Override public int encodeMore(char[] buffer, int ptr, int end) { return NumberUtil.writeDouble(_value, buffer, ptr); } @Override 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; } @Override public final boolean isCompleted() { return (_ptr >= _end); } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override 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; } @Override public boolean isCompleted() { return (_inputPtr >= _inputEnd); } @Override 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; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/000077500000000000000000000000001325660720300242045ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/Base64Variant.java000066400000000000000000000246421325660720300274300ustar00rootroot00000000000000/* 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: *

    *
  • The main complication here is trying to limit access to the underlying efficient encoding/decoding tables -- they are needed for fast operation, but it is potentially risky to expose raw arrays since they can not be protected against modification. The approach here is to try to limit access essentially to the main base64 codec classes; but this leads to bit awkward class structure
  • *
* * @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). *

* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/Base64Variants.java000066400000000000000000000065641325660720300276160ustar00rootroot00000000000000/* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/TypedArrayDecoder.java000066400000000000000000000020461325660720300304230ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/TypedValueDecoder.java000066400000000000000000000052401325660720300304200ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/TypedXMLStreamException.java000066400000000000000000000073021325660720300315520ustar00rootroot00000000000000package 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 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/TypedXMLStreamReader.java000066400000000000000000000647641325660720300310350ustar00rootroot00000000000000/* 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 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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* * @throws XMLStreamException If unable to access content * @throws TypedXMLStreamException If unable to convert the resulting * character sequence into an XML Schema boolean value. */ public boolean getElementAsBoolean() throws XMLStreamException; /** *

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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* * @throws XMLStreamException If unable to access content * @throws TypedXMLStreamException If unable to convert the resulting * character sequence into a Java (32-bit) integer. */ public int getElementAsInt() throws XMLStreamException; /** *

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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* * @throws XMLStreamException If unable to access content * @throws TypedXMLStreamException If unable to convert the resulting * character sequence into a Java (64-bit) integer. */ public long getElementAsLong() throws XMLStreamException; /** *

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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* * * @throws XMLStreamException If unable to access content * @throws TypedXMLStreamException If unable to convert the resulting * character sequence into a Java float */ public float getElementAsFloat() throws XMLStreamException; /** *

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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* * * @throws XMLStreamException If unable to access content * @throws TypedXMLStreamException If unable to convert the resulting * character sequence into a Java double */ public double getElementAsDouble() throws XMLStreamException; public BigInteger getElementAsInteger() throws XMLStreamException; public BigDecimal getElementAsDecimal() throws XMLStreamException; public QName getElementAsQName() throws XMLStreamException; // !!! 30-Jan-2008, TSa: JDK 1.5 only, can't add yet //public XMLGregorianCalendar getElementAsCalendar() 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. *

* 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: *

    *
  • Precondition: the current event is START_ELEMENT.
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT.
  • *
* *

* 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: *

    *
  • Precondition: the current event is either START_ELEMENT, * or a textual event (CHARACTERS, CDATA), or END_ELEMENT * (END_ELEMENT is allowed for convenience; if so, no read * operation is tried, and -1 is returned immediately *
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT, if all remaining binary content was read, * or CHARACTERS if only a portion of the array was read *
  • *
*

* 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 Maximum 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: *

    *
  • Precondition: the current event is either START_ELEMENT, * or a textual event (CHARACTERS, CDATA), or END_ELEMENT * (END_ELEMENT is allowed for convenience; if so, no read * operation is tried, and -1 is returned immediately *
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT or CHARACTERS if only a portion of the * array has been copied thus far.
  • *
* 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 more bytes available for reading. * * * @param resultBuffer The array in which to copy the ints. * @param offset The index in the array from which copying starts. * @param length The maximun number of ints to copy. Minimum value * is 1; others an {@link IllegalArgumentException} is thrown * * @return The number of ints actually copied which must * be less or equal than 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: *

    *
  • Precondition: the current event is either START_ELEMENT, * or a textual event (CHARACTERS, CDATA), or END_ELEMENT * (END_ELEMENT is allowed for convenience; if so, no read * operation is tried, and -1 is returned immediately *
  • *
  • Postcondition: the current event is the corresponding * END_ELEMENT or CHARACTERS if only a portion of the * array has been copied thus far.
  • *
* 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 more bytes available for reading. * *

* 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 */ 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/typed/TypedXMLStreamWriter.java000066400000000000000000000244461325660720300311000ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/util/000077500000000000000000000000001325660720300240345ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/util/StreamReader2Delegate.java000066400000000000000000000226671325660720300310070ustar00rootroot00000000000000package 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 _delegate2; /* /********************************************************************** /* Life-cycle /********************************************************************** */ public StreamReader2Delegate(XMLStreamReader2 sr) { super(sr); _delegate2 = sr; } @Override public void setParent(XMLStreamReader pr) { super.setParent(pr); _delegate2 = (XMLStreamReader2) pr; } /* /********************************************************************** /* XMLStreamReader2 implementation /********************************************************************** */ public void closeCompletely() throws XMLStreamException { _delegate2.closeCompletely(); } public AttributeInfo getAttributeInfo() throws XMLStreamException { return _delegate2.getAttributeInfo(); } public DTDInfo getDTDInfo() throws XMLStreamException { return _delegate2.getDTDInfo(); } public int getDepth() { return _delegate2.getDepth(); } @SuppressWarnings("deprecation") public Object getFeature(String name) { return _delegate2.getFeature(name); } public LocationInfo getLocationInfo() { return _delegate2.getLocationInfo(); } public NamespaceContext getNonTransientNamespaceContext() { return _delegate2.getNonTransientNamespaceContext(); } public String getPrefixedName() { return _delegate2.getPrefixedName(); } public int getText(Writer w, boolean preserveContents) throws IOException, XMLStreamException { return _delegate2.getText(w, preserveContents); } public boolean isEmptyElement() throws XMLStreamException { return _delegate2.isEmptyElement(); } public boolean isPropertySupported(String name) { return _delegate2.isPropertySupported(name); } @SuppressWarnings("deprecation") public void setFeature(String name, Object value) { _delegate2.setFeature(name, value); } public boolean setProperty(String name, Object value) { return _delegate2.setProperty(name, value); } public void skipElement() throws XMLStreamException { _delegate2.skipElement(); } /* /********************************************************************** /* XMLStreamReader2, Validatable /********************************************************************** */ public ValidationProblemHandler setValidationProblemHandler(ValidationProblemHandler h) { return _delegate2.setValidationProblemHandler(h); } public XMLValidator stopValidatingAgainst(XMLValidationSchema schema) throws XMLStreamException { return _delegate2.stopValidatingAgainst(schema); } public XMLValidator stopValidatingAgainst(XMLValidator validator) throws XMLStreamException { return _delegate2.stopValidatingAgainst(validator); } public XMLValidator validateAgainst(XMLValidationSchema schema) throws XMLStreamException { return _delegate2.validateAgainst(schema); } /* /********************************************************************** /* TypedXMLStreamReader implementation /********************************************************************** */ public int getAttributeIndex(String namespaceURI, String localName) { return _delegate2.getAttributeIndex(namespaceURI, localName); } public boolean getAttributeAsBoolean(int index) throws XMLStreamException { return _delegate2.getAttributeAsBoolean(index); } public BigDecimal getAttributeAsDecimal(int index) throws XMLStreamException { return _delegate2.getAttributeAsDecimal(index); } public double getAttributeAsDouble(int index) throws XMLStreamException { return _delegate2.getAttributeAsDouble(index); } public float getAttributeAsFloat(int index) throws XMLStreamException { return _delegate2.getAttributeAsFloat(index); } public int getAttributeAsInt(int index) throws XMLStreamException { return _delegate2.getAttributeAsInt(index); } public BigInteger getAttributeAsInteger(int index) throws XMLStreamException { return _delegate2.getAttributeAsInteger(index); } public long getAttributeAsLong(int index) throws XMLStreamException { return _delegate2.getAttributeAsLong(index); } public QName getAttributeAsQName(int index) throws XMLStreamException { return _delegate2.getAttributeAsQName(index); } public int[] getAttributeAsIntArray(int index) throws XMLStreamException { return _delegate2.getAttributeAsIntArray(index); } public long[] getAttributeAsLongArray(int index) throws XMLStreamException { return _delegate2.getAttributeAsLongArray(index); } public float[] getAttributeAsFloatArray(int index) throws XMLStreamException { return _delegate2.getAttributeAsFloatArray(index); } public double[] getAttributeAsDoubleArray(int index) throws XMLStreamException { return _delegate2.getAttributeAsDoubleArray(index); } public void getElementAs(TypedValueDecoder tvd) throws XMLStreamException { _delegate2.getElementAs(tvd); } public boolean getElementAsBoolean() throws XMLStreamException { return _delegate2.getElementAsBoolean(); } public BigDecimal getElementAsDecimal() throws XMLStreamException { return _delegate2.getElementAsDecimal(); } public double getElementAsDouble() throws XMLStreamException { return _delegate2.getElementAsDouble(); } public float getElementAsFloat() throws XMLStreamException { return _delegate2.getElementAsFloat(); } public int getElementAsInt() throws XMLStreamException { return _delegate2.getElementAsInt(); } public BigInteger getElementAsInteger() throws XMLStreamException { return _delegate2.getElementAsInteger(); } public long getElementAsLong() throws XMLStreamException { return _delegate2.getElementAsLong(); } public QName getElementAsQName() throws XMLStreamException { return _delegate2.getElementAsQName(); } public byte[] getElementAsBinary() throws XMLStreamException { return _delegate2.getElementAsBinary(); } public byte[] getElementAsBinary(Base64Variant v) throws XMLStreamException { return _delegate2.getElementAsBinary(v); } public void getAttributeAs(int index, TypedValueDecoder tvd) throws XMLStreamException { _delegate2.getAttributeAs(index, tvd); } public int getAttributeAsArray(int index, TypedArrayDecoder tad) throws XMLStreamException { return _delegate2.getAttributeAsArray(index, tad); } public byte[] getAttributeAsBinary(int index) throws XMLStreamException { return _delegate2.getAttributeAsBinary(index); } public byte[] getAttributeAsBinary(int index, Base64Variant v) throws XMLStreamException { return _delegate2.getAttributeAsBinary(index, v); } public int readElementAsDoubleArray(double[] value, int from, int length) throws XMLStreamException { return _delegate2.readElementAsDoubleArray(value, from, length); } public int readElementAsFloatArray(float[] value, int from, int length) throws XMLStreamException { return _delegate2.readElementAsFloatArray(value, from, length); } public int readElementAsIntArray(int[] value, int from, int length) throws XMLStreamException { return _delegate2.readElementAsIntArray(value, from, length); } public int readElementAsLongArray(long[] value, int from, int length) throws XMLStreamException { return _delegate2.readElementAsLongArray(value, from, length); } public int readElementAsArray(TypedArrayDecoder tad) throws XMLStreamException { return _delegate2.readElementAsArray(tad); } public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength) throws XMLStreamException { return _delegate2.readElementAsBinary(resultBuffer, offset, maxLength); } public int readElementAsBinary(byte[] resultBuffer, int offset, int maxLength, Base64Variant v) throws XMLStreamException { return _delegate2.readElementAsBinary(resultBuffer, offset, maxLength, v); } } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/util/StreamWriter2Delegate.java000066400000000000000000000227071325660720300310540ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/util/StreamWriterDelegate.java000066400000000000000000000137771325660720300310010ustar00rootroot00000000000000/* 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/000077500000000000000000000000001325660720300252115ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/AttributeContainer.java000066400000000000000000000023621325660720300316650ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/DTDValidationSchema.java000066400000000000000000000042221325660720300316230ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/Validatable.java000066400000000000000000000057011325660720300302670ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/ValidationContext.java000066400000000000000000000164241325660720300315220ustar00rootroot00000000000000package 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. * @throws XMLStreamException */ public int addDefaultAttribute(String localName, String uri, String prefix, String value) throws XMLStreamException; } stax2-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/ValidationProblemHandler.java000066400000000000000000000015551325660720300327730ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/ValidatorPair.java000066400000000000000000000215341325660720300306220ustar00rootroot00000000000000package 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. */ @Override public XMLValidationSchema getSchema() { return null; } @Override public void validateElementStart(String localName, String uri, String prefix) throws XMLStreamException { mFirst.validateElementStart(localName, uri, prefix); mSecond.validateElementStart(localName, uri, prefix); } @Override 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); } @Override 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); } @Override 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; } @Override 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; } @Override public void validateText(String text, boolean lastTextSegment) throws XMLStreamException { mFirst.validateText(text, lastTextSegment); mSecond.validateText(text, lastTextSegment); } @Override 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); } @Override public void validationCompleted(boolean eod) throws XMLStreamException { mFirst.validationCompleted(eod); mSecond.validationCompleted(eod); } /* /////////////////////////////////////////////////// // Access to post-validation data (type info) /////////////////////////////////////////////////// */ @Override 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; } @Override public int getIdAttrIndex() { int index = mFirst.getIdAttrIndex(); if (index < 0) { return mSecond.getIdAttrIndex(); } return index; } @Override 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/XMLValidationException.java000066400000000000000000000046461325660720300324200ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/XMLValidationProblem.java000066400000000000000000000060601325660720300320520ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/XMLValidationSchema.java000066400000000000000000000040621325660720300316520ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/XMLValidationSchemaFactory.java000066400000000000000000000271701325660720300332070ustar00rootroot00000000000000package 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-api-stax2-api-4.1/src/main/java/org/codehaus/stax2/validation/XMLValidator.java000066400000000000000000000273461325660720300303760ustar00rootroot00000000000000package 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(); } stax2-api-stax2-api-4.1/src/main/resources/000077500000000000000000000000001325660720300205255ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/resources/META-INF/000077500000000000000000000000001325660720300216655ustar00rootroot00000000000000stax2-api-stax2-api-4.1/src/main/resources/META-INF/LICENSE000066400000000000000000000005721325660720300226760ustar00rootroot00000000000000This copy of Stax2 API is licensed under the Simplified BSF License (also known as "2-clause BSD", or "FreeBSD License") See the License for details about distribution rights, and the specific rights regarding derivate works. You may obtain a copy of the License at: http://www.opensource.org/licenses/bsd-license.php with details of: = FasterXML.com = 2010-